Compare commits
16 Commits
master
...
release/20
Author | SHA1 | Date | |
---|---|---|---|
|
c4023f7299 | ||
|
86d1fbe521 | ||
|
71b1c36ca3 | ||
|
382c624f10 | ||
|
d903c61166 | ||
|
acc1a5145a | ||
|
e892d17f74 | ||
|
7cd35f4477 | ||
|
fb5f40339b | ||
|
0f25bb7386 | ||
|
4952be6990 | ||
|
3f3a0c307d | ||
|
63002dd1a5 | ||
|
95f62fbf58 | ||
|
f28b6ed05d | ||
|
c0616be20e |
@ -1,5 +1,6 @@
|
||||
{
|
||||
BasedOnStyle: WebKit,
|
||||
AlignAfterOpenBracket: AlwaysBreak,
|
||||
AlignConsecutiveAssignments: false,
|
||||
AlignConsecutiveDeclarations: false,
|
||||
AlignAfterOpenBracket: Align,
|
||||
|
@ -72,7 +72,10 @@ if(fmt_FOUND)
|
||||
# OpmSatellites will not add the library, do it here.
|
||||
list(APPEND opm-common_LIBRARIES fmt::fmt)
|
||||
else()
|
||||
include(DownloadFmt)
|
||||
add_definitions(-DFMT_HEADER_ONLY)
|
||||
include_directories(SYSTEM ${PROJECT_SOURCE_DIR}/external/fmtlib/include)
|
||||
# Not sure why this is needed.
|
||||
list(APPEND EXTRA_INCLUDES ${PROJECT_SOURCE_DIR}/external/fmtlib/include)
|
||||
endif()
|
||||
|
||||
if(OPM_ENABLE_EMBEDDED_PYTHON AND NOT OPM_ENABLE_PYTHON)
|
||||
@ -88,6 +91,10 @@ include (CMakeLists_files.cmake)
|
||||
|
||||
macro (config_hook)
|
||||
if(ENABLE_ECL_INPUT)
|
||||
if(NOT cjson_FOUND)
|
||||
list(APPEND EXTRA_INCLUDES ${PROJECT_SOURCE_DIR}/external/cjson)
|
||||
endif()
|
||||
|
||||
# For this project
|
||||
include_directories(${EXTRA_INCLUDES} ${PROJECT_BINARY_DIR}/include)
|
||||
# For downstreams
|
||||
@ -126,12 +133,6 @@ macro (prereqs_hook)
|
||||
endmacro (prereqs_hook)
|
||||
|
||||
macro (sources_hook)
|
||||
if(NOT cjson_FOUND)
|
||||
include(DownloadCjson)
|
||||
include_directories(${cjson_SOURCE_DIR})
|
||||
list(APPEND opm-common_SOURCES ${cjson_SOURCE_DIR}/cJSON.c)
|
||||
endif()
|
||||
|
||||
if(ENABLE_ECL_INPUT)
|
||||
# Keyword generation
|
||||
include(GenerateKeywords.cmake)
|
||||
@ -268,7 +269,10 @@ if (OPM_ENABLE_PYTHON)
|
||||
endif()
|
||||
find_package(pybind11 2.2 CONFIG)
|
||||
if (NOT pybind11_FOUND)
|
||||
include(DownloadPyBind11)
|
||||
add_subdirectory(python/pybind11)
|
||||
if (NOT pybind11_INCLUDE_DIRS)
|
||||
set(pybind11_INCLUDE_DIRS ${PYBIND11_INCLUDE_DIR} ${PYTHON_INCLUDE_DIRS})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -362,7 +366,7 @@ endif()
|
||||
find_package(dune-common REQUIRED)
|
||||
opm_need_version_of ("dune-common")
|
||||
target_include_directories(dunecommon INTERFACE ${dune-common_INCLUDE_DIRS})
|
||||
string(REPLACE " " ";" dflags "${dune-common_CXX_FLAGS}")
|
||||
string(REPLACE " " ";" dflags ${dune-common_CXX_FLAGS})
|
||||
target_compile_options(dunecommon INTERFACE ${dflags})
|
||||
target_compile_definitions(dunecommon INTERFACE DUNE_COMMON_VERSION_MAJOR=${DUNE_COMMON_VERSION_MAJOR})
|
||||
target_compile_definitions(dunecommon INTERFACE DUNE_COMMON_VERSION_MINOR=${DUNE_COMMON_VERSION_MINOR})
|
||||
@ -375,7 +379,6 @@ if(Boost_UNIT_TEST_FRAMEWORK_FOUND)
|
||||
endif()
|
||||
if(BUILD_EXAMPLES)
|
||||
target_link_libraries(co2brinepvt dunecommon)
|
||||
install(TARGETS co2brinepvt DESTINATION bin)
|
||||
endif()
|
||||
|
||||
# Install build system files and documentation
|
||||
|
@ -51,7 +51,6 @@ list (APPEND MAIN_SOURCE_FILES
|
||||
src/opm/material/common/TridiagonalMatrix.cpp
|
||||
src/opm/material/common/UniformXTabulated2DFunction.cpp
|
||||
src/opm/material/components/CO2.cpp
|
||||
src/opm/material/components/H2.cpp
|
||||
src/opm/material/densead/Evaluation.cpp
|
||||
src/opm/material/fluidmatrixinteractions/EclEpsScalingPoints.cpp
|
||||
src/opm/material/fluidsystems/BlackOilFluidSystem.cpp
|
||||
@ -119,7 +118,6 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/input/eclipse/EclipseState/Grid/BoxManager.cpp
|
||||
src/opm/input/eclipse/EclipseState/Grid/Carfin.cpp
|
||||
src/opm/input/eclipse/EclipseState/Grid/CarfinManager.cpp
|
||||
src/opm/input/eclipse/EclipseState/Grid/LgrCollection.cpp
|
||||
src/opm/input/eclipse/EclipseState/Grid/EclipseGrid.cpp
|
||||
src/opm/input/eclipse/EclipseState/Grid/FieldProps.cpp
|
||||
src/opm/input/eclipse/EclipseState/Grid/FieldPropsManager.cpp
|
||||
@ -142,13 +140,11 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/input/eclipse/EclipseState/InitConfig/Equil.cpp
|
||||
src/opm/input/eclipse/EclipseState/InitConfig/FoamConfig.cpp
|
||||
src/opm/input/eclipse/EclipseState/InitConfig/InitConfig.cpp
|
||||
src/opm/input/eclipse/EclipseState/IOConfig/FIPConfig.cpp
|
||||
src/opm/input/eclipse/EclipseState/IOConfig/IOConfig.cpp
|
||||
src/opm/input/eclipse/EclipseState/Runspec.cpp
|
||||
src/opm/input/eclipse/EclipseState/Phase.cpp
|
||||
src/opm/input/eclipse/EclipseState/TracerConfig.cpp
|
||||
src/opm/input/eclipse/EclipseState/MICPpara.cpp
|
||||
src/opm/input/eclipse/EclipseState/WagHysteresisConfig.cpp
|
||||
src/opm/input/eclipse/Schedule/Action/ActionAST.cpp
|
||||
src/opm/input/eclipse/Schedule/Action/ActionContext.cpp
|
||||
src/opm/input/eclipse/Schedule/Action/ActionResult.cpp
|
||||
@ -163,7 +159,6 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/input/eclipse/Schedule/Action/State.cpp
|
||||
src/opm/input/eclipse/Schedule/Action/WGNames.cpp
|
||||
src/opm/input/eclipse/Schedule/ArrayDimChecker.cpp
|
||||
src/opm/input/eclipse/Schedule/BCProp.cpp
|
||||
src/opm/input/eclipse/Schedule/CompletedCells.cpp
|
||||
src/opm/input/eclipse/Schedule/eval_uda.cpp
|
||||
src/opm/input/eclipse/Schedule/Events.cpp
|
||||
@ -175,9 +170,7 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/input/eclipse/Schedule/Group/GuideRateModel.cpp
|
||||
src/opm/input/eclipse/Schedule/Group/GConSale.cpp
|
||||
src/opm/input/eclipse/Schedule/Group/GConSump.cpp
|
||||
src/opm/input/eclipse/Schedule/Group/GroupEconProductionLimits.cpp
|
||||
src/opm/input/eclipse/Schedule/Group/GTNode.cpp
|
||||
src/opm/input/eclipse/Schedule/HandlerContext.cpp
|
||||
src/opm/input/eclipse/Schedule/KeywordHandlers.cpp
|
||||
src/opm/input/eclipse/Schedule/MessageLimits.cpp
|
||||
src/opm/input/eclipse/Schedule/MSW/icd.cpp
|
||||
@ -185,7 +178,6 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/input/eclipse/Schedule/MSW/Segment.cpp
|
||||
src/opm/input/eclipse/Schedule/MSW/SegmentMatcher.cpp
|
||||
src/opm/input/eclipse/Schedule/MSW/WellSegments.cpp
|
||||
src/opm/input/eclipse/Schedule/MSW/WelSegsSet.cpp
|
||||
src/opm/input/eclipse/Schedule/MSW/AICD.cpp
|
||||
src/opm/input/eclipse/Schedule/MSW/SICD.cpp
|
||||
src/opm/input/eclipse/Schedule/MSW/Valve.cpp
|
||||
@ -206,13 +198,11 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/input/eclipse/Schedule/Tuning.cpp
|
||||
src/opm/input/eclipse/Schedule/WriteRestartFileEvents.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/Connection.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/FilterCake.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/injection.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/NameOrder.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/PAvg.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/PAvgCalculator.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/PAvgCalculatorCollection.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/PAvgDynamicSourceData.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/Well.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/WellConnections.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/WellMatcher.cpp
|
||||
@ -228,11 +218,8 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/input/eclipse/Schedule/Well/WellTestState.cpp
|
||||
src/opm/input/eclipse/Schedule/WellTraj/RigEclipseWellLogExtractor.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/WellTracerProperties.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/WINJMULT.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/WList.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/WListManager.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/WDFAC.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/WVFPDP.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/WVFPEXP.cpp
|
||||
src/opm/input/eclipse/Schedule/WellTraj/RigEclipseWellLogExtractor.cpp
|
||||
src/opm/input/eclipse/EclipseState/SimulationConfig/BCConfig.cpp
|
||||
@ -255,7 +242,6 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/input/eclipse/EclipseState/Tables/TableContainer.cpp
|
||||
src/opm/input/eclipse/EclipseState/Tables/TableIndex.cpp
|
||||
src/opm/input/eclipse/EclipseState/Tables/TLMixpar.cpp
|
||||
src/opm/input/eclipse/EclipseState/Tables/Ppcwmax.cpp
|
||||
src/opm/input/eclipse/EclipseState/Tables/TableManager.cpp
|
||||
src/opm/input/eclipse/EclipseState/Tables/TableSchema.cpp
|
||||
src/opm/input/eclipse/EclipseState/Tables/Tables.cpp
|
||||
@ -265,22 +251,21 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/input/eclipse/EclipseState/Tables/BrineDensityTable.cpp
|
||||
src/opm/input/eclipse/EclipseState/Tables/SolventDensityTable.cpp
|
||||
src/opm/input/eclipse/EclipseState/Tables/Tabdims.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQActive.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQAssign.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQASTNode.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQConfig.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQContext.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQDefine.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQEnums.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQFunction.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQFunctionTable.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQInput.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQParams.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQParser.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQSet.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQState.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQActive.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQAssign.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQDefine.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQEnums.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQToken.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDT.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQConfig.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQContext.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQFunction.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQFunctionTable.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQInput.cpp
|
||||
src/opm/input/eclipse/Schedule/UDQ/UDQState.cpp
|
||||
src/opm/input/eclipse/Schedule/VFPInjTable.cpp
|
||||
src/opm/input/eclipse/Schedule/VFPProdTable.cpp
|
||||
src/opm/input/eclipse/Parser/ErrorGuard.cpp
|
||||
@ -306,8 +291,6 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/material/fluidmatrixinteractions/EclMaterialLawManagerHystParams.cpp
|
||||
src/opm/material/fluidsystems/blackoilpvt/BrineCo2Pvt.cpp
|
||||
src/opm/material/fluidsystems/blackoilpvt/Co2GasPvt.cpp
|
||||
src/opm/material/fluidsystems/blackoilpvt/BrineH2Pvt.cpp
|
||||
src/opm/material/fluidsystems/blackoilpvt/H2GasPvt.cpp
|
||||
src/opm/material/fluidsystems/blackoilpvt/ConstantCompressibilityBrinePvt.cpp
|
||||
src/opm/material/fluidsystems/blackoilpvt/ConstantCompressibilityOilPvt.cpp
|
||||
src/opm/material/fluidsystems/blackoilpvt/ConstantCompressibilityWaterPvt.cpp
|
||||
@ -356,6 +339,10 @@ if(ENABLE_ECL_INPUT)
|
||||
list( APPEND PYTHON_CXX_DEPENDS ${PYTHON_CXX_SOURCE_FILES}
|
||||
python/cxx/converters.hpp
|
||||
python/cxx/export.hpp)
|
||||
|
||||
if(NOT cjson_FOUND)
|
||||
list(APPEND MAIN_SOURCE_FILES external/cjson/cJSON.c)
|
||||
endif()
|
||||
endif()
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list( APPEND MAIN_SOURCE_FILES
|
||||
@ -464,29 +451,24 @@ if(ENABLE_ECL_INPUT)
|
||||
tests/rst_test.cpp
|
||||
tests/test_ActiveGridCells.cpp
|
||||
tests/test_CopyablePtr.cpp
|
||||
tests/test_CSRGraphFromCoordinates.cpp
|
||||
tests/test_ERsm.cpp
|
||||
tests/test_GuideRate.cpp
|
||||
tests/test_RestartFileView.cpp
|
||||
tests/test_EclIO.cpp
|
||||
tests/test_EGrid.cpp
|
||||
tests/test_EInit.cpp
|
||||
tests/test_ERft.cpp
|
||||
tests/test_ERst.cpp
|
||||
tests/test_ESmry.cpp
|
||||
tests/test_EInit.cpp
|
||||
tests/test_ExtESmry.cpp
|
||||
tests/test_PAvgCalculator.cpp
|
||||
tests/test_PAvgDynamicSourceData.cpp
|
||||
tests/test_Serialization.cpp
|
||||
tests/material/test_co2brinepvt.cpp
|
||||
tests/material/test_h2brinepvt.cpp
|
||||
tests/material/test_eclblackoilfluidsystem.cpp
|
||||
tests/material/test_eclblackoilpvt.cpp
|
||||
tests/material/test_eclmateriallawmanager.cpp
|
||||
tests/parser/ACTIONX.cpp
|
||||
tests/parser/ADDREGTests.cpp
|
||||
tests/parser/AquiferTests.cpp
|
||||
tests/parser/BCConfigTests.cpp
|
||||
tests/parser/BoxTests.cpp
|
||||
tests/parser/CarfinTests.cpp
|
||||
tests/parser/ColumnSchemaTests.cpp
|
||||
@ -502,7 +484,6 @@ if(ENABLE_ECL_INPUT)
|
||||
tests/parser/FaceDirTests.cpp
|
||||
tests/parser/FaultTests.cpp
|
||||
tests/parser/FieldPropsTests.cpp
|
||||
tests/parser/FIPConfigTests.cpp
|
||||
tests/parser/FoamTests.cpp
|
||||
tests/parser/FunctionalTests.cpp
|
||||
tests/parser/GeomodifierTests.cpp
|
||||
@ -510,7 +491,6 @@ if(ENABLE_ECL_INPUT)
|
||||
tests/parser/ImportTests.cpp
|
||||
tests/parser/InitConfigTest.cpp
|
||||
tests/parser/IOConfigTests.cpp
|
||||
tests/parser/LgrTests.cpp
|
||||
tests/parser/MICPTests.cpp
|
||||
tests/parser/MessageLimitTests.cpp
|
||||
tests/parser/MultiRegTests.cpp
|
||||
@ -550,7 +530,6 @@ if(ENABLE_ECL_INPUT)
|
||||
tests/parser/TransMultTests.cpp
|
||||
tests/parser/TuningTests.cpp
|
||||
tests/parser/UDQTests.cpp
|
||||
tests/parser/UDTTests.cpp
|
||||
tests/parser/UnitTests.cpp
|
||||
tests/parser/integration/NNCTests.cpp
|
||||
tests/parser/WellSolventTests.cpp
|
||||
@ -605,13 +584,6 @@ list(APPEND TEST_SOURCE_FILES ${DUNE_TEST_SOURCE_FILES})
|
||||
|
||||
list (APPEND TEST_DATA_FILES
|
||||
tests/testdata.param
|
||||
tests/material/brine_unittest.json
|
||||
tests/material/co2_unittest_part1.json
|
||||
tests/material/co2_unittest_part2.json
|
||||
tests/material/co2_unittest_above_sat.json
|
||||
tests/material/co2_unittest_below_sat.json
|
||||
tests/material/h2o_unittest.json
|
||||
tests/material/h2_unittest.json
|
||||
)
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
list (APPEND TEST_DATA_FILES
|
||||
@ -760,8 +732,6 @@ list( APPEND PUBLIC_HEADER_FILES
|
||||
opm/common/OpmLog/StreamLog.hpp
|
||||
opm/common/OpmLog/TimerLog.hpp
|
||||
opm/common/utility/ActiveGridCells.hpp
|
||||
opm/common/utility/CSRGraphFromCoordinates.hpp
|
||||
opm/common/utility/CSRGraphFromCoordinates_impl.hpp
|
||||
opm/common/utility/Demangle.hpp
|
||||
opm/common/utility/FileSystem.hpp
|
||||
opm/common/utility/OpmInputError.hpp
|
||||
@ -812,7 +782,6 @@ list( APPEND PUBLIC_HEADER_FILES
|
||||
opm/material/components/Air.hpp
|
||||
opm/material/components/C1.hpp
|
||||
opm/material/components/Brine.hpp
|
||||
opm/material/components/BrineDynamic.hpp
|
||||
opm/material/fluidstates/BlackOilFluidState.hpp
|
||||
opm/material/fluidstates/NonEquilibriumFluidState.hpp
|
||||
opm/material/fluidstates/FluidStateSaturationModules.hpp
|
||||
@ -846,7 +815,6 @@ list( APPEND PUBLIC_HEADER_FILES
|
||||
opm/material/binarycoefficients/H2O_CO2.hpp
|
||||
opm/material/binarycoefficients/Air_Xylene.hpp
|
||||
opm/material/binarycoefficients/Brine_CO2.hpp
|
||||
opm/material/binarycoefficients/Brine_H2.hpp
|
||||
opm/material/binarycoefficients/HenryIapws.hpp
|
||||
opm/material/Constants.hpp
|
||||
opm/material/fluidsystems/NullParameterCache.hpp
|
||||
@ -870,7 +838,6 @@ list( APPEND PUBLIC_HEADER_FILES
|
||||
opm/material/fluidsystems/blackoilpvt/WaterPvtThermal.hpp
|
||||
opm/material/fluidsystems/blackoilpvt/WaterPvtMultiplexer.hpp
|
||||
opm/material/fluidsystems/blackoilpvt/BrineCo2Pvt.hpp
|
||||
opm/material/fluidsystems/blackoilpvt/BrineH2Pvt.hpp
|
||||
opm/material/fluidsystems/blackoilpvt/OilPvtMultiplexer.hpp
|
||||
opm/material/fluidsystems/blackoilpvt/GasPvtMultiplexer.hpp
|
||||
opm/material/fluidsystems/blackoilpvt/DryHumidGasPvt.hpp
|
||||
@ -883,11 +850,9 @@ list( APPEND PUBLIC_HEADER_FILES
|
||||
opm/material/fluidsystems/blackoilpvt/ConstantCompressibilityBrinePvt.hpp
|
||||
opm/material/fluidsystems/blackoilpvt/GasPvtThermal.hpp
|
||||
opm/material/fluidsystems/blackoilpvt/Co2GasPvt.hpp
|
||||
opm/material/fluidsystems/blackoilpvt/H2GasPvt.hpp
|
||||
opm/material/fluidsystems/blackoilpvt/ConstantCompressibilityOilPvt.hpp
|
||||
opm/material/fluidsystems/H2OAirFluidSystem.hpp
|
||||
opm/material/fluidsystems/H2ON2FluidSystem.hpp
|
||||
opm/material/fluidsystems/ThreeComponentFluidSystem.hh
|
||||
opm/material/fluidmatrixinteractions/EclTwoPhaseMaterial.hpp
|
||||
opm/material/fluidmatrixinteractions/SatCurveMultiplexerParams.hpp
|
||||
opm/material/fluidmatrixinteractions/EclTwoPhaseMaterialParams.hpp
|
||||
@ -1103,7 +1068,6 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/input/eclipse/EclipseState/Grid/Fault.hpp
|
||||
opm/input/eclipse/EclipseState/Grid/Box.hpp
|
||||
opm/input/eclipse/EclipseState/Grid/Carfin.hpp
|
||||
opm/input/eclipse/EclipseState/Grid/LgrCollection.hpp
|
||||
opm/input/eclipse/EclipseState/Grid/FieldProps.hpp
|
||||
opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp
|
||||
opm/input/eclipse/EclipseState/Grid/FaultFace.hpp
|
||||
@ -1117,7 +1081,6 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/input/eclipse/EclipseState/EndpointScaling.hpp
|
||||
opm/input/eclipse/EclipseState/TracerConfig.hpp
|
||||
opm/input/eclipse/EclipseState/MICPpara.hpp
|
||||
opm/input/eclipse/EclipseState/WagHysteresisConfig.hpp
|
||||
opm/input/eclipse/EclipseState/Tables/DenT.hpp
|
||||
opm/input/eclipse/EclipseState/Tables/JouleThomson.hpp
|
||||
opm/input/eclipse/EclipseState/Tables/SimpleTable.hpp
|
||||
@ -1149,7 +1112,6 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/input/eclipse/EclipseState/Tables/SgcwmisTable.hpp
|
||||
opm/input/eclipse/EclipseState/Tables/Sof2Table.hpp
|
||||
opm/input/eclipse/EclipseState/Tables/TLMixpar.hpp
|
||||
opm/input/eclipse/EclipseState/Tables/Ppcwmax.hpp
|
||||
opm/input/eclipse/EclipseState/Tables/TableManager.hpp
|
||||
opm/input/eclipse/EclipseState/Tables/SwfnTable.hpp
|
||||
opm/input/eclipse/EclipseState/Tables/EnptvdTable.hpp
|
||||
@ -1231,7 +1193,6 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/input/eclipse/Schedule/Action/State.hpp
|
||||
opm/input/eclipse/Schedule/Action/WGNames.hpp
|
||||
opm/input/eclipse/Schedule/ArrayDimChecker.hpp
|
||||
opm/input/eclipse/Schedule/BCProp.hpp
|
||||
opm/input/eclipse/Schedule/GasLiftOpt.hpp
|
||||
opm/input/eclipse/Schedule/Network/Balance.hpp
|
||||
opm/input/eclipse/Schedule/Network/Branch.hpp
|
||||
@ -1240,11 +1201,9 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/input/eclipse/Schedule/VFPInjTable.hpp
|
||||
opm/input/eclipse/Schedule/VFPProdTable.hpp
|
||||
opm/input/eclipse/Schedule/Well/Connection.hpp
|
||||
opm/input/eclipse/Schedule/Well/FilterCake.hpp
|
||||
opm/input/eclipse/Schedule/Well/PAvg.hpp
|
||||
opm/input/eclipse/Schedule/Well/PAvgCalculator.hpp
|
||||
opm/input/eclipse/Schedule/Well/PAvgCalculatorCollection.hpp
|
||||
opm/input/eclipse/Schedule/Well/PAvgDynamicSourceData.hpp
|
||||
opm/input/eclipse/Schedule/Well/Well.hpp
|
||||
opm/input/eclipse/Schedule/Well/WellEnums.hpp
|
||||
opm/input/eclipse/Schedule/Well/WellInjectionControls.hpp
|
||||
@ -1259,9 +1218,6 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/input/eclipse/Schedule/Well/WellMICPProperties.hpp
|
||||
opm/input/eclipse/Schedule/Well/WellPolymerProperties.hpp
|
||||
opm/input/eclipse/Schedule/Well/WellTracerProperties.hpp
|
||||
opm/input/eclipse/Schedule/Well/WINJMULT.hpp
|
||||
opm/input/eclipse/Schedule/Well/WDFAC.hpp
|
||||
opm/input/eclipse/Schedule/Well/WVFPDP.hpp
|
||||
opm/input/eclipse/Schedule/Well/WVFPEXP.hpp
|
||||
opm/input/eclipse/Schedule/Well/WellTestConfig.hpp
|
||||
opm/input/eclipse/Schedule/Well/WellTestState.hpp
|
||||
@ -1284,7 +1240,6 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/input/eclipse/Schedule/Group/GuideRate.hpp
|
||||
opm/input/eclipse/Schedule/Group/GConSale.hpp
|
||||
opm/input/eclipse/Schedule/Group/GConSump.hpp
|
||||
opm/input/eclipse/Schedule/Group/GroupEconProductionLimits.hpp
|
||||
opm/input/eclipse/Schedule/Group/GuideRateConfig.hpp
|
||||
opm/input/eclipse/Schedule/Group/GuideRateModel.hpp
|
||||
opm/input/eclipse/Schedule/MessageLimits.hpp
|
||||
@ -1302,26 +1257,24 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/input/eclipse/EclipseState/SimulationConfig/RockConfig.hpp
|
||||
opm/input/eclipse/EclipseState/SimulationConfig/SimulationConfig.hpp
|
||||
opm/input/eclipse/Schedule/MSW/Valve.hpp
|
||||
opm/input/eclipse/EclipseState/IOConfig/FIPConfig.hpp
|
||||
opm/input/eclipse/EclipseState/IOConfig/IOConfig.hpp
|
||||
opm/input/eclipse/EclipseState/checkDeck.hpp
|
||||
opm/input/eclipse/EclipseState/Phase.hpp
|
||||
opm/input/eclipse/EclipseState/Runspec.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQActive.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQAssign.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQASTNode.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQContext.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQDefine.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQContext.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQState.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQEnums.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQParams.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQInput.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQActive.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQSet.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQToken.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQFunction.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQFunctionTable.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQInput.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQParams.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQSet.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQState.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDQToken.hpp
|
||||
opm/input/eclipse/Schedule/UDQ/UDT.hpp
|
||||
opm/input/eclipse/Deck/DeckItem.hpp
|
||||
opm/input/eclipse/Deck/Deck.hpp
|
||||
opm/input/eclipse/Deck/DeckView.hpp
|
||||
|
@ -33,7 +33,7 @@ set(genkw_SOURCES src/opm/json/JsonObject.cpp
|
||||
src/opm/common/OpmLog/LogUtil.cpp
|
||||
)
|
||||
if(NOT cjson_FOUND)
|
||||
list(APPEND genkw_SOURCES ${cjson_SOURCE_DIR}/cJSON.c)
|
||||
list(APPEND genkw_SOURCES external/cjson/cJSON.c)
|
||||
endif()
|
||||
add_executable(genkw ${genkw_SOURCES})
|
||||
|
||||
|
@ -1,18 +0,0 @@
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(cjson
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP ON
|
||||
URL https://github.com/DaveGamble/cJSON/archive/refs/tags/v1.7.16.tar.gz
|
||||
URL_HASH SHA512=3a894de03c33d89f1e7ee572418d5483c844d38e1e64aa4f6297ddaa01f4111f07601f8d26617b424b5af15d469e3955dae075d9f30b5c25e16ec348fdb06e6f)
|
||||
FetchContent_Populate(cjson)
|
||||
|
||||
# set(ENABLE_CJSON_TEST OFF CACHE BOOL "")
|
||||
# set(BUILD_SHARED_AND_STATIC_LIBS OFF CACHE BOOL "")
|
||||
# set(CJSON_BUILD_SHARED_LIBS OFF CACHE BOOL "")
|
||||
# set(CJSON_OVERRIDE_BUILD_SHARED_LIBS ON CACHE BOOL "")
|
||||
|
||||
# add_subdirectory(${cjson_SOURCE_DIR} ${cjson_BINARY_DIR})
|
||||
|
||||
# add_library(cjson::cjson STATIC IMPORTED)
|
||||
# set_target_properties(cjson::cjson PROPERTIES
|
||||
# INTERFACE_INCLUDE_DIRECTORIES ${cjson_SOURCE_DIR}
|
||||
# IMPORTED_LOCATION lib/libcjson.a)
|
@ -1,17 +0,0 @@
|
||||
include(FetchContent)
|
||||
|
||||
if(NOT fmt_POPULATED)
|
||||
FetchContent_Declare(fmt
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP ON
|
||||
URL https://github.com/fmtlib/fmt/archive/refs/tags/10.1.1.tar.gz
|
||||
URL_HASH SHA512=288c349baac5f96f527d5b1bed0fa5f031aa509b4526560c684281388e91909a280c3262a2474d963b5d1bf7064b1c9930c6677fe54a0d8f86982d063296a54c)
|
||||
FetchContent_Populate(fmt)
|
||||
endif()
|
||||
|
||||
# We do not want to use the target directly as that means it ends up
|
||||
# in our depends list for downstream modules and the installation list.
|
||||
# Instead, we just download and use header only mode.
|
||||
add_compile_definitions(FMT_HEADER_ONLY)
|
||||
include_directories(${fmt_SOURCE_DIR}/include)
|
||||
set(fmt_POPULATED ${fmt_POPULATED} PARENT_SCOPE)
|
||||
set(fmt_SOURCE_DIR ${fmt_SOURCE_DIR} PARENT_SCOPE)
|
@ -1,6 +0,0 @@
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(pybind11
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP ON
|
||||
URL https://github.com/pybind/pybind11/archive/refs/tags/v2.11.1.tar.gz
|
||||
URL_HASH SHA512=ed1512ff0bca3bc0a45edc2eb8c77f8286ab9389f6ff1d5cb309be24bc608abbe0df6a7f5cb18c8f80a3bfa509058547c13551c3cd6a759af708fd0cdcdd9e95)
|
||||
FetchContent_MakeAvailable(pybind11)
|
@ -294,7 +294,7 @@ if(SuiteSparse_FOUND)
|
||||
string (TOUPPER ${_module} _MODULE)
|
||||
if(SuiteSparse_${_MODULE}_FOUND)
|
||||
if(NOT TARGET SuiteSparse::${_module})
|
||||
message(STATUS "Creating target SuiteSparse::${_module}")
|
||||
message(STATUS "Creating target SuitSparse::${_module}")
|
||||
add_library(SuiteSparse::${_module} UNKNOWN IMPORTED GLOBAL)
|
||||
set_target_properties(SuiteSparse::${_module} PROPERTIES
|
||||
IMPORTED_LOCATION ${${_MODULE}_LIBRARY}
|
||||
|
@ -19,7 +19,8 @@ find_opm_package (
|
||||
# TODO: we should probe for all the HAVE_* values listed below;
|
||||
# however, we don't actually use them in our implementation, so
|
||||
# we just include them to forward here in case anyone else does
|
||||
"dune-common REQUIRED"
|
||||
"dune-common REQUIRED;
|
||||
"
|
||||
# header to search for
|
||||
"dune/polygongrid/mesh.hh"
|
||||
|
||||
|
200
cmake/Modules/LibtoolArchives.cmake
Normal file
200
cmake/Modules/LibtoolArchives.cmake
Normal file
@ -0,0 +1,200 @@
|
||||
# translate a list of libraries into a command-line that can be passed to the
|
||||
# compiler/linker. first parameter is the name of the variable that will
|
||||
# receive this list, the rest is considered the list of libraries
|
||||
function (linker_cmdline what INTO outvar FROM)
|
||||
if (NOT (UNIX OR MSYS OR MINGW))
|
||||
return ()
|
||||
endif (NOT (UNIX OR MSYS OR MINGW))
|
||||
|
||||
# if we are going to put these in regexps, we must escape period
|
||||
string (REPLACE "." "\\." esc_dl_pref "${CMAKE_SHARED_LIBRARY_PREFIX}")
|
||||
string (REPLACE "." "\\." esc_dl_suff "${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
string (REPLACE "." "\\." esc_ar_pref "${CMAKE_STATIC_LIBRARY_PREFIX}")
|
||||
string (REPLACE "." "\\." esc_ar_suff "${CMAKE_STATIC_LIBRARY_PREFIX}")
|
||||
|
||||
# CMake loves absolute paths, whereas libtool won't have any of it!
|
||||
# (you get an error message about argument not parsed). translate each
|
||||
# of the libraries into a linker option
|
||||
set (deplib_list "")
|
||||
set (deplib_list_tmp "")
|
||||
foreach (deplib IN LISTS ARGN)
|
||||
# resolve imported targets
|
||||
string(FIND ${deplib} "::" _sep)
|
||||
if (_sep GREATER "-1")
|
||||
set(_lib "")
|
||||
# the code below does not really work for imported interface library
|
||||
# as cmake will error out whene querying IMPORTED_LOCATION, because the
|
||||
# property is not whitelisted. I have no idea how to determine if
|
||||
# a library is an imported interface library
|
||||
# At least it works for resolving OpenMP::OpenMP_CXX
|
||||
#
|
||||
# get_property(_def TARGET ${deplib} PROPERTY IMPORTED_LOCATION DEFINED)
|
||||
# if (_def)
|
||||
# get_property(_def TARGET ${deplib} PROPERTY IMPORTED_LOCATION SET)
|
||||
# if (_def)
|
||||
# get_target_property(_tmp_lib ${deplib} IMPORTED_LOCATION)
|
||||
# list(APPEND _lib ${_tmp_lib})
|
||||
# endif()
|
||||
# endif()
|
||||
get_property(_def TARGET ${deplib} PROPERTY INTERFACE_LINK_LIBRARIES SET)
|
||||
if (_def)
|
||||
get_target_property(_tmp_lib ${deplib} INTERFACE_LINK_LIBRARIES)
|
||||
list(APPEND _lib ${_tmp_lib})
|
||||
endif()
|
||||
set(deplib ${_lib})
|
||||
endif()
|
||||
list(APPEND deplib_list_tmp ${deplib})
|
||||
endforeach()
|
||||
foreach (deplib IN LISTS deplib_list_tmp)
|
||||
# starts with a hyphen already? then just add it
|
||||
string (SUBSTRING ${deplib} 0 1 dash)
|
||||
if (${dash} STREQUAL "-")
|
||||
list (APPEND deplib_list ${deplib})
|
||||
else (${dash} STREQUAL "-")
|
||||
# otherwise, parse the name into a directory and a name
|
||||
get_filename_component (deplib_dir ${deplib} PATH)
|
||||
get_filename_component (deplib_orig ${deplib} NAME)
|
||||
string (REGEX REPLACE
|
||||
"^${esc_dl_pref}(.*)${esc_dl_suff}$"
|
||||
"\\1"
|
||||
deplib_name
|
||||
${deplib_orig}
|
||||
)
|
||||
string (REGEX REPLACE
|
||||
"^${esc_ar_pref}(.*)${esc_ar_suff}$"
|
||||
"\\1"
|
||||
deplib_name
|
||||
${deplib_name}
|
||||
)
|
||||
# directory and name each on their own; this is somewhat
|
||||
# unsatisfactory because it may be that a system dir is specified
|
||||
# by an earlier directory and you start picking up libraries from
|
||||
# there instead of the "closest" path here. also, the soversion
|
||||
# is more or less lost. remove system default path, to lessen the
|
||||
# chance that we pick the wrong library
|
||||
if (NOT ((deplib_dir STREQUAL "/usr/lib") OR
|
||||
(deplib_dir STREQUAL "") OR
|
||||
(deplib_dir STREQUAL "/usr/${CMAKE_INSTALL_LIBDIR}")))
|
||||
list (APPEND deplib_list "-L${deplib_dir}")
|
||||
endif ()
|
||||
# if there was no translation of the name, the library is named
|
||||
# unconventionally (.so.3gf, I'm looking at you), so pass this
|
||||
# name unmodified to the linker switch
|
||||
if (deplib_orig STREQUAL deplib_name AND
|
||||
NOT deplib_orig STREQUAL "stdc++fs")
|
||||
list (APPEND deplib_list "-l:${deplib_orig}")
|
||||
else ()
|
||||
list (APPEND deplib_list "-l${deplib_name}")
|
||||
endif (deplib_orig STREQUAL deplib_name AND
|
||||
NOT deplib_orig STREQUAL "stdc++fs")
|
||||
endif (${dash} STREQUAL "-")
|
||||
endforeach (deplib)
|
||||
# caller determines whether we want it returned as a list or a string
|
||||
if ("${what}" STREQUAL "LIST")
|
||||
set (${outvar} ${deplib_list})
|
||||
else ("${what}" STREQUAL "LIST")
|
||||
set (${outvar} "${deplib_list}")
|
||||
string (REPLACE ";" " " ${outvar} "${${outvar}}")
|
||||
endif ("${what}" STREQUAL "LIST")
|
||||
set (${outvar} "${${outvar}}" PARENT_SCOPE)
|
||||
endfunction (linker_cmdline what INTO outvar FROM)
|
||||
|
||||
function (configure_la name target)
|
||||
if (NOT (UNIX OR MSYS OR MINGW))
|
||||
return ()
|
||||
endif (NOT (UNIX OR MSYS OR MINGW))
|
||||
|
||||
# these generic variables are initialized from the project info
|
||||
set (current "${${name}_VERSION_MAJOR}")
|
||||
set (age "${${name}_VERSION_MINOR}")
|
||||
set (inherited_linker_flags "${${name}_LINKER_FLAGS}")
|
||||
set (dependency_libs "${${name}_LIBRARIES}")
|
||||
|
||||
# translate list of libraries to command line
|
||||
linker_cmdline (LIST INTO dependency_libs FROM ${dependency_libs})
|
||||
|
||||
# convert from CMake list (i.e. semi-colon separated)
|
||||
string (REPLACE ";" " " inherited_linker_flags "${inherited_linker_flags}")
|
||||
string (REPLACE ";" " " dependency_libs "${dependency_libs}")
|
||||
|
||||
# this is the preferred installation path
|
||||
set (libdir "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
|
||||
|
||||
# ${name}_LIBRARY_TYPE is either SHARED or STATIC
|
||||
if (${name}_LIBRARY_TYPE STREQUAL "SHARED")
|
||||
set (libprefix "${CMAKE_SHARED_LIBRARY_PREFIX}")
|
||||
set (libsuffix "${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
set (libname "${CMAKE_SHARED_LIBRARY_PREFIX}${target}${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
# only Unix has soversion in library names
|
||||
if (UNIX)
|
||||
set (dlname "${libname}.${current}")
|
||||
set (library_names "${libname}.${current}.${age} ${libname}.${current} ${libname}")
|
||||
else (UNIX)
|
||||
set (dlname "${libname}")
|
||||
set (library_names "${libname}")
|
||||
endif (UNIX)
|
||||
set (old_library "")
|
||||
else (${name}_LIBRARY_TYPE STREQUAL "SHARED")
|
||||
set (dlname "")
|
||||
set (library_names "")
|
||||
set (old_library "${CMAKE_STATIC_LIBRARY_PREFIX}${target}${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
endif (${name}_LIBRARY_TYPE STREQUAL "SHARED")
|
||||
|
||||
# get the version of libtool installed on the system; this is
|
||||
# necessary because libtool checks that the file contains its own
|
||||
# signature(!)
|
||||
if (NOT libtool_MAIN)
|
||||
find_file (
|
||||
libtool_MAIN
|
||||
ltmain.sh
|
||||
PATHS /usr
|
||||
PATH_SUFFIXES share/libtool/config/
|
||||
DOC "Location of libtool"
|
||||
)
|
||||
mark_as_advanced (libtool_MAIN)
|
||||
# notify the user if it not found after we explicitly searched
|
||||
if (NOT libtool_MAIN)
|
||||
message (STATUS "Not generating libtool archive (.la) since libtool was not found")
|
||||
endif (NOT libtool_MAIN)
|
||||
endif (NOT libtool_MAIN)
|
||||
if (libtool_MAIN)
|
||||
file (STRINGS
|
||||
${libtool_MAIN}
|
||||
ltversion_STRING
|
||||
REGEX "^VERSION=\".*\""
|
||||
)
|
||||
endif (libtool_MAIN)
|
||||
if (ltversion_STRING)
|
||||
string (REGEX REPLACE
|
||||
"^VERSION=\"?(.*)\"?"
|
||||
"\\1"
|
||||
ltversion
|
||||
${ltversion_STRING}
|
||||
)
|
||||
endif (ltversion_STRING)
|
||||
|
||||
# assume that we are in cmake/Modules, and that the template have been
|
||||
# put in cmake/Templates. we cannot use CMAKE_CURRENT_LIST_DIR because
|
||||
# this is in a function, and we cannot know who's calling us
|
||||
set (templ_dir "${OPM_MACROS_ROOT}/cmake/Templates")
|
||||
|
||||
|
||||
# only write an .la if libtool is found; otherwise we have no use
|
||||
# for it.
|
||||
if (ltversion)
|
||||
set (la_file "lib${target}.la")
|
||||
message (STATUS "Writing libtool archive for ${target}")
|
||||
configure_file (
|
||||
${templ_dir}/la.in
|
||||
${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/${la_file}
|
||||
@ONLY@
|
||||
)
|
||||
else (ltversion)
|
||||
set (la_file "")
|
||||
endif (ltversion)
|
||||
|
||||
# return this variable to the caller
|
||||
if (ARGV2)
|
||||
set (${ARGV2} "${la_file}" PARENT_SCOPE)
|
||||
endif (ARGV2)
|
||||
endfunction (configure_la target)
|
@ -110,10 +110,6 @@ macro (OpmInitDirVars)
|
||||
endif (COMMAND dir_hook)
|
||||
endmacro ()
|
||||
|
||||
if("${CMAKE_SIZEOF_VOID_P}" LESS 8)
|
||||
message(FATAL_ERROR "OPM will only work correctly on 64bit (or higher) systems!")
|
||||
endif()
|
||||
|
||||
OpmInitProjVars ()
|
||||
OpmInitDirVars ()
|
||||
|
||||
|
@ -1,5 +1,38 @@
|
||||
# - Helper routines for opm-core like projects
|
||||
|
||||
include (LibtoolArchives) # linker_cmdline
|
||||
|
||||
# convert a list back to a command-line string
|
||||
function (unseparate_args var_name prefix value)
|
||||
separate_arguments (value)
|
||||
foreach (item IN LISTS value)
|
||||
set (prefixed_item "${prefix}${item}")
|
||||
if (${var_name})
|
||||
set (${var_name} "${${var_name}} ${prefixed_item}")
|
||||
else (${var_name})
|
||||
set (${var_name} "${prefixed_item}")
|
||||
endif (${var_name})
|
||||
endforeach (item)
|
||||
set (${var_name} "${${var_name}}" PARENT_SCOPE)
|
||||
endfunction (unseparate_args var_name prefix value)
|
||||
|
||||
# wrapper to set variables in pkg-config file
|
||||
function (configure_pc_file name source dest prefix libdir includedir)
|
||||
# escape set of standard strings
|
||||
unseparate_args (includes "-I" "${${name}_INCLUDE_DIRS}")
|
||||
unseparate_args (defs "" "${${name}_DEFINITIONS}")
|
||||
linker_cmdline (STRING INTO libs FROM ${${name}_LIBRARIES})
|
||||
|
||||
# necessary to make these variables visible to configure_file
|
||||
set (name "${${name}_NAME}")
|
||||
set (description "${${name}_DESCRIPTION}")
|
||||
set (major "${${name}_VERSION_MAJOR}")
|
||||
set (minor "${${name}_VERSION_MINOR}")
|
||||
set (target "${${name}_LIBRARY}")
|
||||
linker_cmdline (STRING INTO target from ${target})
|
||||
configure_file (${source} ${dest} @ONLY)
|
||||
endfunction (configure_pc_file name source dist prefix libdir includedir)
|
||||
|
||||
function (configure_cmake_file name variant version)
|
||||
# declarative list of the variable names that are used in the template
|
||||
# and that must be defined in the project to be exported
|
||||
@ -58,6 +91,16 @@ function (opm_cmake_config name)
|
||||
APPEND "${${name}_CONFIG_VARS}"
|
||||
)
|
||||
|
||||
# config-mode .pc file; use this to find the build tree
|
||||
configure_pc_file (
|
||||
${name}
|
||||
${template_dir}/opm-project.pc.in
|
||||
${PROJECT_BINARY_DIR}/${${name}_NAME}.pc
|
||||
${PROJECT_BINARY_DIR}
|
||||
"${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"
|
||||
${PROJECT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
# The next replace will result in bogus entries if install directory is
|
||||
# a subdirectory of source tree,
|
||||
# and we have existing entries pointing to that install directory.
|
||||
@ -111,4 +154,28 @@ function (opm_cmake_config name)
|
||||
FILES ${PROJECT_BINARY_DIR}/${${name}_NAME}-config-version.cmake
|
||||
DESTINATION share/cmake${${name}_VER_DIR}/${${name}_NAME}
|
||||
)
|
||||
|
||||
# find-mode .pc file; use this to locate system installation
|
||||
configure_pc_file (
|
||||
${name}
|
||||
${template_dir}/opm-project.pc.in
|
||||
${PROJECT_BINARY_DIR}/${${name}_NAME}-install.pc
|
||||
${CMAKE_INSTALL_PREFIX}
|
||||
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${${name}_VER_DIR}
|
||||
${CMAKE_INSTALL_PREFIX}/include${${name}_VER_DIR}
|
||||
)
|
||||
|
||||
# put this in the right system location; if we have binaries then it
|
||||
# should go in the arch-specific lib/ directory, otherwise use the
|
||||
# common/noarch lib/ directory (these targets come from UseMultiArch)
|
||||
if (${name}_TARGET)
|
||||
set (_pkg_dir ${CMAKE_INSTALL_LIBDIR})
|
||||
else ()
|
||||
set (_pkg_dir lib)
|
||||
endif ()
|
||||
install (
|
||||
FILES ${PROJECT_BINARY_DIR}/${${name}_NAME}-install.pc
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/${_pkg_dir}/pkgconfig${${name}_VER_DIR}/
|
||||
RENAME ${${name}_NAME}.pc
|
||||
)
|
||||
endfunction (opm_cmake_config name)
|
||||
|
@ -305,10 +305,7 @@ macro(opm_add_test TestName)
|
||||
target_link_libraries (${CURTEST_EXE_NAME} ${CURTEST_LIBRARIES})
|
||||
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
|
||||
add_static_analysis_tests(CURTEST_SOURCES dirs)
|
||||
if(HAVE_DYNAMIC_BOOST_TEST)
|
||||
set_target_properties (${CURTEST_EXE_NAME} PROPERTIES
|
||||
COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK)
|
||||
endif()
|
||||
|
||||
if(TARGET ${project}_prepare)
|
||||
add_dependencies("${CURTEST_EXE_NAME}" ${project}_prepare)
|
||||
endif()
|
||||
|
103
cmake/Modules/OpmStaticTargets.cmake
Normal file
103
cmake/Modules/OpmStaticTargets.cmake
Normal file
@ -0,0 +1,103 @@
|
||||
####################################################################
|
||||
# #
|
||||
# Setup static targets for all submodules. #
|
||||
# Useful when building a static benchmark executable #
|
||||
# #
|
||||
####################################################################
|
||||
|
||||
# Macros
|
||||
|
||||
# Clone a git and build it statically
|
||||
# If ARGN is specified installation is skipped, ARGN0 is
|
||||
# a build-system target name and the rest of ARGN are build tool parameters
|
||||
function(opm_from_git repo name revision)
|
||||
if(ARGN)
|
||||
list(GET ARGN 0 target)
|
||||
list(REMOVE_AT ARGN 0)
|
||||
# This is used for top build of benchmarks.
|
||||
# Clones the local source tree and builds it against the static libraries,
|
||||
# skipping the install step. Note that in pricinple URL instead of GIT_REPOSITORY
|
||||
# could have been used, but externalproject cannot handle build directories
|
||||
# which are a subdirectory of the source tree, and since that is typically the case
|
||||
# we work-around by re-cloning the local git.
|
||||
# The ommision of GIT_TAG ensures that we build the tip of the local git.
|
||||
set(COMMANDS BUILD_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --target ${target} -- ${ARGN}
|
||||
GIT_TAG ${revision}
|
||||
INSTALL_COMMAND)
|
||||
else()
|
||||
# This is used with "normal" static builds.
|
||||
set(COMMANDS GIT_TAG ${revision})
|
||||
endif()
|
||||
externalproject_add(${name}-static
|
||||
GIT_REPOSITORY ${repo}
|
||||
PREFIX static/${name}
|
||||
CONFIGURE_COMMAND PKG_CONFIG_PATH=${CMAKE_BINARY_DIR}/static/installed/lib/pkgconfig:${CMAKE_BINARY_DIR}/static/installed/${CMAKE_INSTALL_LIBDIR}/pkgconfig:$ENV{PKG_CONFIG_PATH}
|
||||
${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/static/installed
|
||||
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
|
||||
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
-DBUILD_SHARED_LIBS=0
|
||||
-DBUILD_TESTING=0 -DBUILD_EXAMPLES=0 <SOURCE_DIR>
|
||||
-G ${CMAKE_GENERATOR}
|
||||
${COMMANDS} "")
|
||||
set_target_properties(${name}-static PROPERTIES EXCLUDE_FROM_ALL 1)
|
||||
endfunction()
|
||||
|
||||
# Convenience macro for adding dependencies without having to include the -static all over
|
||||
macro(opm_static_add_dependencies target)
|
||||
foreach(arg ${ARGN})
|
||||
add_dependencies(${target}-static ${arg}-static)
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
include(ExternalProject)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# Defaults to building master
|
||||
if(NOT OPM_BENCHMARK_VERSION)
|
||||
set(OPM_BENCHMARK_VERSION "origin/master")
|
||||
endif()
|
||||
|
||||
# ERT
|
||||
externalproject_add(ert-static
|
||||
GIT_REPOSITORY https://github.com/Ensembles/ert
|
||||
PREFIX static/ert
|
||||
GIT_TAG ${revision}
|
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND}
|
||||
-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/static/installed
|
||||
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
-DBUILD_SHARED_LIBS=0 <SOURCE_DIR>/devel)
|
||||
set_target_properties(ert-static PROPERTIES EXCLUDE_FROM_ALL 1)
|
||||
|
||||
# 2015.04 release used dune v2.3.1
|
||||
if(OPM_BENCHMARK_VERSION STREQUAL "release/2015.04/final")
|
||||
set(DUNE_VERSION v2.3.1)
|
||||
endif()
|
||||
|
||||
# Master currently uses dune v2.3.1
|
||||
if(OPM_BENCHMARK_VERSION STREQUAL "origin/master")
|
||||
set(DUNE_VERSION v2.3.1)
|
||||
endif()
|
||||
|
||||
# Fallback
|
||||
if(NOT DUNE_VERSION)
|
||||
set(DUNE_VERSION v2.3.1)
|
||||
endif()
|
||||
|
||||
# Dune
|
||||
foreach(dune_repo dune-common dune-geometry dune-grid dune-istl)
|
||||
opm_from_git(http://git.dune-project.org/repositories/${dune_repo} ${dune_repo} ${DUNE_VERSION})
|
||||
endforeach()
|
||||
opm_static_add_dependencies(dune-istl dune-common)
|
||||
opm_static_add_dependencies(dune-geometry dune-common)
|
||||
opm_static_add_dependencies(dune-grid dune-geometry)
|
||||
|
||||
# OPM
|
||||
foreach(opm_repo opm-common opm-parser opm-core opm-output opm-grid opm-material
|
||||
opm-upscaling)
|
||||
opm_from_git(https://github.com/OPM/${opm_repo} ${opm_repo} ${OPM_BENCHMARK_VERSION})
|
||||
endforeach()
|
||||
opm_static_add_dependencies(opm-parser opm-common ert)
|
||||
opm_static_add_dependencies(opm-core opm-parser dune-istl)
|
||||
opm_static_add_dependencies(opm-grid opm-core dune-grid)
|
||||
opm_static_add_dependencies(opm-material opm-core)
|
||||
opm_static_add_dependencies(opm-upscaling opm-grid opm-material)
|
@ -18,7 +18,7 @@ if(USE_DAMARIS_LIB AND MPI_FOUND)
|
||||
message(STATUS "The Damaris library does NOT have Catalyst support")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "The Damaris library was requested but NOT found")
|
||||
message(STATUS "The Damaris library was requested but NOT found")
|
||||
endif()
|
||||
else() # User did not request Damaris support
|
||||
unset(HAVE_DAMARIS)
|
||||
|
20
cmake/Modules/opm-verteq-prereqs.cmake
Normal file
20
cmake/Modules/opm-verteq-prereqs.cmake
Normal file
@ -0,0 +1,20 @@
|
||||
# -*- mode: cmake; tab-width: 2; indent-tabs-mode: t; truncate-lines: t; compile-command: "cmake -Wdev" -*-
|
||||
# vim: set filetype=cmake autoindent tabstop=2 shiftwidth=2 noexpandtab softtabstop=2 nowrap:
|
||||
|
||||
# defines that must be present in config.h for our headers
|
||||
set (opm-verteq_CONFIG_VAR
|
||||
)
|
||||
|
||||
# dependencies
|
||||
set (opm-verteq_DEPS
|
||||
# compile with C99 support if available
|
||||
"C99"
|
||||
# compile with C++0x/11 support if available
|
||||
"CXX11Features"
|
||||
# various runtime library enhancements
|
||||
"Boost 1.44.0
|
||||
COMPONENTS date_time filesystem system unit_test_framework REQUIRED"
|
||||
# OPM dependency
|
||||
"opm-common;
|
||||
opm-core REQUIRED"
|
||||
)
|
@ -1,9 +1,6 @@
|
||||
.TH SUMMARY "1" "October 2023" "arraylist 2023.10" "User Commands"
|
||||
.TH SUMMARY "1" "October 2022" "arraylist 2022.10" "User Commands"
|
||||
.SH NAME
|
||||
arraylist \- Printer for list of arrays in Eclipse summary files
|
||||
.SH SYNOPSIS
|
||||
.B arraylist
|
||||
[\fI\,OPTIONS\/\fR] \fI\,ECL_DECK_FILENAME\/\fR
|
||||
summary \- Printer for list of arrays in Eclipse summary files
|
||||
.SH DESCRIPTION
|
||||
List all arrays found in an EclFile specified on the command line.
|
||||
.PP
|
||||
|
@ -1,10 +1,6 @@
|
||||
.TH CO2BRINEPVT "1" "October 2023" "co2brinepvt" "User Commands"
|
||||
.TH CO2BRINEPVT "1" "April 2022" "co2brinepvt" "User Commands"
|
||||
.SH NAME
|
||||
co2brinepvt \- compute and print pvt properties for co2 with brine
|
||||
.SH SYNOPSIS
|
||||
.B co2brinepvt
|
||||
[\fI\,OPTIONS\/\fR] \fI\,PROPERTY\/\fR \fI\,PHASE\/\fR
|
||||
\fI\,PRESSURE\/\fR \fI\,TEMPERATURE\/\fR [\fI\,SALINITY\/\fR] [\fI\,RS\/\fR]
|
||||
.SH DESCRIPTION
|
||||
co2brinepvt computes PVT properties of a brine/co2 system
|
||||
for a given phase (oil or brine), pressure, temperature, salinity and rs.
|
||||
|
@ -1,9 +1,6 @@
|
||||
.TH COMPAREECL "1" "October 2023" "compareECL 2023.10" "User Commands"
|
||||
.TH COMPAREECL "1" "October 2022" "compareECL 2022.10" "User Commands"
|
||||
.SH NAME
|
||||
compareECL \- Comparator for Eclipse files
|
||||
.SH SYNOPSIS
|
||||
.B convertECL
|
||||
[\fI\,OPTIONS\/\fR] \fI\,ECL_DECK_FILENAME_1\/\fR \fI\,ECL_DECK_FILENAME_2\/\fR
|
||||
.SH DESCRIPTION
|
||||
compareECL compares ECLIPSE files (restart (.RST), unified restart (.UNRST), initial (.INIT), summary (.SMRY), unified summary (.UNSMRY) or .RFT) and gridsizes (from .EGRID or .GRID file) from two simulations.
|
||||
The program takes four arguments:
|
||||
|
@ -1,10 +1,6 @@
|
||||
.TH CONVERTECL "1" "October 2023" "convertECL 2023.10" "User Commands"
|
||||
.TH CONVERTECL "1" "October 2022" "convertECL 2022.10" "User Commands"
|
||||
.SH NAME
|
||||
convertECL \- Converter for Eclipse files (binary <-> formatted
|
||||
format)
|
||||
.SH SYNOPSIS
|
||||
.B convertECL
|
||||
[\fI\,OPTIONS\/\fR] \fI\,ECL_DECK_FILENAME\/\fR
|
||||
convertECL \- Converter for Eclipse files (binary <-> formatted format)
|
||||
.SH DESCRIPTION
|
||||
convertECL needs one argument which is the input file to be converted. If this is a binary file the output file will be formatted. If the input file is formatted the output will be binary.
|
||||
.PP
|
||||
|
@ -1,11 +1,8 @@
|
||||
.TH OPMHASH "1" "October 2023" "opmhash 2023.10" "User Commands"
|
||||
.TH OPMHASH "1" "October 2022" "opmhash 2022.10" "User Commands"
|
||||
.SH NAME
|
||||
opmhash \- Hasher for summary keywords in Eclipse files
|
||||
.SH SYNOPSIS
|
||||
.B opmhash
|
||||
[\fI\,OPTIONS\/\fR] \fI\,ECL_DECK_FILENAME\/\fR
|
||||
[\fI\,ECL_DECK_FILENAME_2\/\fR] [\fI\,ECL_DECK_FILENAME_3\/\fR] ...
|
||||
.SH DESCRIPTION
|
||||
opmhash: invalid option \fB\-\-\fR 'h'
|
||||
The purpose of the opmhash program is to load a deck and create a summary, by
|
||||
diffing two such summaries it is simple to determine if two decks are similar.
|
||||
For each keyword a hash of the normalized content is calculated. The output of
|
||||
|
@ -1,9 +1,6 @@
|
||||
.TH OPMPACK "1" "October 2023" "opmpack 2023.10" "User Commands"
|
||||
.TH OPMPACK "1" "October 2022" "opmpack 2022.10" "User Commands"
|
||||
.SH NAME
|
||||
opmpack \- Validator and printer of deck in Eclipse files without comments
|
||||
.SH SYNOPSIS
|
||||
.B opmpack
|
||||
[\fI\,OPTIONS\/\fR] \fI\,ECL_DECK_FILENAME\/\fR
|
||||
.SH DESCRIPTION
|
||||
The opmpack program will load a deck, resolve all include
|
||||
files and then print it out again on stdout. All comments
|
||||
|
@ -1,10 +1,6 @@
|
||||
.TH RST_DECK: "1" "October 2023" "rst_deck 2023.10" "User Commands"
|
||||
.TH RST_DECK: "1" "October 2022" "rst_deck 2022.10" "User Commands"
|
||||
.SH NAME
|
||||
rst_deck \- Convert simulation deck to a deck ready for restart
|
||||
.SH SYNOPSIS
|
||||
.B rst_deck
|
||||
[\fI\,OPTIONS\/\fR] \fI\,ECL_DECK_FILENAME\/\fR
|
||||
\fI\,RESTART_SOURCE\/\fR [\fI\,BASENAME_RESTART_DECK\/\fR
|
||||
.SH DESCRIPTION
|
||||
The rst_deck program will load a simulation deck and parameters for a restart
|
||||
and reformat the deck to become a restart deck. Before the updated deck is
|
||||
|
@ -1,10 +1,6 @@
|
||||
.TH SUMMARY "1" "October 2023" "summary 2023.10" "User Commands"
|
||||
.TH SUMMARY "1" "October 2022" "summary 2022.10" "User Commands"
|
||||
.SH NAME
|
||||
summary \- Printer for summary keys in Eclipse summary files
|
||||
.SH SYNOPSIS
|
||||
.B summary
|
||||
[\fI\,OPTIONS\/\fR] \fI\,ECL_DECK_FILENAME\/\fR
|
||||
\fI\,SUMMARY_KEY1\/\fR [\fI\,SUMMARY_KEY2\/\fR] ...
|
||||
.SH DESCRIPTION
|
||||
summary needs a minimum of two arguments. First is smspec filename and then list of vectors
|
||||
.PP
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
Module: opm-common
|
||||
Description: Open Porous Media Initiative shared infrastructure
|
||||
Version: 2024.04-pre
|
||||
Label: 2024.04-pre
|
||||
Version: 2023.04
|
||||
Label: 2023.04
|
||||
Maintainer: opm@opm-project.org
|
||||
MaintainerName: OPM community
|
||||
Url: http://opm-project.org
|
||||
|
@ -93,7 +93,7 @@ int main(int argc, char **argv)
|
||||
if (argc > 6)
|
||||
rs = atof(argv[6]);
|
||||
|
||||
const double MmNaCl = 58.44e-3; // molar mass of NaCl [kg/mol]
|
||||
const double MmNaCl = 58e-3; // molar mass of NaCl [kg/mol]
|
||||
// convert to mass fraction
|
||||
std::vector<double> salinity = {0.0};
|
||||
if (molality > 0.0)
|
||||
|
247
external/cjson/README
vendored
Normal file
247
external/cjson/README
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
Welcome to cJSON.
|
||||
|
||||
cJSON aims to be the dumbest possible parser that you can get your job done with.
|
||||
It's a single file of C, and a single header file.
|
||||
|
||||
JSON is described best here: http://www.json.org/
|
||||
It's like XML, but fat-free. You use it to move data around, store things, or just
|
||||
generally represent your program's state.
|
||||
|
||||
|
||||
First up, how do I build?
|
||||
Add cJSON.c to your project, and put cJSON.h somewhere in the header search path.
|
||||
For example, to build the test app:
|
||||
|
||||
gcc cJSON.c test.c -o test -lm
|
||||
./test
|
||||
|
||||
|
||||
As a library, cJSON exists to take away as much legwork as it can, but not get in your way.
|
||||
As a point of pragmatism (i.e. ignoring the truth), I'm going to say that you can use it
|
||||
in one of two modes: Auto and Manual. Let's have a quick run-through.
|
||||
|
||||
|
||||
I lifted some JSON from this page: http://www.json.org/fatfree.html
|
||||
That page inspired me to write cJSON, which is a parser that tries to share the same
|
||||
philosophy as JSON itself. Simple, dumb, out of the way.
|
||||
|
||||
Some JSON:
|
||||
{
|
||||
"name": "Jack (\"Bee\") Nimble",
|
||||
"format": {
|
||||
"type": "rect",
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"interlace": false,
|
||||
"frame rate": 24
|
||||
}
|
||||
}
|
||||
|
||||
Assume that you got this from a file, a webserver, or magic JSON elves, whatever,
|
||||
you have a char * to it. Everything is a cJSON struct.
|
||||
Get it parsed:
|
||||
cJSON *root = cJSON_Parse(my_json_string);
|
||||
|
||||
This is an object. We're in C. We don't have objects. But we do have structs.
|
||||
What's the framerate?
|
||||
|
||||
cJSON *format = cJSON_GetObjectItem(root,"format");
|
||||
int framerate = cJSON_GetObjectItem(format,"frame rate")->valueint;
|
||||
|
||||
|
||||
Want to change the framerate?
|
||||
cJSON_GetObjectItem(format,"frame rate")->valueint=25;
|
||||
|
||||
Back to disk?
|
||||
char *rendered=cJSON_Print(root);
|
||||
|
||||
Finished? Delete the root (this takes care of everything else).
|
||||
cJSON_Delete(root);
|
||||
|
||||
That's AUTO mode. If you're going to use Auto mode, you really ought to check pointers
|
||||
before you dereference them. If you want to see how you'd build this struct in code?
|
||||
cJSON *root,*fmt;
|
||||
root=cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
|
||||
cJSON_AddItemToObject(root, "format", fmt=cJSON_CreateObject());
|
||||
cJSON_AddStringToObject(fmt,"type", "rect");
|
||||
cJSON_AddNumberToObject(fmt,"width", 1920);
|
||||
cJSON_AddNumberToObject(fmt,"height", 1080);
|
||||
cJSON_AddFalseToObject (fmt,"interlace");
|
||||
cJSON_AddNumberToObject(fmt,"frame rate", 24);
|
||||
|
||||
Hopefully we can agree that's not a lot of code? There's no overhead, no unnecessary setup.
|
||||
Look at test.c for a bunch of nice examples, mostly all ripped off the json.org site, and
|
||||
a few from elsewhere.
|
||||
|
||||
What about manual mode? First up you need some detail.
|
||||
Let's cover how the cJSON objects represent the JSON data.
|
||||
cJSON doesn't distinguish arrays from objects in handling; just type.
|
||||
Each cJSON has, potentially, a child, siblings, value, a name.
|
||||
|
||||
The root object has: Object Type and a Child
|
||||
The Child has name "name", with value "Jack ("Bee") Nimble", and a sibling:
|
||||
Sibling has type Object, name "format", and a child.
|
||||
That child has type String, name "type", value "rect", and a sibling:
|
||||
Sibling has type Number, name "width", value 1920, and a sibling:
|
||||
Sibling has type Number, name "height", value 1080, and a sibling:
|
||||
Sibling hs type False, name "interlace", and a sibling:
|
||||
Sibling has type Number, name "frame rate", value 24
|
||||
|
||||
Here's the structure:
|
||||
typedef struct cJSON {
|
||||
struct cJSON *next,*prev;
|
||||
struct cJSON *child;
|
||||
|
||||
int type;
|
||||
|
||||
char *valuestring;
|
||||
int valueint;
|
||||
double valuedouble;
|
||||
|
||||
char *string;
|
||||
} cJSON;
|
||||
|
||||
By default all values are 0 unless set by virtue of being meaningful.
|
||||
|
||||
next/prev is a doubly linked list of siblings. next takes you to your sibling,
|
||||
prev takes you back from your sibling to you.
|
||||
Only objects and arrays have a "child", and it's the head of the doubly linked list.
|
||||
A "child" entry will have prev==0, but next potentially points on. The last sibling has next=0.
|
||||
The type expresses Null/True/False/Number/String/Array/Object, all of which are #defined in
|
||||
cJSON.h
|
||||
|
||||
A Number has valueint and valuedouble. If you're expecting an int, read valueint, if not read
|
||||
valuedouble.
|
||||
|
||||
Any entry which is in the linked list which is the child of an object will have a "string"
|
||||
which is the "name" of the entry. When I said "name" in the above example, that's "string".
|
||||
"string" is the JSON name for the 'variable name' if you will.
|
||||
|
||||
Now you can trivially walk the lists, recursively, and parse as you please.
|
||||
You can invoke cJSON_Parse to get cJSON to parse for you, and then you can take
|
||||
the root object, and traverse the structure (which is, formally, an N-tree),
|
||||
and tokenise as you please. If you wanted to build a callback style parser, this is how
|
||||
you'd do it (just an example, since these things are very specific):
|
||||
|
||||
void parse_and_callback(cJSON *item,const char *prefix)
|
||||
{
|
||||
while (item)
|
||||
{
|
||||
char *newprefix=malloc(strlen(prefix)+strlen(item->name)+2);
|
||||
sprintf(newprefix,"%s/%s",prefix,item->name);
|
||||
int dorecurse=callback(newprefix, item->type, item);
|
||||
if (item->child && dorecurse) parse_and_callback(item->child,newprefix);
|
||||
item=item->next;
|
||||
free(newprefix);
|
||||
}
|
||||
}
|
||||
|
||||
The prefix process will build you a separated list, to simplify your callback handling.
|
||||
The 'dorecurse' flag would let the callback decide to handle sub-arrays on it's own, or
|
||||
let you invoke it per-item. For the item above, your callback might look like this:
|
||||
|
||||
int callback(const char *name,int type,cJSON *item)
|
||||
{
|
||||
if (!strcmp(name,"name")) { /* populate name */ }
|
||||
else if (!strcmp(name,"format/type") { /* handle "rect" */ }
|
||||
else if (!strcmp(name,"format/width") { /* 800 */ }
|
||||
else if (!strcmp(name,"format/height") { /* 600 */ }
|
||||
else if (!strcmp(name,"format/interlace") { /* false */ }
|
||||
else if (!strcmp(name,"format/frame rate") { /* 24 */ }
|
||||
return 1;
|
||||
}
|
||||
|
||||
Alternatively, you might like to parse iteratively.
|
||||
You'd use:
|
||||
|
||||
void parse_object(cJSON *item)
|
||||
{
|
||||
int i; for (i=0;i<cJSON_GetArraySize(item);i++)
|
||||
{
|
||||
cJSON *subitem=cJSON_GetArrayItem(item,i);
|
||||
// handle subitem.
|
||||
}
|
||||
}
|
||||
|
||||
Or, for PROPER manual mode:
|
||||
|
||||
void parse_object(cJSON *item)
|
||||
{
|
||||
cJSON *subitem=item->child;
|
||||
while (subitem)
|
||||
{
|
||||
// handle subitem
|
||||
if (subitem->child) parse_object(subitem->child);
|
||||
|
||||
subitem=subitem->next;
|
||||
}
|
||||
}
|
||||
|
||||
Of course, this should look familiar, since this is just a stripped-down version
|
||||
of the callback-parser.
|
||||
|
||||
This should cover most uses you'll find for parsing. The rest should be possible
|
||||
to infer.. and if in doubt, read the source! There's not a lot of it! ;)
|
||||
|
||||
|
||||
In terms of constructing JSON data, the example code above is the right way to do it.
|
||||
You can, of course, hand your sub-objects to other functions to populate.
|
||||
Also, if you find a use for it, you can manually build the objects.
|
||||
For instance, suppose you wanted to build an array of objects?
|
||||
|
||||
cJSON *objects[24];
|
||||
|
||||
cJSON *Create_array_of_anything(cJSON **items,int num)
|
||||
{
|
||||
int i;cJSON *prev, *root=cJSON_CreateArray();
|
||||
for (i=0;i<24;i++)
|
||||
{
|
||||
if (!i) root->child=objects[i];
|
||||
else prev->next=objects[i], objects[i]->prev=prev;
|
||||
prev=objects[i];
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
and simply: Create_array_of_anything(objects,24);
|
||||
|
||||
cJSON doesn't make any assumptions about what order you create things in.
|
||||
You can attach the objects, as above, and later add children to each
|
||||
of those objects.
|
||||
|
||||
As soon as you call cJSON_Print, it renders the structure to text.
|
||||
|
||||
|
||||
|
||||
The test.c code shows how to handle a bunch of typical cases. If you uncomment
|
||||
the code, it'll load, parse and print a bunch of test files, also from json.org,
|
||||
which are more complex than I'd care to try and stash into a const char array[].
|
||||
|
||||
|
||||
Enjoy cJSON!
|
||||
|
||||
|
||||
- Dave Gamble, Aug 2009
|
2
external/cjson/README.opm
vendored
Normal file
2
external/cjson/README.opm
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
This directory contains the the 1.7.10 version of the cJSON package from https://github.com/DaveGamble/cJSON
|
||||
|
2936
external/cjson/cJSON.c
vendored
Normal file
2936
external/cjson/cJSON.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
285
external/cjson/cJSON.h
vendored
Normal file
285
external/cjson/cJSON.h
vendored
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
|
||||
|
||||
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
||||
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
||||
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||
|
||||
For *nix builds that support visibility attribute, you can define similar behavior by
|
||||
|
||||
setting default visibility to hidden by adding
|
||||
-fvisibility=hidden (for gcc)
|
||||
or
|
||||
-xldscope=hidden (for sun cc)
|
||||
to CFLAGS
|
||||
|
||||
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
||||
|
||||
*/
|
||||
|
||||
#define CJSON_CDECL __cdecl
|
||||
#define CJSON_STDCALL __stdcall
|
||||
|
||||
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
||||
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_EXPORT_SYMBOLS
|
||||
#endif
|
||||
|
||||
#if defined(CJSON_HIDE_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) type CJSON_STDCALL
|
||||
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
|
||||
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
|
||||
#endif
|
||||
#else /* !__WINDOWS__ */
|
||||
#define CJSON_CDECL
|
||||
#define CJSON_STDCALL
|
||||
|
||||
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
||||
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||
#else
|
||||
#define CJSON_PUBLIC(type) type
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* project version */
|
||||
#define CJSON_VERSION_MAJOR 1
|
||||
#define CJSON_VERSION_MINOR 7
|
||||
#define CJSON_VERSION_PATCH 10
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_Invalid (0)
|
||||
#define cJSON_False (1 << 0)
|
||||
#define cJSON_True (1 << 1)
|
||||
#define cJSON_NULL (1 << 2)
|
||||
#define cJSON_Number (1 << 3)
|
||||
#define cJSON_String (1 << 4)
|
||||
#define cJSON_Array (1 << 5)
|
||||
#define cJSON_Object (1 << 6)
|
||||
#define cJSON_Raw (1 << 7) /* raw json */
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
#define cJSON_StringIsConst 512
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON
|
||||
{
|
||||
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *next;
|
||||
struct cJSON *prev;
|
||||
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
struct cJSON *child;
|
||||
|
||||
/* The type of the item, as above. */
|
||||
int type;
|
||||
|
||||
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||
char *valuestring;
|
||||
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||
int valueint;
|
||||
/* The item's number, if type==cJSON_Number */
|
||||
double valuedouble;
|
||||
|
||||
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
char *string;
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks
|
||||
{
|
||||
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
|
||||
void *(CJSON_CDECL *malloc_fn)(size_t sz);
|
||||
void (CJSON_CDECL *free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
typedef int cJSON_bool;
|
||||
|
||||
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||
* This is to prevent stack overflows. */
|
||||
#ifndef CJSON_NESTING_LIMIT
|
||||
#define CJSON_NESTING_LIMIT 1000
|
||||
#endif
|
||||
|
||||
/* returns the version of cJSON as a string */
|
||||
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||
|
||||
/* Render a cJSON entity to text for transfer/storage. */
|
||||
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
||||
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||
|
||||
/* Check if the item is a string and return its valuestring */
|
||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item);
|
||||
|
||||
/* These functions check the type of an item */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||
/* raw json */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||
|
||||
/* Create a string where valuestring references a string so
|
||||
* it will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||
/* Create an object/arrray that only references it's elements so
|
||||
* they will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
||||
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||
* writing to `item->string` */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||
|
||||
/* Remove/Detatch items from Arrays/Objects. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||
need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||
The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
||||
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||
|
||||
|
||||
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||
|
||||
/* Helper functions for creating and adding items to an object at the same time.
|
||||
* They return the added item or NULL on failure. */
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
|
||||
/* helper for the cJSON_SetNumberValue macro */
|
||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||
|
||||
/* Macro for iterating over an array or object */
|
||||
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||
|
||||
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
|
||||
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
27
external/fmtlib/LICENSE.rst
vendored
Normal file
27
external/fmtlib/LICENSE.rst
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
Copyright (c) 2012 - present, Victor Zverovich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
--- Optional exception to the license ---
|
||||
|
||||
As an exception, if, as a result of your compiling your source code, portions
|
||||
of this Software are embedded into a machine-executable object form of such
|
||||
source code, you may redistribute such embedded portions in such object form
|
||||
without including the above copyright and permission notices.
|
12
external/fmtlib/README.opm
vendored
Normal file
12
external/fmtlib/README.opm
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
The include/ directory is a copy of the include directory from version 7.0.3 of
|
||||
the fmtlib distribution. The fmtlib can be found at https://github.com/fmtlib/fmt
|
||||
|
||||
The fmtlib code embedded here should be compiled in header only mode, to ensure
|
||||
that the symbol FMT_HEADER_ONLY must be defined before the the fmt/format.h
|
||||
header is included:
|
||||
|
||||
#define FMT_HEADER_ONLY
|
||||
#include <fmt/format.h>
|
||||
|
||||
....
|
||||
auto msg = fmt::format("Hello {}", "world");
|
1123
external/fmtlib/include/fmt/chrono.h
vendored
Normal file
1123
external/fmtlib/include/fmt/chrono.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
566
external/fmtlib/include/fmt/color.h
vendored
Normal file
566
external/fmtlib/include/fmt/color.h
vendored
Normal file
@ -0,0 +1,566 @@
|
||||
// Formatting library for C++ - color support
|
||||
//
|
||||
// Copyright (c) 2018 - present, Victor Zverovich and fmt contributors
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_COLOR_H_
|
||||
#define FMT_COLOR_H_
|
||||
|
||||
#include "format.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
enum class color : uint32_t {
|
||||
alice_blue = 0xF0F8FF, // rgb(240,248,255)
|
||||
antique_white = 0xFAEBD7, // rgb(250,235,215)
|
||||
aqua = 0x00FFFF, // rgb(0,255,255)
|
||||
aquamarine = 0x7FFFD4, // rgb(127,255,212)
|
||||
azure = 0xF0FFFF, // rgb(240,255,255)
|
||||
beige = 0xF5F5DC, // rgb(245,245,220)
|
||||
bisque = 0xFFE4C4, // rgb(255,228,196)
|
||||
black = 0x000000, // rgb(0,0,0)
|
||||
blanched_almond = 0xFFEBCD, // rgb(255,235,205)
|
||||
blue = 0x0000FF, // rgb(0,0,255)
|
||||
blue_violet = 0x8A2BE2, // rgb(138,43,226)
|
||||
brown = 0xA52A2A, // rgb(165,42,42)
|
||||
burly_wood = 0xDEB887, // rgb(222,184,135)
|
||||
cadet_blue = 0x5F9EA0, // rgb(95,158,160)
|
||||
chartreuse = 0x7FFF00, // rgb(127,255,0)
|
||||
chocolate = 0xD2691E, // rgb(210,105,30)
|
||||
coral = 0xFF7F50, // rgb(255,127,80)
|
||||
cornflower_blue = 0x6495ED, // rgb(100,149,237)
|
||||
cornsilk = 0xFFF8DC, // rgb(255,248,220)
|
||||
crimson = 0xDC143C, // rgb(220,20,60)
|
||||
cyan = 0x00FFFF, // rgb(0,255,255)
|
||||
dark_blue = 0x00008B, // rgb(0,0,139)
|
||||
dark_cyan = 0x008B8B, // rgb(0,139,139)
|
||||
dark_golden_rod = 0xB8860B, // rgb(184,134,11)
|
||||
dark_gray = 0xA9A9A9, // rgb(169,169,169)
|
||||
dark_green = 0x006400, // rgb(0,100,0)
|
||||
dark_khaki = 0xBDB76B, // rgb(189,183,107)
|
||||
dark_magenta = 0x8B008B, // rgb(139,0,139)
|
||||
dark_olive_green = 0x556B2F, // rgb(85,107,47)
|
||||
dark_orange = 0xFF8C00, // rgb(255,140,0)
|
||||
dark_orchid = 0x9932CC, // rgb(153,50,204)
|
||||
dark_red = 0x8B0000, // rgb(139,0,0)
|
||||
dark_salmon = 0xE9967A, // rgb(233,150,122)
|
||||
dark_sea_green = 0x8FBC8F, // rgb(143,188,143)
|
||||
dark_slate_blue = 0x483D8B, // rgb(72,61,139)
|
||||
dark_slate_gray = 0x2F4F4F, // rgb(47,79,79)
|
||||
dark_turquoise = 0x00CED1, // rgb(0,206,209)
|
||||
dark_violet = 0x9400D3, // rgb(148,0,211)
|
||||
deep_pink = 0xFF1493, // rgb(255,20,147)
|
||||
deep_sky_blue = 0x00BFFF, // rgb(0,191,255)
|
||||
dim_gray = 0x696969, // rgb(105,105,105)
|
||||
dodger_blue = 0x1E90FF, // rgb(30,144,255)
|
||||
fire_brick = 0xB22222, // rgb(178,34,34)
|
||||
floral_white = 0xFFFAF0, // rgb(255,250,240)
|
||||
forest_green = 0x228B22, // rgb(34,139,34)
|
||||
fuchsia = 0xFF00FF, // rgb(255,0,255)
|
||||
gainsboro = 0xDCDCDC, // rgb(220,220,220)
|
||||
ghost_white = 0xF8F8FF, // rgb(248,248,255)
|
||||
gold = 0xFFD700, // rgb(255,215,0)
|
||||
golden_rod = 0xDAA520, // rgb(218,165,32)
|
||||
gray = 0x808080, // rgb(128,128,128)
|
||||
green = 0x008000, // rgb(0,128,0)
|
||||
green_yellow = 0xADFF2F, // rgb(173,255,47)
|
||||
honey_dew = 0xF0FFF0, // rgb(240,255,240)
|
||||
hot_pink = 0xFF69B4, // rgb(255,105,180)
|
||||
indian_red = 0xCD5C5C, // rgb(205,92,92)
|
||||
indigo = 0x4B0082, // rgb(75,0,130)
|
||||
ivory = 0xFFFFF0, // rgb(255,255,240)
|
||||
khaki = 0xF0E68C, // rgb(240,230,140)
|
||||
lavender = 0xE6E6FA, // rgb(230,230,250)
|
||||
lavender_blush = 0xFFF0F5, // rgb(255,240,245)
|
||||
lawn_green = 0x7CFC00, // rgb(124,252,0)
|
||||
lemon_chiffon = 0xFFFACD, // rgb(255,250,205)
|
||||
light_blue = 0xADD8E6, // rgb(173,216,230)
|
||||
light_coral = 0xF08080, // rgb(240,128,128)
|
||||
light_cyan = 0xE0FFFF, // rgb(224,255,255)
|
||||
light_golden_rod_yellow = 0xFAFAD2, // rgb(250,250,210)
|
||||
light_gray = 0xD3D3D3, // rgb(211,211,211)
|
||||
light_green = 0x90EE90, // rgb(144,238,144)
|
||||
light_pink = 0xFFB6C1, // rgb(255,182,193)
|
||||
light_salmon = 0xFFA07A, // rgb(255,160,122)
|
||||
light_sea_green = 0x20B2AA, // rgb(32,178,170)
|
||||
light_sky_blue = 0x87CEFA, // rgb(135,206,250)
|
||||
light_slate_gray = 0x778899, // rgb(119,136,153)
|
||||
light_steel_blue = 0xB0C4DE, // rgb(176,196,222)
|
||||
light_yellow = 0xFFFFE0, // rgb(255,255,224)
|
||||
lime = 0x00FF00, // rgb(0,255,0)
|
||||
lime_green = 0x32CD32, // rgb(50,205,50)
|
||||
linen = 0xFAF0E6, // rgb(250,240,230)
|
||||
magenta = 0xFF00FF, // rgb(255,0,255)
|
||||
maroon = 0x800000, // rgb(128,0,0)
|
||||
medium_aquamarine = 0x66CDAA, // rgb(102,205,170)
|
||||
medium_blue = 0x0000CD, // rgb(0,0,205)
|
||||
medium_orchid = 0xBA55D3, // rgb(186,85,211)
|
||||
medium_purple = 0x9370DB, // rgb(147,112,219)
|
||||
medium_sea_green = 0x3CB371, // rgb(60,179,113)
|
||||
medium_slate_blue = 0x7B68EE, // rgb(123,104,238)
|
||||
medium_spring_green = 0x00FA9A, // rgb(0,250,154)
|
||||
medium_turquoise = 0x48D1CC, // rgb(72,209,204)
|
||||
medium_violet_red = 0xC71585, // rgb(199,21,133)
|
||||
midnight_blue = 0x191970, // rgb(25,25,112)
|
||||
mint_cream = 0xF5FFFA, // rgb(245,255,250)
|
||||
misty_rose = 0xFFE4E1, // rgb(255,228,225)
|
||||
moccasin = 0xFFE4B5, // rgb(255,228,181)
|
||||
navajo_white = 0xFFDEAD, // rgb(255,222,173)
|
||||
navy = 0x000080, // rgb(0,0,128)
|
||||
old_lace = 0xFDF5E6, // rgb(253,245,230)
|
||||
olive = 0x808000, // rgb(128,128,0)
|
||||
olive_drab = 0x6B8E23, // rgb(107,142,35)
|
||||
orange = 0xFFA500, // rgb(255,165,0)
|
||||
orange_red = 0xFF4500, // rgb(255,69,0)
|
||||
orchid = 0xDA70D6, // rgb(218,112,214)
|
||||
pale_golden_rod = 0xEEE8AA, // rgb(238,232,170)
|
||||
pale_green = 0x98FB98, // rgb(152,251,152)
|
||||
pale_turquoise = 0xAFEEEE, // rgb(175,238,238)
|
||||
pale_violet_red = 0xDB7093, // rgb(219,112,147)
|
||||
papaya_whip = 0xFFEFD5, // rgb(255,239,213)
|
||||
peach_puff = 0xFFDAB9, // rgb(255,218,185)
|
||||
peru = 0xCD853F, // rgb(205,133,63)
|
||||
pink = 0xFFC0CB, // rgb(255,192,203)
|
||||
plum = 0xDDA0DD, // rgb(221,160,221)
|
||||
powder_blue = 0xB0E0E6, // rgb(176,224,230)
|
||||
purple = 0x800080, // rgb(128,0,128)
|
||||
rebecca_purple = 0x663399, // rgb(102,51,153)
|
||||
red = 0xFF0000, // rgb(255,0,0)
|
||||
rosy_brown = 0xBC8F8F, // rgb(188,143,143)
|
||||
royal_blue = 0x4169E1, // rgb(65,105,225)
|
||||
saddle_brown = 0x8B4513, // rgb(139,69,19)
|
||||
salmon = 0xFA8072, // rgb(250,128,114)
|
||||
sandy_brown = 0xF4A460, // rgb(244,164,96)
|
||||
sea_green = 0x2E8B57, // rgb(46,139,87)
|
||||
sea_shell = 0xFFF5EE, // rgb(255,245,238)
|
||||
sienna = 0xA0522D, // rgb(160,82,45)
|
||||
silver = 0xC0C0C0, // rgb(192,192,192)
|
||||
sky_blue = 0x87CEEB, // rgb(135,206,235)
|
||||
slate_blue = 0x6A5ACD, // rgb(106,90,205)
|
||||
slate_gray = 0x708090, // rgb(112,128,144)
|
||||
snow = 0xFFFAFA, // rgb(255,250,250)
|
||||
spring_green = 0x00FF7F, // rgb(0,255,127)
|
||||
steel_blue = 0x4682B4, // rgb(70,130,180)
|
||||
tan = 0xD2B48C, // rgb(210,180,140)
|
||||
teal = 0x008080, // rgb(0,128,128)
|
||||
thistle = 0xD8BFD8, // rgb(216,191,216)
|
||||
tomato = 0xFF6347, // rgb(255,99,71)
|
||||
turquoise = 0x40E0D0, // rgb(64,224,208)
|
||||
violet = 0xEE82EE, // rgb(238,130,238)
|
||||
wheat = 0xF5DEB3, // rgb(245,222,179)
|
||||
white = 0xFFFFFF, // rgb(255,255,255)
|
||||
white_smoke = 0xF5F5F5, // rgb(245,245,245)
|
||||
yellow = 0xFFFF00, // rgb(255,255,0)
|
||||
yellow_green = 0x9ACD32 // rgb(154,205,50)
|
||||
}; // enum class color
|
||||
|
||||
enum class terminal_color : uint8_t {
|
||||
black = 30,
|
||||
red,
|
||||
green,
|
||||
yellow,
|
||||
blue,
|
||||
magenta,
|
||||
cyan,
|
||||
white,
|
||||
bright_black = 90,
|
||||
bright_red,
|
||||
bright_green,
|
||||
bright_yellow,
|
||||
bright_blue,
|
||||
bright_magenta,
|
||||
bright_cyan,
|
||||
bright_white
|
||||
};
|
||||
|
||||
enum class emphasis : uint8_t {
|
||||
bold = 1,
|
||||
italic = 1 << 1,
|
||||
underline = 1 << 2,
|
||||
strikethrough = 1 << 3
|
||||
};
|
||||
|
||||
// rgb is a struct for red, green and blue colors.
|
||||
// Using the name "rgb" makes some editors show the color in a tooltip.
|
||||
struct rgb {
|
||||
FMT_CONSTEXPR rgb() : r(0), g(0), b(0) {}
|
||||
FMT_CONSTEXPR rgb(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {}
|
||||
FMT_CONSTEXPR rgb(uint32_t hex)
|
||||
: r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b(hex & 0xFF) {}
|
||||
FMT_CONSTEXPR rgb(color hex)
|
||||
: r((uint32_t(hex) >> 16) & 0xFF),
|
||||
g((uint32_t(hex) >> 8) & 0xFF),
|
||||
b(uint32_t(hex) & 0xFF) {}
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
// color is a struct of either a rgb color or a terminal color.
|
||||
struct color_type {
|
||||
FMT_CONSTEXPR color_type() FMT_NOEXCEPT : is_rgb(), value{} {}
|
||||
FMT_CONSTEXPR color_type(color rgb_color) FMT_NOEXCEPT : is_rgb(true),
|
||||
value{} {
|
||||
value.rgb_color = static_cast<uint32_t>(rgb_color);
|
||||
}
|
||||
FMT_CONSTEXPR color_type(rgb rgb_color) FMT_NOEXCEPT : is_rgb(true), value{} {
|
||||
value.rgb_color = (static_cast<uint32_t>(rgb_color.r) << 16) |
|
||||
(static_cast<uint32_t>(rgb_color.g) << 8) | rgb_color.b;
|
||||
}
|
||||
FMT_CONSTEXPR color_type(terminal_color term_color) FMT_NOEXCEPT : is_rgb(),
|
||||
value{} {
|
||||
value.term_color = static_cast<uint8_t>(term_color);
|
||||
}
|
||||
bool is_rgb;
|
||||
union color_union {
|
||||
uint8_t term_color;
|
||||
uint32_t rgb_color;
|
||||
} value;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
// Experimental text formatting support.
|
||||
class text_style {
|
||||
public:
|
||||
FMT_CONSTEXPR text_style(emphasis em = emphasis()) FMT_NOEXCEPT
|
||||
: set_foreground_color(),
|
||||
set_background_color(),
|
||||
ems(em) {}
|
||||
|
||||
FMT_CONSTEXPR text_style& operator|=(const text_style& rhs) {
|
||||
if (!set_foreground_color) {
|
||||
set_foreground_color = rhs.set_foreground_color;
|
||||
foreground_color = rhs.foreground_color;
|
||||
} else if (rhs.set_foreground_color) {
|
||||
if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb)
|
||||
FMT_THROW(format_error("can't OR a terminal color"));
|
||||
foreground_color.value.rgb_color |= rhs.foreground_color.value.rgb_color;
|
||||
}
|
||||
|
||||
if (!set_background_color) {
|
||||
set_background_color = rhs.set_background_color;
|
||||
background_color = rhs.background_color;
|
||||
} else if (rhs.set_background_color) {
|
||||
if (!background_color.is_rgb || !rhs.background_color.is_rgb)
|
||||
FMT_THROW(format_error("can't OR a terminal color"));
|
||||
background_color.value.rgb_color |= rhs.background_color.value.rgb_color;
|
||||
}
|
||||
|
||||
ems = static_cast<emphasis>(static_cast<uint8_t>(ems) |
|
||||
static_cast<uint8_t>(rhs.ems));
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend FMT_CONSTEXPR text_style operator|(text_style lhs,
|
||||
const text_style& rhs) {
|
||||
return lhs |= rhs;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR text_style& operator&=(const text_style& rhs) {
|
||||
if (!set_foreground_color) {
|
||||
set_foreground_color = rhs.set_foreground_color;
|
||||
foreground_color = rhs.foreground_color;
|
||||
} else if (rhs.set_foreground_color) {
|
||||
if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb)
|
||||
FMT_THROW(format_error("can't AND a terminal color"));
|
||||
foreground_color.value.rgb_color &= rhs.foreground_color.value.rgb_color;
|
||||
}
|
||||
|
||||
if (!set_background_color) {
|
||||
set_background_color = rhs.set_background_color;
|
||||
background_color = rhs.background_color;
|
||||
} else if (rhs.set_background_color) {
|
||||
if (!background_color.is_rgb || !rhs.background_color.is_rgb)
|
||||
FMT_THROW(format_error("can't AND a terminal color"));
|
||||
background_color.value.rgb_color &= rhs.background_color.value.rgb_color;
|
||||
}
|
||||
|
||||
ems = static_cast<emphasis>(static_cast<uint8_t>(ems) &
|
||||
static_cast<uint8_t>(rhs.ems));
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend FMT_CONSTEXPR text_style operator&(text_style lhs,
|
||||
const text_style& rhs) {
|
||||
return lhs &= rhs;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR bool has_foreground() const FMT_NOEXCEPT {
|
||||
return set_foreground_color;
|
||||
}
|
||||
FMT_CONSTEXPR bool has_background() const FMT_NOEXCEPT {
|
||||
return set_background_color;
|
||||
}
|
||||
FMT_CONSTEXPR bool has_emphasis() const FMT_NOEXCEPT {
|
||||
return static_cast<uint8_t>(ems) != 0;
|
||||
}
|
||||
FMT_CONSTEXPR detail::color_type get_foreground() const FMT_NOEXCEPT {
|
||||
FMT_ASSERT(has_foreground(), "no foreground specified for this style");
|
||||
return foreground_color;
|
||||
}
|
||||
FMT_CONSTEXPR detail::color_type get_background() const FMT_NOEXCEPT {
|
||||
FMT_ASSERT(has_background(), "no background specified for this style");
|
||||
return background_color;
|
||||
}
|
||||
FMT_CONSTEXPR emphasis get_emphasis() const FMT_NOEXCEPT {
|
||||
FMT_ASSERT(has_emphasis(), "no emphasis specified for this style");
|
||||
return ems;
|
||||
}
|
||||
|
||||
private:
|
||||
FMT_CONSTEXPR text_style(bool is_foreground,
|
||||
detail::color_type text_color) FMT_NOEXCEPT
|
||||
: set_foreground_color(),
|
||||
set_background_color(),
|
||||
ems() {
|
||||
if (is_foreground) {
|
||||
foreground_color = text_color;
|
||||
set_foreground_color = true;
|
||||
} else {
|
||||
background_color = text_color;
|
||||
set_background_color = true;
|
||||
}
|
||||
}
|
||||
|
||||
friend FMT_CONSTEXPR_DECL text_style fg(detail::color_type foreground)
|
||||
FMT_NOEXCEPT;
|
||||
friend FMT_CONSTEXPR_DECL text_style bg(detail::color_type background)
|
||||
FMT_NOEXCEPT;
|
||||
|
||||
detail::color_type foreground_color;
|
||||
detail::color_type background_color;
|
||||
bool set_foreground_color;
|
||||
bool set_background_color;
|
||||
emphasis ems;
|
||||
};
|
||||
|
||||
FMT_CONSTEXPR text_style fg(detail::color_type foreground) FMT_NOEXCEPT {
|
||||
return text_style(/*is_foreground=*/true, foreground);
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR text_style bg(detail::color_type background) FMT_NOEXCEPT {
|
||||
return text_style(/*is_foreground=*/false, background);
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR text_style operator|(emphasis lhs, emphasis rhs) FMT_NOEXCEPT {
|
||||
return text_style(lhs) | rhs;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Char> struct ansi_color_escape {
|
||||
FMT_CONSTEXPR ansi_color_escape(detail::color_type text_color,
|
||||
const char* esc) FMT_NOEXCEPT {
|
||||
// If we have a terminal color, we need to output another escape code
|
||||
// sequence.
|
||||
if (!text_color.is_rgb) {
|
||||
bool is_background = esc == detail::data::background_color;
|
||||
uint32_t value = text_color.value.term_color;
|
||||
// Background ASCII codes are the same as the foreground ones but with
|
||||
// 10 more.
|
||||
if (is_background) value += 10u;
|
||||
|
||||
size_t index = 0;
|
||||
buffer[index++] = static_cast<Char>('\x1b');
|
||||
buffer[index++] = static_cast<Char>('[');
|
||||
|
||||
if (value >= 100u) {
|
||||
buffer[index++] = static_cast<Char>('1');
|
||||
value %= 100u;
|
||||
}
|
||||
buffer[index++] = static_cast<Char>('0' + value / 10u);
|
||||
buffer[index++] = static_cast<Char>('0' + value % 10u);
|
||||
|
||||
buffer[index++] = static_cast<Char>('m');
|
||||
buffer[index++] = static_cast<Char>('\0');
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
buffer[i] = static_cast<Char>(esc[i]);
|
||||
}
|
||||
rgb color(text_color.value.rgb_color);
|
||||
to_esc(color.r, buffer + 7, ';');
|
||||
to_esc(color.g, buffer + 11, ';');
|
||||
to_esc(color.b, buffer + 15, 'm');
|
||||
buffer[19] = static_cast<Char>(0);
|
||||
}
|
||||
FMT_CONSTEXPR ansi_color_escape(emphasis em) FMT_NOEXCEPT {
|
||||
uint8_t em_codes[4] = {};
|
||||
uint8_t em_bits = static_cast<uint8_t>(em);
|
||||
if (em_bits & static_cast<uint8_t>(emphasis::bold)) em_codes[0] = 1;
|
||||
if (em_bits & static_cast<uint8_t>(emphasis::italic)) em_codes[1] = 3;
|
||||
if (em_bits & static_cast<uint8_t>(emphasis::underline)) em_codes[2] = 4;
|
||||
if (em_bits & static_cast<uint8_t>(emphasis::strikethrough))
|
||||
em_codes[3] = 9;
|
||||
|
||||
size_t index = 0;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (!em_codes[i]) continue;
|
||||
buffer[index++] = static_cast<Char>('\x1b');
|
||||
buffer[index++] = static_cast<Char>('[');
|
||||
buffer[index++] = static_cast<Char>('0' + em_codes[i]);
|
||||
buffer[index++] = static_cast<Char>('m');
|
||||
}
|
||||
buffer[index++] = static_cast<Char>(0);
|
||||
}
|
||||
FMT_CONSTEXPR operator const Char*() const FMT_NOEXCEPT { return buffer; }
|
||||
|
||||
FMT_CONSTEXPR const Char* begin() const FMT_NOEXCEPT { return buffer; }
|
||||
FMT_CONSTEXPR const Char* end() const FMT_NOEXCEPT {
|
||||
return buffer + std::char_traits<Char>::length(buffer);
|
||||
}
|
||||
|
||||
private:
|
||||
Char buffer[7u + 3u * 4u + 1u];
|
||||
|
||||
static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out,
|
||||
char delimiter) FMT_NOEXCEPT {
|
||||
out[0] = static_cast<Char>('0' + c / 100);
|
||||
out[1] = static_cast<Char>('0' + c / 10 % 10);
|
||||
out[2] = static_cast<Char>('0' + c % 10);
|
||||
out[3] = static_cast<Char>(delimiter);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR ansi_color_escape<Char> make_foreground_color(
|
||||
detail::color_type foreground) FMT_NOEXCEPT {
|
||||
return ansi_color_escape<Char>(foreground, detail::data::foreground_color);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR ansi_color_escape<Char> make_background_color(
|
||||
detail::color_type background) FMT_NOEXCEPT {
|
||||
return ansi_color_escape<Char>(background, detail::data::background_color);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR ansi_color_escape<Char> make_emphasis(emphasis em) FMT_NOEXCEPT {
|
||||
return ansi_color_escape<Char>(em);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline void fputs(const Char* chars, FILE* stream) FMT_NOEXCEPT {
|
||||
std::fputs(chars, stream);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void fputs<wchar_t>(const wchar_t* chars, FILE* stream) FMT_NOEXCEPT {
|
||||
std::fputws(chars, stream);
|
||||
}
|
||||
|
||||
template <typename Char> inline void reset_color(FILE* stream) FMT_NOEXCEPT {
|
||||
fputs(detail::data::reset_color, stream);
|
||||
}
|
||||
|
||||
template <> inline void reset_color<wchar_t>(FILE* stream) FMT_NOEXCEPT {
|
||||
fputs(detail::data::wreset_color, stream);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline void reset_color(basic_memory_buffer<Char>& buffer) FMT_NOEXCEPT {
|
||||
const char* begin = data::reset_color;
|
||||
const char* end = begin + sizeof(data::reset_color) - 1;
|
||||
buffer.append(begin, end);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
void vformat_to(basic_memory_buffer<Char>& buf, const text_style& ts,
|
||||
basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<Char>> args) {
|
||||
bool has_style = false;
|
||||
if (ts.has_emphasis()) {
|
||||
has_style = true;
|
||||
auto emphasis = detail::make_emphasis<Char>(ts.get_emphasis());
|
||||
buf.append(emphasis.begin(), emphasis.end());
|
||||
}
|
||||
if (ts.has_foreground()) {
|
||||
has_style = true;
|
||||
auto foreground = detail::make_foreground_color<Char>(ts.get_foreground());
|
||||
buf.append(foreground.begin(), foreground.end());
|
||||
}
|
||||
if (ts.has_background()) {
|
||||
has_style = true;
|
||||
auto background = detail::make_background_color<Char>(ts.get_background());
|
||||
buf.append(background.begin(), background.end());
|
||||
}
|
||||
detail::vformat_to(buf, format_str, args);
|
||||
if (has_style) detail::reset_color<Char>(buf);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
void vprint(std::FILE* f, const text_style& ts, const S& format,
|
||||
basic_format_args<buffer_context<Char>> args) {
|
||||
basic_memory_buffer<Char> buf;
|
||||
detail::vformat_to(buf, ts, to_string_view(format), args);
|
||||
buf.push_back(Char(0));
|
||||
detail::fputs(buf.data(), f);
|
||||
}
|
||||
|
||||
/**
|
||||
Formats a string and prints it to the specified file stream using ANSI
|
||||
escape sequences to specify text formatting.
|
||||
Example:
|
||||
fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
|
||||
"Elapsed time: {0:.2f} seconds", 1.23);
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_string<S>::value)>
|
||||
void print(std::FILE* f, const text_style& ts, const S& format_str,
|
||||
const Args&... args) {
|
||||
detail::check_format_string<Args...>(format_str);
|
||||
using context = buffer_context<char_t<S>>;
|
||||
format_arg_store<context, Args...> as{args...};
|
||||
vprint(f, ts, format_str, basic_format_args<context>(as));
|
||||
}
|
||||
|
||||
/**
|
||||
Formats a string and prints it to stdout using ANSI escape sequences to
|
||||
specify text formatting.
|
||||
Example:
|
||||
fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
|
||||
"Elapsed time: {0:.2f} seconds", 1.23);
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_string<S>::value)>
|
||||
void print(const text_style& ts, const S& format_str, const Args&... args) {
|
||||
return print(stdout, ts, format_str, args...);
|
||||
}
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline std::basic_string<Char> vformat(
|
||||
const text_style& ts, const S& format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buf;
|
||||
detail::vformat_to(buf, ts, to_string_view(format_str), args);
|
||||
return fmt::to_string(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Formats arguments and returns the result as a string using ANSI
|
||||
escape sequences to specify text formatting.
|
||||
|
||||
**Example**::
|
||||
|
||||
#include <fmt/color.h>
|
||||
std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red),
|
||||
"The answer is {}", 42);
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args, typename Char = char_t<S>>
|
||||
inline std::basic_string<Char> format(const text_style& ts, const S& format_str,
|
||||
const Args&... args) {
|
||||
return vformat(ts, to_string_view(format_str),
|
||||
detail::make_args_checked<Args...>(format_str, args...));
|
||||
}
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_COLOR_H_
|
665
external/fmtlib/include/fmt/compile.h
vendored
Normal file
665
external/fmtlib/include/fmt/compile.h
vendored
Normal file
@ -0,0 +1,665 @@
|
||||
// Formatting library for C++ - experimental format string compilation
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich and fmt contributors
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_COMPILE_H_
|
||||
#define FMT_COMPILE_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "format.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
// A compile-time string which is compiled into fast formatting code.
|
||||
class compiled_string {};
|
||||
|
||||
template <typename S>
|
||||
struct is_compiled_string : std::is_base_of<compiled_string, S> {};
|
||||
|
||||
/**
|
||||
\rst
|
||||
Converts a string literal *s* into a format string that will be parsed at
|
||||
compile time and converted into efficient formatting code. Requires C++17
|
||||
``constexpr if`` compiler support.
|
||||
|
||||
**Example**::
|
||||
|
||||
// Converts 42 into std::string using the most efficient method and no
|
||||
// runtime format string processing.
|
||||
std::string s = fmt::format(FMT_COMPILE("{}"), 42);
|
||||
\endrst
|
||||
*/
|
||||
#define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::detail::compiled_string)
|
||||
|
||||
template <typename T, typename... Tail>
|
||||
const T& first(const T& value, const Tail&...) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// Part of a compiled format string. It can be either literal text or a
|
||||
// replacement field.
|
||||
template <typename Char> struct format_part {
|
||||
enum class kind { arg_index, arg_name, text, replacement };
|
||||
|
||||
struct replacement {
|
||||
arg_ref<Char> arg_id;
|
||||
dynamic_format_specs<Char> specs;
|
||||
};
|
||||
|
||||
kind part_kind;
|
||||
union value {
|
||||
int arg_index;
|
||||
basic_string_view<Char> str;
|
||||
replacement repl;
|
||||
|
||||
FMT_CONSTEXPR value(int index = 0) : arg_index(index) {}
|
||||
FMT_CONSTEXPR value(basic_string_view<Char> s) : str(s) {}
|
||||
FMT_CONSTEXPR value(replacement r) : repl(r) {}
|
||||
} val;
|
||||
// Position past the end of the argument id.
|
||||
const Char* arg_id_end = nullptr;
|
||||
|
||||
FMT_CONSTEXPR format_part(kind k = kind::arg_index, value v = {})
|
||||
: part_kind(k), val(v) {}
|
||||
|
||||
static FMT_CONSTEXPR format_part make_arg_index(int index) {
|
||||
return format_part(kind::arg_index, index);
|
||||
}
|
||||
static FMT_CONSTEXPR format_part make_arg_name(basic_string_view<Char> name) {
|
||||
return format_part(kind::arg_name, name);
|
||||
}
|
||||
static FMT_CONSTEXPR format_part make_text(basic_string_view<Char> text) {
|
||||
return format_part(kind::text, text);
|
||||
}
|
||||
static FMT_CONSTEXPR format_part make_replacement(replacement repl) {
|
||||
return format_part(kind::replacement, repl);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char> struct part_counter {
|
||||
unsigned num_parts = 0;
|
||||
|
||||
FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) {
|
||||
if (begin != end) ++num_parts;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR int on_arg_id() { return ++num_parts, 0; }
|
||||
FMT_CONSTEXPR int on_arg_id(int) { return ++num_parts, 0; }
|
||||
FMT_CONSTEXPR int on_arg_id(basic_string_view<Char>) {
|
||||
return ++num_parts, 0;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void on_replacement_field(int, const Char*) {}
|
||||
|
||||
FMT_CONSTEXPR const Char* on_format_specs(int, const Char* begin,
|
||||
const Char* end) {
|
||||
// Find the matching brace.
|
||||
unsigned brace_counter = 0;
|
||||
for (; begin != end; ++begin) {
|
||||
if (*begin == '{') {
|
||||
++brace_counter;
|
||||
} else if (*begin == '}') {
|
||||
if (brace_counter == 0u) break;
|
||||
--brace_counter;
|
||||
}
|
||||
}
|
||||
return begin;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void on_error(const char*) {}
|
||||
};
|
||||
|
||||
// Counts the number of parts in a format string.
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR unsigned count_parts(basic_string_view<Char> format_str) {
|
||||
part_counter<Char> counter;
|
||||
parse_format_string<true>(format_str, counter);
|
||||
return counter.num_parts;
|
||||
}
|
||||
|
||||
template <typename Char, typename PartHandler>
|
||||
class format_string_compiler : public error_handler {
|
||||
private:
|
||||
using part = format_part<Char>;
|
||||
|
||||
PartHandler handler_;
|
||||
part part_;
|
||||
basic_string_view<Char> format_str_;
|
||||
basic_format_parse_context<Char> parse_context_;
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR format_string_compiler(basic_string_view<Char> format_str,
|
||||
PartHandler handler)
|
||||
: handler_(handler),
|
||||
format_str_(format_str),
|
||||
parse_context_(format_str) {}
|
||||
|
||||
FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) {
|
||||
if (begin != end)
|
||||
handler_(part::make_text({begin, to_unsigned(end - begin)}));
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR int on_arg_id() {
|
||||
part_ = part::make_arg_index(parse_context_.next_arg_id());
|
||||
return 0;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR int on_arg_id(int id) {
|
||||
parse_context_.check_arg_id(id);
|
||||
part_ = part::make_arg_index(id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR int on_arg_id(basic_string_view<Char> id) {
|
||||
part_ = part::make_arg_name(id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void on_replacement_field(int, const Char* ptr) {
|
||||
part_.arg_id_end = ptr;
|
||||
handler_(part_);
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR const Char* on_format_specs(int, const Char* begin,
|
||||
const Char* end) {
|
||||
auto repl = typename part::replacement();
|
||||
dynamic_specs_handler<basic_format_parse_context<Char>> handler(
|
||||
repl.specs, parse_context_);
|
||||
auto it = parse_format_specs(begin, end, handler);
|
||||
if (*it != '}') on_error("missing '}' in format string");
|
||||
repl.arg_id = part_.part_kind == part::kind::arg_index
|
||||
? arg_ref<Char>(part_.val.arg_index)
|
||||
: arg_ref<Char>(part_.val.str);
|
||||
auto part = part::make_replacement(repl);
|
||||
part.arg_id_end = begin;
|
||||
handler_(part);
|
||||
return it;
|
||||
}
|
||||
};
|
||||
|
||||
// Compiles a format string and invokes handler(part) for each parsed part.
|
||||
template <bool IS_CONSTEXPR, typename Char, typename PartHandler>
|
||||
FMT_CONSTEXPR void compile_format_string(basic_string_view<Char> format_str,
|
||||
PartHandler handler) {
|
||||
parse_format_string<IS_CONSTEXPR>(
|
||||
format_str,
|
||||
format_string_compiler<Char, PartHandler>(format_str, handler));
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename Context, typename Id>
|
||||
void format_arg(
|
||||
basic_format_parse_context<typename Context::char_type>& parse_ctx,
|
||||
Context& ctx, Id arg_id) {
|
||||
ctx.advance_to(visit_format_arg(
|
||||
arg_formatter<OutputIt, typename Context::char_type>(ctx, &parse_ctx),
|
||||
ctx.arg(arg_id)));
|
||||
}
|
||||
|
||||
// vformat_to is defined in a subnamespace to prevent ADL.
|
||||
namespace cf {
|
||||
template <typename Context, typename OutputIt, typename CompiledFormat>
|
||||
auto vformat_to(OutputIt out, CompiledFormat& cf,
|
||||
basic_format_args<Context> args) -> typename Context::iterator {
|
||||
using char_type = typename Context::char_type;
|
||||
basic_format_parse_context<char_type> parse_ctx(
|
||||
to_string_view(cf.format_str_));
|
||||
Context ctx(out, args);
|
||||
|
||||
const auto& parts = cf.parts();
|
||||
for (auto part_it = std::begin(parts); part_it != std::end(parts);
|
||||
++part_it) {
|
||||
const auto& part = *part_it;
|
||||
const auto& value = part.val;
|
||||
|
||||
using format_part_t = format_part<char_type>;
|
||||
switch (part.part_kind) {
|
||||
case format_part_t::kind::text: {
|
||||
const auto text = value.str;
|
||||
auto output = ctx.out();
|
||||
auto&& it = reserve(output, text.size());
|
||||
it = std::copy_n(text.begin(), text.size(), it);
|
||||
ctx.advance_to(output);
|
||||
break;
|
||||
}
|
||||
|
||||
case format_part_t::kind::arg_index:
|
||||
advance_to(parse_ctx, part.arg_id_end);
|
||||
detail::format_arg<OutputIt>(parse_ctx, ctx, value.arg_index);
|
||||
break;
|
||||
|
||||
case format_part_t::kind::arg_name:
|
||||
advance_to(parse_ctx, part.arg_id_end);
|
||||
detail::format_arg<OutputIt>(parse_ctx, ctx, value.str);
|
||||
break;
|
||||
|
||||
case format_part_t::kind::replacement: {
|
||||
const auto& arg_id_value = value.repl.arg_id.val;
|
||||
const auto arg = value.repl.arg_id.kind == arg_id_kind::index
|
||||
? ctx.arg(arg_id_value.index)
|
||||
: ctx.arg(arg_id_value.name);
|
||||
|
||||
auto specs = value.repl.specs;
|
||||
|
||||
handle_dynamic_spec<width_checker>(specs.width, specs.width_ref, ctx);
|
||||
handle_dynamic_spec<precision_checker>(specs.precision,
|
||||
specs.precision_ref, ctx);
|
||||
|
||||
error_handler h;
|
||||
numeric_specs_checker<error_handler> checker(h, arg.type());
|
||||
if (specs.align == align::numeric) checker.require_numeric_argument();
|
||||
if (specs.sign != sign::none) checker.check_sign();
|
||||
if (specs.alt) checker.require_numeric_argument();
|
||||
if (specs.precision >= 0) checker.check_precision();
|
||||
|
||||
advance_to(parse_ctx, part.arg_id_end);
|
||||
ctx.advance_to(
|
||||
visit_format_arg(arg_formatter<OutputIt, typename Context::char_type>(
|
||||
ctx, nullptr, &specs),
|
||||
arg));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ctx.out();
|
||||
}
|
||||
} // namespace cf
|
||||
|
||||
struct basic_compiled_format {};
|
||||
|
||||
template <typename S, typename = void>
|
||||
struct compiled_format_base : basic_compiled_format {
|
||||
using char_type = char_t<S>;
|
||||
using parts_container = std::vector<detail::format_part<char_type>>;
|
||||
|
||||
parts_container compiled_parts;
|
||||
|
||||
explicit compiled_format_base(basic_string_view<char_type> format_str) {
|
||||
compile_format_string<false>(format_str,
|
||||
[this](const format_part<char_type>& part) {
|
||||
compiled_parts.push_back(part);
|
||||
});
|
||||
}
|
||||
|
||||
const parts_container& parts() const { return compiled_parts; }
|
||||
};
|
||||
|
||||
template <typename Char, unsigned N> struct format_part_array {
|
||||
format_part<Char> data[N] = {};
|
||||
FMT_CONSTEXPR format_part_array() = default;
|
||||
};
|
||||
|
||||
template <typename Char, unsigned N>
|
||||
FMT_CONSTEXPR format_part_array<Char, N> compile_to_parts(
|
||||
basic_string_view<Char> format_str) {
|
||||
format_part_array<Char, N> parts;
|
||||
unsigned counter = 0;
|
||||
// This is not a lambda for compatibility with older compilers.
|
||||
struct {
|
||||
format_part<Char>* parts;
|
||||
unsigned* counter;
|
||||
FMT_CONSTEXPR void operator()(const format_part<Char>& part) {
|
||||
parts[(*counter)++] = part;
|
||||
}
|
||||
} collector{parts.data, &counter};
|
||||
compile_format_string<true>(format_str, collector);
|
||||
if (counter < N) {
|
||||
parts.data[counter] =
|
||||
format_part<Char>::make_text(basic_string_view<Char>());
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
template <typename T> constexpr const T& constexpr_max(const T& a, const T& b) {
|
||||
return (a < b) ? b : a;
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
struct compiled_format_base<S, enable_if_t<is_compile_string<S>::value>>
|
||||
: basic_compiled_format {
|
||||
using char_type = char_t<S>;
|
||||
|
||||
FMT_CONSTEXPR explicit compiled_format_base(basic_string_view<char_type>) {}
|
||||
|
||||
// Workaround for old compilers. Format string compilation will not be
|
||||
// performed there anyway.
|
||||
#if FMT_USE_CONSTEXPR
|
||||
static FMT_CONSTEXPR_DECL const unsigned num_format_parts =
|
||||
constexpr_max(count_parts(to_string_view(S())), 1u);
|
||||
#else
|
||||
static const unsigned num_format_parts = 1;
|
||||
#endif
|
||||
|
||||
using parts_container = format_part<char_type>[num_format_parts];
|
||||
|
||||
const parts_container& parts() const {
|
||||
static FMT_CONSTEXPR_DECL const auto compiled_parts =
|
||||
compile_to_parts<char_type, num_format_parts>(
|
||||
detail::to_string_view(S()));
|
||||
return compiled_parts.data;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename S, typename... Args>
|
||||
class compiled_format : private compiled_format_base<S> {
|
||||
public:
|
||||
using typename compiled_format_base<S>::char_type;
|
||||
|
||||
private:
|
||||
basic_string_view<char_type> format_str_;
|
||||
|
||||
template <typename Context, typename OutputIt, typename CompiledFormat>
|
||||
friend auto cf::vformat_to(OutputIt out, CompiledFormat& cf,
|
||||
basic_format_args<Context> args) ->
|
||||
typename Context::iterator;
|
||||
|
||||
public:
|
||||
compiled_format() = delete;
|
||||
explicit constexpr compiled_format(basic_string_view<char_type> format_str)
|
||||
: compiled_format_base<S>(format_str), format_str_(format_str) {}
|
||||
};
|
||||
|
||||
#ifdef __cpp_if_constexpr
|
||||
template <typename... Args> struct type_list {};
|
||||
|
||||
// Returns a reference to the argument at index N from [first, rest...].
|
||||
template <int N, typename T, typename... Args>
|
||||
constexpr const auto& get(const T& first, const Args&... rest) {
|
||||
static_assert(N < 1 + sizeof...(Args), "index is out of bounds");
|
||||
if constexpr (N == 0)
|
||||
return first;
|
||||
else
|
||||
return get<N - 1>(rest...);
|
||||
}
|
||||
|
||||
template <int N, typename> struct get_type_impl;
|
||||
|
||||
template <int N, typename... Args> struct get_type_impl<N, type_list<Args...>> {
|
||||
using type = remove_cvref_t<decltype(get<N>(std::declval<Args>()...))>;
|
||||
};
|
||||
|
||||
template <int N, typename T>
|
||||
using get_type = typename get_type_impl<N, T>::type;
|
||||
|
||||
template <typename T> struct is_compiled_format : std::false_type {};
|
||||
|
||||
template <typename Char> struct text {
|
||||
basic_string_view<Char> data;
|
||||
using char_type = Char;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
OutputIt format(OutputIt out, const Args&...) const {
|
||||
return write<Char>(out, data);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
struct is_compiled_format<text<Char>> : std::true_type {};
|
||||
|
||||
template <typename Char>
|
||||
constexpr text<Char> make_text(basic_string_view<Char> s, size_t pos,
|
||||
size_t size) {
|
||||
return {{&s[pos], size}};
|
||||
}
|
||||
|
||||
// A replacement field that refers to argument N.
|
||||
template <typename Char, typename T, int N> struct field {
|
||||
using char_type = Char;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
OutputIt format(OutputIt out, const Args&... args) const {
|
||||
// This ensures that the argument type is convertile to `const T&`.
|
||||
const T& arg = get<N>(args...);
|
||||
return write<Char>(out, arg);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename T, int N>
|
||||
struct is_compiled_format<field<Char, T, N>> : std::true_type {};
|
||||
|
||||
// A replacement field that refers to argument N and has format specifiers.
|
||||
template <typename Char, typename T, int N> struct spec_field {
|
||||
using char_type = Char;
|
||||
mutable formatter<T, Char> fmt;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
OutputIt format(OutputIt out, const Args&... args) const {
|
||||
// This ensures that the argument type is convertile to `const T&`.
|
||||
const T& arg = get<N>(args...);
|
||||
basic_format_context<OutputIt, Char> ctx(out, {});
|
||||
return fmt.format(arg, ctx);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename T, int N>
|
||||
struct is_compiled_format<spec_field<Char, T, N>> : std::true_type {};
|
||||
|
||||
template <typename L, typename R> struct concat {
|
||||
L lhs;
|
||||
R rhs;
|
||||
using char_type = typename L::char_type;
|
||||
|
||||
template <typename OutputIt, typename... Args>
|
||||
OutputIt format(OutputIt out, const Args&... args) const {
|
||||
out = lhs.format(out, args...);
|
||||
return rhs.format(out, args...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
struct is_compiled_format<concat<L, R>> : std::true_type {};
|
||||
|
||||
template <typename L, typename R>
|
||||
constexpr concat<L, R> make_concat(L lhs, R rhs) {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
|
||||
struct unknown_format {};
|
||||
|
||||
template <typename Char>
|
||||
constexpr size_t parse_text(basic_string_view<Char> str, size_t pos) {
|
||||
for (size_t size = str.size(); pos != size; ++pos) {
|
||||
if (str[pos] == '{' || str[pos] == '}') break;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
template <typename Args, size_t POS, int ID, typename S>
|
||||
constexpr auto compile_format_string(S format_str);
|
||||
|
||||
template <typename Args, size_t POS, int ID, typename T, typename S>
|
||||
constexpr auto parse_tail(T head, S format_str) {
|
||||
if constexpr (POS !=
|
||||
basic_string_view<typename S::char_type>(format_str).size()) {
|
||||
constexpr auto tail = compile_format_string<Args, POS, ID>(format_str);
|
||||
if constexpr (std::is_same<remove_cvref_t<decltype(tail)>,
|
||||
unknown_format>())
|
||||
return tail;
|
||||
else
|
||||
return make_concat(head, tail);
|
||||
} else {
|
||||
return head;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Char> struct parse_specs_result {
|
||||
formatter<T, Char> fmt;
|
||||
size_t end;
|
||||
};
|
||||
|
||||
template <typename T, typename Char>
|
||||
constexpr parse_specs_result<T, Char> parse_specs(basic_string_view<Char> str,
|
||||
size_t pos) {
|
||||
str.remove_prefix(pos);
|
||||
auto ctx = basic_format_parse_context<Char>(str);
|
||||
auto f = formatter<T, Char>();
|
||||
auto end = f.parse(ctx);
|
||||
return {f, pos + (end - str.data()) + 1};
|
||||
}
|
||||
|
||||
// Compiles a non-empty format string and returns the compiled representation
|
||||
// or unknown_format() on unrecognized input.
|
||||
template <typename Args, size_t POS, int ID, typename S>
|
||||
constexpr auto compile_format_string(S format_str) {
|
||||
using char_type = typename S::char_type;
|
||||
constexpr basic_string_view<char_type> str = format_str;
|
||||
if constexpr (str[POS] == '{') {
|
||||
if (POS + 1 == str.size())
|
||||
throw format_error("unmatched '{' in format string");
|
||||
if constexpr (str[POS + 1] == '{') {
|
||||
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
|
||||
} else if constexpr (str[POS + 1] == '}') {
|
||||
using type = get_type<ID, Args>;
|
||||
return parse_tail<Args, POS + 2, ID + 1>(field<char_type, type, ID>(),
|
||||
format_str);
|
||||
} else if constexpr (str[POS + 1] == ':') {
|
||||
using type = get_type<ID, Args>;
|
||||
constexpr auto result = parse_specs<type>(str, POS + 2);
|
||||
return parse_tail<Args, result.end, ID + 1>(
|
||||
spec_field<char_type, type, ID>{result.fmt}, format_str);
|
||||
} else {
|
||||
return unknown_format();
|
||||
}
|
||||
} else if constexpr (str[POS] == '}') {
|
||||
if (POS + 1 == str.size())
|
||||
throw format_error("unmatched '}' in format string");
|
||||
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
|
||||
} else {
|
||||
constexpr auto end = parse_text(str, POS + 1);
|
||||
return parse_tail<Args, end, ID>(make_text(str, POS, end - POS),
|
||||
format_str);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args, typename S,
|
||||
FMT_ENABLE_IF(is_compile_string<S>::value ||
|
||||
detail::is_compiled_string<S>::value)>
|
||||
constexpr auto compile(S format_str) {
|
||||
constexpr basic_string_view<typename S::char_type> str = format_str;
|
||||
if constexpr (str.size() == 0) {
|
||||
return detail::make_text(str, 0, 0);
|
||||
} else {
|
||||
constexpr auto result =
|
||||
detail::compile_format_string<detail::type_list<Args...>, 0, 0>(
|
||||
format_str);
|
||||
if constexpr (std::is_same<remove_cvref_t<decltype(result)>,
|
||||
detail::unknown_format>()) {
|
||||
return detail::compiled_format<S, Args...>(to_string_view(format_str));
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
template <typename... Args, typename S,
|
||||
FMT_ENABLE_IF(is_compile_string<S>::value)>
|
||||
constexpr auto compile(S format_str) -> detail::compiled_format<S, Args...> {
|
||||
return detail::compiled_format<S, Args...>(to_string_view(format_str));
|
||||
}
|
||||
#endif // __cpp_if_constexpr
|
||||
|
||||
// Compiles the format string which must be a string literal.
|
||||
template <typename... Args, typename Char, size_t N>
|
||||
auto compile(const Char (&format_str)[N])
|
||||
-> detail::compiled_format<const Char*, Args...> {
|
||||
return detail::compiled_format<const Char*, Args...>(
|
||||
basic_string_view<Char>(format_str, N - 1));
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// DEPRECATED! use FMT_COMPILE instead.
|
||||
template <typename... Args>
|
||||
FMT_DEPRECATED auto compile(const Args&... args)
|
||||
-> decltype(detail::compile(args...)) {
|
||||
return detail::compile(args...);
|
||||
}
|
||||
|
||||
#if FMT_USE_CONSTEXPR
|
||||
# ifdef __cpp_if_constexpr
|
||||
|
||||
template <typename CompiledFormat, typename... Args,
|
||||
typename Char = typename CompiledFormat::char_type,
|
||||
FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
|
||||
FMT_INLINE std::basic_string<Char> format(const CompiledFormat& cf,
|
||||
const Args&... args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
detail::buffer<Char>& base = buffer;
|
||||
cf.format(std::back_inserter(base), args...);
|
||||
return to_string(buffer);
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename CompiledFormat, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
|
||||
OutputIt format_to(OutputIt out, const CompiledFormat& cf,
|
||||
const Args&... args) {
|
||||
return cf.format(out, args...);
|
||||
}
|
||||
# endif // __cpp_if_constexpr
|
||||
#endif // FMT_USE_CONSTEXPR
|
||||
|
||||
template <typename CompiledFormat, typename... Args,
|
||||
typename Char = typename CompiledFormat::char_type,
|
||||
FMT_ENABLE_IF(std::is_base_of<detail::basic_compiled_format,
|
||||
CompiledFormat>::value)>
|
||||
std::basic_string<Char> format(const CompiledFormat& cf, const Args&... args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
using context = buffer_context<Char>;
|
||||
detail::buffer<Char>& base = buffer;
|
||||
detail::cf::vformat_to<context>(std::back_inserter(base), cf,
|
||||
make_format_args<context>(args...));
|
||||
return to_string(buffer);
|
||||
}
|
||||
|
||||
template <typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
||||
FMT_INLINE std::basic_string<typename S::char_type> format(const S&,
|
||||
Args&&... args) {
|
||||
constexpr basic_string_view<typename S::char_type> str = S();
|
||||
if (str.size() == 2 && str[0] == '{' && str[1] == '}')
|
||||
return fmt::to_string(detail::first(args...));
|
||||
constexpr auto compiled = detail::compile<Args...>(S());
|
||||
return format(compiled, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename CompiledFormat, typename... Args,
|
||||
FMT_ENABLE_IF(std::is_base_of<detail::basic_compiled_format,
|
||||
CompiledFormat>::value)>
|
||||
OutputIt format_to(OutputIt out, const CompiledFormat& cf,
|
||||
const Args&... args) {
|
||||
using char_type = typename CompiledFormat::char_type;
|
||||
using context = format_context_t<OutputIt, char_type>;
|
||||
return detail::cf::vformat_to<context>(out, cf,
|
||||
make_format_args<context>(args...));
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
||||
OutputIt format_to(OutputIt out, const S&, const Args&... args) {
|
||||
constexpr auto compiled = detail::compile<Args...>(S());
|
||||
return format_to(out, compiled, args...);
|
||||
}
|
||||
|
||||
template <
|
||||
typename OutputIt, typename CompiledFormat, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt>::value&& std::is_base_of<
|
||||
detail::basic_compiled_format, CompiledFormat>::value)>
|
||||
format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n,
|
||||
const CompiledFormat& cf,
|
||||
const Args&... args) {
|
||||
auto it =
|
||||
format_to(detail::truncating_iterator<OutputIt>(out, n), cf, args...);
|
||||
return {it.base(), it.count()};
|
||||
}
|
||||
|
||||
template <typename CompiledFormat, typename... Args>
|
||||
size_t formatted_size(const CompiledFormat& cf, const Args&... args) {
|
||||
return format_to(detail::counting_iterator(), cf, args...).count();
|
||||
}
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_COMPILE_H_
|
1882
external/fmtlib/include/fmt/core.h
vendored
Normal file
1882
external/fmtlib/include/fmt/core.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1453
external/fmtlib/include/fmt/format-inl.h
vendored
Normal file
1453
external/fmtlib/include/fmt/format-inl.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3729
external/fmtlib/include/fmt/format.h
vendored
Normal file
3729
external/fmtlib/include/fmt/format.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
78
external/fmtlib/include/fmt/locale.h
vendored
Normal file
78
external/fmtlib/include/fmt/locale.h
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
// Formatting library for C++ - std::locale support
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_LOCALE_H_
|
||||
#define FMT_LOCALE_H_
|
||||
|
||||
#include <locale>
|
||||
|
||||
#include "format.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
namespace detail {
|
||||
template <typename Char>
|
||||
typename buffer_context<Char>::iterator vformat_to(
|
||||
const std::locale& loc, buffer<Char>& buf,
|
||||
basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
using af = arg_formatter<typename buffer_context<Char>::iterator, Char>;
|
||||
return vformat_to<af>(std::back_inserter(buf), to_string_view(format_str),
|
||||
args, detail::locale_ref(loc));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
std::basic_string<Char> vformat(
|
||||
const std::locale& loc, basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
detail::vformat_to(loc, buffer, format_str, args);
|
||||
return fmt::to_string(buffer);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline std::basic_string<Char> vformat(
|
||||
const std::locale& loc, const S& format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
return detail::vformat(loc, to_string_view(format_str), args);
|
||||
}
|
||||
|
||||
template <typename S, typename... Args, typename Char = char_t<S>>
|
||||
inline std::basic_string<Char> format(const std::locale& loc,
|
||||
const S& format_str, Args&&... args) {
|
||||
return detail::vformat(
|
||||
loc, to_string_view(format_str),
|
||||
detail::make_args_checked<Args...>(format_str, args...));
|
||||
}
|
||||
|
||||
template <typename S, typename OutputIt, typename... Args,
|
||||
typename Char = enable_if_t<
|
||||
detail::is_output_iterator<OutputIt>::value, char_t<S>>>
|
||||
inline OutputIt vformat_to(
|
||||
OutputIt out, const std::locale& loc, const S& format_str,
|
||||
format_args_t<type_identity_t<OutputIt>, Char> args) {
|
||||
using af = detail::arg_formatter<OutputIt, Char>;
|
||||
return vformat_to<af>(out, to_string_view(format_str), args,
|
||||
detail::locale_ref(loc));
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt>::value&&
|
||||
detail::is_string<S>::value)>
|
||||
inline OutputIt format_to(OutputIt out, const std::locale& loc,
|
||||
const S& format_str, Args&&... args) {
|
||||
detail::check_format_string<Args...>(format_str);
|
||||
using context = format_context_t<OutputIt, char_t<S>>;
|
||||
format_arg_store<context, Args...> as{args...};
|
||||
return vformat_to(out, loc, to_string_view(format_str),
|
||||
basic_format_args<context>(as));
|
||||
}
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_LOCALE_H_
|
450
external/fmtlib/include/fmt/os.h
vendored
Normal file
450
external/fmtlib/include/fmt/os.h
vendored
Normal file
@ -0,0 +1,450 @@
|
||||
// Formatting library for C++ - optional OS-specific functionality
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_OS_H_
|
||||
#define FMT_OS_H_
|
||||
|
||||
#if defined(__MINGW32__) || defined(__CYGWIN__)
|
||||
// Workaround MinGW bug https://sourceforge.net/p/mingw/bugs/2024/.
|
||||
# undef __STRICT_ANSI__
|
||||
#endif
|
||||
|
||||
#include <cerrno>
|
||||
#include <clocale> // for locale_t
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstdlib> // for strtod_l
|
||||
|
||||
#if defined __APPLE__ || defined(__FreeBSD__)
|
||||
# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
|
||||
#endif
|
||||
|
||||
#include "format.h"
|
||||
|
||||
// UWP doesn't provide _pipe.
|
||||
#if FMT_HAS_INCLUDE("winapifamily.h")
|
||||
# include <winapifamily.h>
|
||||
#endif
|
||||
#if FMT_HAS_INCLUDE("fcntl.h") && \
|
||||
(!defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
|
||||
# include <fcntl.h> // for O_RDONLY
|
||||
# define FMT_USE_FCNTL 1
|
||||
#else
|
||||
# define FMT_USE_FCNTL 0
|
||||
#endif
|
||||
|
||||
#ifndef FMT_POSIX
|
||||
# if defined(_WIN32) && !defined(__MINGW32__)
|
||||
// Fix warnings about deprecated symbols.
|
||||
# define FMT_POSIX(call) _##call
|
||||
# else
|
||||
# define FMT_POSIX(call) call
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Calls to system functions are wrapped in FMT_SYSTEM for testability.
|
||||
#ifdef FMT_SYSTEM
|
||||
# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
|
||||
#else
|
||||
# define FMT_SYSTEM(call) ::call
|
||||
# ifdef _WIN32
|
||||
// Fix warnings about deprecated symbols.
|
||||
# define FMT_POSIX_CALL(call) ::_##call
|
||||
# else
|
||||
# define FMT_POSIX_CALL(call) ::call
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Retries the expression while it evaluates to error_result and errno
|
||||
// equals to EINTR.
|
||||
#ifndef _WIN32
|
||||
# define FMT_RETRY_VAL(result, expression, error_result) \
|
||||
do { \
|
||||
(result) = (expression); \
|
||||
} while ((result) == (error_result) && errno == EINTR)
|
||||
#else
|
||||
# define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
|
||||
#endif
|
||||
|
||||
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
/**
|
||||
\rst
|
||||
A reference to a null-terminated string. It can be constructed from a C
|
||||
string or ``std::string``.
|
||||
|
||||
You can use one of the following type aliases for common character types:
|
||||
|
||||
+---------------+-----------------------------+
|
||||
| Type | Definition |
|
||||
+===============+=============================+
|
||||
| cstring_view | basic_cstring_view<char> |
|
||||
+---------------+-----------------------------+
|
||||
| wcstring_view | basic_cstring_view<wchar_t> |
|
||||
+---------------+-----------------------------+
|
||||
|
||||
This class is most useful as a parameter type to allow passing
|
||||
different types of strings to a function, for example::
|
||||
|
||||
template <typename... Args>
|
||||
std::string format(cstring_view format_str, const Args & ... args);
|
||||
|
||||
format("{}", 42);
|
||||
format(std::string("{}"), 42);
|
||||
\endrst
|
||||
*/
|
||||
template <typename Char> class basic_cstring_view {
|
||||
private:
|
||||
const Char* data_;
|
||||
|
||||
public:
|
||||
/** Constructs a string reference object from a C string. */
|
||||
basic_cstring_view(const Char* s) : data_(s) {}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Constructs a string reference from an ``std::string`` object.
|
||||
\endrst
|
||||
*/
|
||||
basic_cstring_view(const std::basic_string<Char>& s) : data_(s.c_str()) {}
|
||||
|
||||
/** Returns the pointer to a C string. */
|
||||
const Char* c_str() const { return data_; }
|
||||
};
|
||||
|
||||
using cstring_view = basic_cstring_view<char>;
|
||||
using wcstring_view = basic_cstring_view<wchar_t>;
|
||||
|
||||
// An error code.
|
||||
class error_code {
|
||||
private:
|
||||
int value_;
|
||||
|
||||
public:
|
||||
explicit error_code(int value = 0) FMT_NOEXCEPT : value_(value) {}
|
||||
|
||||
int get() const FMT_NOEXCEPT { return value_; }
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
namespace detail {
|
||||
// A converter from UTF-16 to UTF-8.
|
||||
// It is only provided for Windows since other systems support UTF-8 natively.
|
||||
class utf16_to_utf8 {
|
||||
private:
|
||||
memory_buffer buffer_;
|
||||
|
||||
public:
|
||||
utf16_to_utf8() {}
|
||||
FMT_API explicit utf16_to_utf8(wstring_view s);
|
||||
operator string_view() const { return string_view(&buffer_[0], size()); }
|
||||
size_t size() const { return buffer_.size() - 1; }
|
||||
const char* c_str() const { return &buffer_[0]; }
|
||||
std::string str() const { return std::string(&buffer_[0], size()); }
|
||||
|
||||
// Performs conversion returning a system error code instead of
|
||||
// throwing exception on conversion error. This method may still throw
|
||||
// in case of memory allocation error.
|
||||
FMT_API int convert(wstring_view s);
|
||||
};
|
||||
|
||||
FMT_API void format_windows_error(buffer<char>& out, int error_code,
|
||||
string_view message) FMT_NOEXCEPT;
|
||||
} // namespace detail
|
||||
|
||||
/** A Windows error. */
|
||||
class windows_error : public system_error {
|
||||
private:
|
||||
FMT_API void init(int error_code, string_view format_str, format_args args);
|
||||
|
||||
public:
|
||||
/**
|
||||
\rst
|
||||
Constructs a :class:`fmt::windows_error` object with the description
|
||||
of the form
|
||||
|
||||
.. parsed-literal::
|
||||
*<message>*: *<system-message>*
|
||||
|
||||
where *<message>* is the formatted message and *<system-message>* is the
|
||||
system message corresponding to the error code.
|
||||
*error_code* is a Windows error code as given by ``GetLastError``.
|
||||
If *error_code* is not a valid error code such as -1, the system message
|
||||
will look like "error -1".
|
||||
|
||||
**Example**::
|
||||
|
||||
// This throws a windows_error with the description
|
||||
// cannot open file 'madeup': The system cannot find the file specified.
|
||||
// or similar (system message may vary).
|
||||
const char *filename = "madeup";
|
||||
LPOFSTRUCT of = LPOFSTRUCT();
|
||||
HFILE file = OpenFile(filename, &of, OF_READ);
|
||||
if (file == HFILE_ERROR) {
|
||||
throw fmt::windows_error(GetLastError(),
|
||||
"cannot open file '{}'", filename);
|
||||
}
|
||||
\endrst
|
||||
*/
|
||||
template <typename... Args>
|
||||
windows_error(int error_code, string_view message, const Args&... args) {
|
||||
init(error_code, message, make_format_args(args...));
|
||||
}
|
||||
};
|
||||
|
||||
// Reports a Windows error without throwing an exception.
|
||||
// Can be used to report errors from destructors.
|
||||
FMT_API void report_windows_error(int error_code,
|
||||
string_view message) FMT_NOEXCEPT;
|
||||
#endif // _WIN32
|
||||
|
||||
// A buffered file.
|
||||
class buffered_file {
|
||||
private:
|
||||
FILE* file_;
|
||||
|
||||
friend class file;
|
||||
|
||||
explicit buffered_file(FILE* f) : file_(f) {}
|
||||
|
||||
public:
|
||||
buffered_file(const buffered_file&) = delete;
|
||||
void operator=(const buffered_file&) = delete;
|
||||
|
||||
// Constructs a buffered_file object which doesn't represent any file.
|
||||
buffered_file() FMT_NOEXCEPT : file_(nullptr) {}
|
||||
|
||||
// Destroys the object closing the file it represents if any.
|
||||
FMT_API ~buffered_file() FMT_NOEXCEPT;
|
||||
|
||||
public:
|
||||
buffered_file(buffered_file&& other) FMT_NOEXCEPT : file_(other.file_) {
|
||||
other.file_ = nullptr;
|
||||
}
|
||||
|
||||
buffered_file& operator=(buffered_file&& other) {
|
||||
close();
|
||||
file_ = other.file_;
|
||||
other.file_ = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Opens a file.
|
||||
FMT_API buffered_file(cstring_view filename, cstring_view mode);
|
||||
|
||||
// Closes the file.
|
||||
FMT_API void close();
|
||||
|
||||
// Returns the pointer to a FILE object representing this file.
|
||||
FILE* get() const FMT_NOEXCEPT { return file_; }
|
||||
|
||||
// We place parentheses around fileno to workaround a bug in some versions
|
||||
// of MinGW that define fileno as a macro.
|
||||
FMT_API int(fileno)() const;
|
||||
|
||||
void vprint(string_view format_str, format_args args) {
|
||||
fmt::vprint(file_, format_str, args);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void print(string_view format_str, const Args&... args) {
|
||||
vprint(format_str, make_format_args(args...));
|
||||
}
|
||||
};
|
||||
|
||||
#if FMT_USE_FCNTL
|
||||
// A file. Closed file is represented by a file object with descriptor -1.
|
||||
// Methods that are not declared with FMT_NOEXCEPT may throw
|
||||
// fmt::system_error in case of failure. Note that some errors such as
|
||||
// closing the file multiple times will cause a crash on Windows rather
|
||||
// than an exception. You can get standard behavior by overriding the
|
||||
// invalid parameter handler with _set_invalid_parameter_handler.
|
||||
class file {
|
||||
private:
|
||||
int fd_; // File descriptor.
|
||||
|
||||
// Constructs a file object with a given descriptor.
|
||||
explicit file(int fd) : fd_(fd) {}
|
||||
|
||||
public:
|
||||
// Possible values for the oflag argument to the constructor.
|
||||
enum {
|
||||
RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only.
|
||||
WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only.
|
||||
RDWR = FMT_POSIX(O_RDWR), // Open for reading and writing.
|
||||
CREATE = FMT_POSIX(O_CREAT) // Create if the file doesn't exist.
|
||||
};
|
||||
|
||||
// Constructs a file object which doesn't represent any file.
|
||||
file() FMT_NOEXCEPT : fd_(-1) {}
|
||||
|
||||
// Opens a file and constructs a file object representing this file.
|
||||
FMT_API file(cstring_view path, int oflag);
|
||||
|
||||
public:
|
||||
file(const file&) = delete;
|
||||
void operator=(const file&) = delete;
|
||||
|
||||
file(file&& other) FMT_NOEXCEPT : fd_(other.fd_) { other.fd_ = -1; }
|
||||
|
||||
file& operator=(file&& other) FMT_NOEXCEPT {
|
||||
close();
|
||||
fd_ = other.fd_;
|
||||
other.fd_ = -1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Destroys the object closing the file it represents if any.
|
||||
FMT_API ~file() FMT_NOEXCEPT;
|
||||
|
||||
// Returns the file descriptor.
|
||||
int descriptor() const FMT_NOEXCEPT { return fd_; }
|
||||
|
||||
// Closes the file.
|
||||
FMT_API void close();
|
||||
|
||||
// Returns the file size. The size has signed type for consistency with
|
||||
// stat::st_size.
|
||||
FMT_API long long size() const;
|
||||
|
||||
// Attempts to read count bytes from the file into the specified buffer.
|
||||
FMT_API size_t read(void* buffer, size_t count);
|
||||
|
||||
// Attempts to write count bytes from the specified buffer to the file.
|
||||
FMT_API size_t write(const void* buffer, size_t count);
|
||||
|
||||
// Duplicates a file descriptor with the dup function and returns
|
||||
// the duplicate as a file object.
|
||||
FMT_API static file dup(int fd);
|
||||
|
||||
// Makes fd be the copy of this file descriptor, closing fd first if
|
||||
// necessary.
|
||||
FMT_API void dup2(int fd);
|
||||
|
||||
// Makes fd be the copy of this file descriptor, closing fd first if
|
||||
// necessary.
|
||||
FMT_API void dup2(int fd, error_code& ec) FMT_NOEXCEPT;
|
||||
|
||||
// Creates a pipe setting up read_end and write_end file objects for reading
|
||||
// and writing respectively.
|
||||
FMT_API static void pipe(file& read_end, file& write_end);
|
||||
|
||||
// Creates a buffered_file object associated with this file and detaches
|
||||
// this file object from the file.
|
||||
FMT_API buffered_file fdopen(const char* mode);
|
||||
};
|
||||
|
||||
// Returns the memory page size.
|
||||
long getpagesize();
|
||||
|
||||
class direct_buffered_file;
|
||||
|
||||
template <typename S, typename... Args>
|
||||
void print(direct_buffered_file& f, const S& format_str,
|
||||
const Args&... args);
|
||||
|
||||
// A buffered file with a direct buffer access and no synchronization.
|
||||
class direct_buffered_file {
|
||||
private:
|
||||
file file_;
|
||||
|
||||
enum { buffer_size = 4096 };
|
||||
char buffer_[buffer_size];
|
||||
int pos_;
|
||||
|
||||
void flush() {
|
||||
if (pos_ == 0) return;
|
||||
file_.write(buffer_, pos_);
|
||||
pos_ = 0;
|
||||
}
|
||||
|
||||
int free_capacity() const { return buffer_size - pos_; }
|
||||
|
||||
public:
|
||||
direct_buffered_file(cstring_view path, int oflag)
|
||||
: file_(path, oflag), pos_(0) {}
|
||||
|
||||
~direct_buffered_file() {
|
||||
flush();
|
||||
}
|
||||
|
||||
void close() {
|
||||
flush();
|
||||
file_.close();
|
||||
}
|
||||
|
||||
template <typename S, typename... Args>
|
||||
friend void print(direct_buffered_file& f, const S& format_str,
|
||||
const Args&... args) {
|
||||
// We could avoid double buffering.
|
||||
auto buf = fmt::memory_buffer();
|
||||
fmt::format_to(std::back_inserter(buf), format_str, args...);
|
||||
auto remaining_pos = 0;
|
||||
auto remaining_size = buf.size();
|
||||
while (remaining_size > detail::to_unsigned(f.free_capacity())) {
|
||||
auto size = f.free_capacity();
|
||||
memcpy(f.buffer_ + f.pos_, buf.data() + remaining_pos, size);
|
||||
f.pos_ += size;
|
||||
f.flush();
|
||||
remaining_pos += size;
|
||||
remaining_size -= size;
|
||||
}
|
||||
memcpy(f.buffer_ + f.pos_, buf.data() + remaining_pos, remaining_size);
|
||||
f.pos_ += static_cast<int>(remaining_size);
|
||||
}
|
||||
};
|
||||
#endif // FMT_USE_FCNTL
|
||||
|
||||
#ifdef FMT_LOCALE
|
||||
// A "C" numeric locale.
|
||||
class locale {
|
||||
private:
|
||||
# ifdef _WIN32
|
||||
using locale_t = _locale_t;
|
||||
|
||||
static void freelocale(locale_t loc) { _free_locale(loc); }
|
||||
|
||||
static double strtod_l(const char* nptr, char** endptr, _locale_t loc) {
|
||||
return _strtod_l(nptr, endptr, loc);
|
||||
}
|
||||
# endif
|
||||
|
||||
locale_t locale_;
|
||||
|
||||
public:
|
||||
using type = locale_t;
|
||||
locale(const locale&) = delete;
|
||||
void operator=(const locale&) = delete;
|
||||
|
||||
locale() {
|
||||
# ifndef _WIN32
|
||||
locale_ = FMT_SYSTEM(newlocale(LC_NUMERIC_MASK, "C", nullptr));
|
||||
# else
|
||||
locale_ = _create_locale(LC_NUMERIC, "C");
|
||||
# endif
|
||||
if (!locale_) FMT_THROW(system_error(errno, "cannot create locale"));
|
||||
}
|
||||
~locale() { freelocale(locale_); }
|
||||
|
||||
type get() const { return locale_; }
|
||||
|
||||
// Converts string to floating-point number and advances str past the end
|
||||
// of the parsed input.
|
||||
double strtod(const char*& str) const {
|
||||
char* end = nullptr;
|
||||
double result = strtod_l(str, &end, locale_);
|
||||
str = end;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
using Locale FMT_DEPRECATED_ALIAS = locale;
|
||||
#endif // FMT_LOCALE
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_OS_H_
|
167
external/fmtlib/include/fmt/ostream.h
vendored
Normal file
167
external/fmtlib/include/fmt/ostream.h
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
// Formatting library for C++ - std::ostream support
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_OSTREAM_H_
|
||||
#define FMT_OSTREAM_H_
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "format.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
template <typename Char> class basic_printf_parse_context;
|
||||
template <typename OutputIt, typename Char> class basic_printf_context;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class Char> class formatbuf : public std::basic_streambuf<Char> {
|
||||
private:
|
||||
using int_type = typename std::basic_streambuf<Char>::int_type;
|
||||
using traits_type = typename std::basic_streambuf<Char>::traits_type;
|
||||
|
||||
buffer<Char>& buffer_;
|
||||
|
||||
public:
|
||||
formatbuf(buffer<Char>& buf) : buffer_(buf) {}
|
||||
|
||||
protected:
|
||||
// The put-area is actually always empty. This makes the implementation
|
||||
// simpler and has the advantage that the streambuf and the buffer are always
|
||||
// in sync and sputc never writes into uninitialized memory. The obvious
|
||||
// disadvantage is that each call to sputc always results in a (virtual) call
|
||||
// to overflow. There is no disadvantage here for sputn since this always
|
||||
// results in a call to xsputn.
|
||||
|
||||
int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE {
|
||||
if (!traits_type::eq_int_type(ch, traits_type::eof()))
|
||||
buffer_.push_back(static_cast<Char>(ch));
|
||||
return ch;
|
||||
}
|
||||
|
||||
std::streamsize xsputn(const Char* s, std::streamsize count) FMT_OVERRIDE {
|
||||
buffer_.append(s, s + count);
|
||||
return count;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char> struct test_stream : std::basic_ostream<Char> {
|
||||
private:
|
||||
// Hide all operator<< from std::basic_ostream<Char>.
|
||||
void_t<> operator<<(null<>);
|
||||
void_t<> operator<<(const Char*);
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(std::is_convertible<T, int>::value &&
|
||||
!std::is_enum<T>::value)>
|
||||
void_t<> operator<<(T);
|
||||
};
|
||||
|
||||
// Checks if T has a user-defined operator<< (e.g. not a member of
|
||||
// std::ostream).
|
||||
template <typename T, typename Char> class is_streamable {
|
||||
private:
|
||||
template <typename U>
|
||||
static bool_constant<!std::is_same<decltype(std::declval<test_stream<Char>&>()
|
||||
<< std::declval<U>()),
|
||||
void_t<>>::value>
|
||||
test(int);
|
||||
|
||||
template <typename> static std::false_type test(...);
|
||||
|
||||
using result = decltype(test<T>(0));
|
||||
|
||||
public:
|
||||
static const bool value = result::value;
|
||||
};
|
||||
|
||||
// Write the content of buf to os.
|
||||
template <typename Char>
|
||||
void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {
|
||||
const Char* buf_data = buf.data();
|
||||
using unsigned_streamsize = std::make_unsigned<std::streamsize>::type;
|
||||
unsigned_streamsize size = buf.size();
|
||||
unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());
|
||||
do {
|
||||
unsigned_streamsize n = size <= max_size ? size : max_size;
|
||||
os.write(buf_data, static_cast<std::streamsize>(n));
|
||||
buf_data += n;
|
||||
size -= n;
|
||||
} while (size != 0);
|
||||
}
|
||||
|
||||
template <typename Char, typename T>
|
||||
void format_value(buffer<Char>& buf, const T& value,
|
||||
locale_ref loc = locale_ref()) {
|
||||
formatbuf<Char> format_buf(buf);
|
||||
std::basic_ostream<Char> output(&format_buf);
|
||||
#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
|
||||
if (loc) output.imbue(loc.get<std::locale>());
|
||||
#endif
|
||||
output << value;
|
||||
output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
|
||||
buf.resize(buf.size());
|
||||
}
|
||||
|
||||
// Formats an object of type T that has an overloaded ostream operator<<.
|
||||
template <typename T, typename Char>
|
||||
struct fallback_formatter<T, Char, enable_if_t<is_streamable<T, Char>::value>>
|
||||
: private formatter<basic_string_view<Char>, Char> {
|
||||
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
|
||||
-> decltype(ctx.begin()) {
|
||||
return formatter<basic_string_view<Char>, Char>::parse(ctx);
|
||||
}
|
||||
template <typename ParseCtx,
|
||||
FMT_ENABLE_IF(std::is_same<
|
||||
ParseCtx, basic_printf_parse_context<Char>>::value)>
|
||||
auto parse(ParseCtx& ctx) -> decltype(ctx.begin()) {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
template <typename OutputIt>
|
||||
auto format(const T& value, basic_format_context<OutputIt, Char>& ctx)
|
||||
-> OutputIt {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
format_value(buffer, value, ctx.locale());
|
||||
basic_string_view<Char> str(buffer.data(), buffer.size());
|
||||
return formatter<basic_string_view<Char>, Char>::format(str, ctx);
|
||||
}
|
||||
template <typename OutputIt>
|
||||
auto format(const T& value, basic_printf_context<OutputIt, Char>& ctx)
|
||||
-> OutputIt {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
format_value(buffer, value, ctx.locale());
|
||||
return std::copy(buffer.begin(), buffer.end(), ctx.out());
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <typename Char>
|
||||
void vprint(std::basic_ostream<Char>& os, basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
detail::vformat_to(buffer, format_str, args);
|
||||
detail::write_buffer(os, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Prints formatted data to the stream *os*.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::print(cerr, "Don't {}!", "panic");
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
|
||||
void print(std::basic_ostream<Char>& os, const S& format_str, Args&&... args) {
|
||||
vprint(os, to_string_view(format_str),
|
||||
detail::make_args_checked<Args...>(format_str, args...));
|
||||
}
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_OSTREAM_H_
|
2
external/fmtlib/include/fmt/posix.h
vendored
Normal file
2
external/fmtlib/include/fmt/posix.h
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
#include "os.h"
|
||||
#warning "fmt/posix.h is deprecated; use fmt/os.h instead"
|
751
external/fmtlib/include/fmt/printf.h
vendored
Normal file
751
external/fmtlib/include/fmt/printf.h
vendored
Normal file
@ -0,0 +1,751 @@
|
||||
// Formatting library for C++ - legacy printf implementation
|
||||
//
|
||||
// Copyright (c) 2012 - 2016, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_PRINTF_H_
|
||||
#define FMT_PRINTF_H_
|
||||
|
||||
#include <algorithm> // std::max
|
||||
#include <limits> // std::numeric_limits
|
||||
|
||||
#include "ostream.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
// Checks if a value fits in int - used to avoid warnings about comparing
|
||||
// signed and unsigned integers.
|
||||
template <bool IsSigned> struct int_checker {
|
||||
template <typename T> static bool fits_in_int(T value) {
|
||||
unsigned max = max_value<int>();
|
||||
return value <= max;
|
||||
}
|
||||
static bool fits_in_int(bool) { return true; }
|
||||
};
|
||||
|
||||
template <> struct int_checker<true> {
|
||||
template <typename T> static bool fits_in_int(T value) {
|
||||
return value >= (std::numeric_limits<int>::min)() &&
|
||||
value <= max_value<int>();
|
||||
}
|
||||
static bool fits_in_int(int) { return true; }
|
||||
};
|
||||
|
||||
class printf_precision_handler {
|
||||
public:
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
int operator()(T value) {
|
||||
if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
|
||||
FMT_THROW(format_error("number is too big"));
|
||||
return (std::max)(static_cast<int>(value), 0);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
int operator()(T) {
|
||||
FMT_THROW(format_error("precision is not integer"));
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
// An argument visitor that returns true iff arg is a zero integer.
|
||||
class is_zero_int {
|
||||
public:
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
bool operator()(T value) {
|
||||
return value == 0;
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
bool operator()(T) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> struct make_unsigned_or_bool : std::make_unsigned<T> {};
|
||||
|
||||
template <> struct make_unsigned_or_bool<bool> { using type = bool; };
|
||||
|
||||
template <typename T, typename Context> class arg_converter {
|
||||
private:
|
||||
using char_type = typename Context::char_type;
|
||||
|
||||
basic_format_arg<Context>& arg_;
|
||||
char_type type_;
|
||||
|
||||
public:
|
||||
arg_converter(basic_format_arg<Context>& arg, char_type type)
|
||||
: arg_(arg), type_(type) {}
|
||||
|
||||
void operator()(bool value) {
|
||||
if (type_ != 's') operator()<bool>(value);
|
||||
}
|
||||
|
||||
template <typename U, FMT_ENABLE_IF(std::is_integral<U>::value)>
|
||||
void operator()(U value) {
|
||||
bool is_signed = type_ == 'd' || type_ == 'i';
|
||||
using target_type = conditional_t<std::is_same<T, void>::value, U, T>;
|
||||
if (const_check(sizeof(target_type) <= sizeof(int))) {
|
||||
// Extra casts are used to silence warnings.
|
||||
if (is_signed) {
|
||||
arg_ = detail::make_arg<Context>(
|
||||
static_cast<int>(static_cast<target_type>(value)));
|
||||
} else {
|
||||
using unsigned_type = typename make_unsigned_or_bool<target_type>::type;
|
||||
arg_ = detail::make_arg<Context>(
|
||||
static_cast<unsigned>(static_cast<unsigned_type>(value)));
|
||||
}
|
||||
} else {
|
||||
if (is_signed) {
|
||||
// glibc's printf doesn't sign extend arguments of smaller types:
|
||||
// std::printf("%lld", -42); // prints "4294967254"
|
||||
// but we don't have to do the same because it's a UB.
|
||||
arg_ = detail::make_arg<Context>(static_cast<long long>(value));
|
||||
} else {
|
||||
arg_ = detail::make_arg<Context>(
|
||||
static_cast<typename make_unsigned_or_bool<U>::type>(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename U, FMT_ENABLE_IF(!std::is_integral<U>::value)>
|
||||
void operator()(U) {} // No conversion needed for non-integral types.
|
||||
};
|
||||
|
||||
// Converts an integer argument to T for printf, if T is an integral type.
|
||||
// If T is void, the argument is converted to corresponding signed or unsigned
|
||||
// type depending on the type specifier: 'd' and 'i' - signed, other -
|
||||
// unsigned).
|
||||
template <typename T, typename Context, typename Char>
|
||||
void convert_arg(basic_format_arg<Context>& arg, Char type) {
|
||||
visit_format_arg(arg_converter<T, Context>(arg, type), arg);
|
||||
}
|
||||
|
||||
// Converts an integer argument to char for printf.
|
||||
template <typename Context> class char_converter {
|
||||
private:
|
||||
basic_format_arg<Context>& arg_;
|
||||
|
||||
public:
|
||||
explicit char_converter(basic_format_arg<Context>& arg) : arg_(arg) {}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
void operator()(T value) {
|
||||
arg_ = detail::make_arg<Context>(
|
||||
static_cast<typename Context::char_type>(value));
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
void operator()(T) {} // No conversion needed for non-integral types.
|
||||
};
|
||||
|
||||
// An argument visitor that return a pointer to a C string if argument is a
|
||||
// string or null otherwise.
|
||||
template <typename Char> struct get_cstring {
|
||||
template <typename T> const Char* operator()(T) { return nullptr; }
|
||||
const Char* operator()(const Char* s) { return s; }
|
||||
};
|
||||
|
||||
// Checks if an argument is a valid printf width specifier and sets
|
||||
// left alignment if it is negative.
|
||||
template <typename Char> class printf_width_handler {
|
||||
private:
|
||||
using format_specs = basic_format_specs<Char>;
|
||||
|
||||
format_specs& specs_;
|
||||
|
||||
public:
|
||||
explicit printf_width_handler(format_specs& specs) : specs_(specs) {}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
unsigned operator()(T value) {
|
||||
auto width = static_cast<uint32_or_64_or_128_t<T>>(value);
|
||||
if (detail::is_negative(value)) {
|
||||
specs_.align = align::left;
|
||||
width = 0 - width;
|
||||
}
|
||||
unsigned int_max = max_value<int>();
|
||||
if (width > int_max) FMT_THROW(format_error("number is too big"));
|
||||
return static_cast<unsigned>(width);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
unsigned operator()(T) {
|
||||
FMT_THROW(format_error("width is not integer"));
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename Context>
|
||||
void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
|
||||
basic_format_args<Context> args) {
|
||||
Context(std::back_inserter(buf), format, args).format();
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// For printing into memory_buffer.
|
||||
template <typename Char, typename Context>
|
||||
FMT_DEPRECATED void printf(detail::buffer<Char>& buf,
|
||||
basic_string_view<Char> format,
|
||||
basic_format_args<Context> args) {
|
||||
return detail::vprintf(buf, format, args);
|
||||
}
|
||||
using detail::vprintf;
|
||||
|
||||
template <typename Char>
|
||||
class basic_printf_parse_context : public basic_format_parse_context<Char> {
|
||||
using basic_format_parse_context<Char>::basic_format_parse_context;
|
||||
};
|
||||
template <typename OutputIt, typename Char> class basic_printf_context;
|
||||
|
||||
/**
|
||||
\rst
|
||||
The ``printf`` argument formatter.
|
||||
\endrst
|
||||
*/
|
||||
template <typename OutputIt, typename Char>
|
||||
class printf_arg_formatter : public detail::arg_formatter_base<OutputIt, Char> {
|
||||
public:
|
||||
using iterator = OutputIt;
|
||||
|
||||
private:
|
||||
using char_type = Char;
|
||||
using base = detail::arg_formatter_base<OutputIt, Char>;
|
||||
using context_type = basic_printf_context<OutputIt, Char>;
|
||||
|
||||
context_type& context_;
|
||||
|
||||
void write_null_pointer(char) {
|
||||
this->specs()->type = 0;
|
||||
this->write("(nil)");
|
||||
}
|
||||
|
||||
void write_null_pointer(wchar_t) {
|
||||
this->specs()->type = 0;
|
||||
this->write(L"(nil)");
|
||||
}
|
||||
|
||||
public:
|
||||
using format_specs = typename base::format_specs;
|
||||
|
||||
/**
|
||||
\rst
|
||||
Constructs an argument formatter object.
|
||||
*buffer* is a reference to the output buffer and *specs* contains format
|
||||
specifier information for standard argument types.
|
||||
\endrst
|
||||
*/
|
||||
printf_arg_formatter(iterator iter, format_specs& specs, context_type& ctx)
|
||||
: base(iter, &specs, detail::locale_ref()), context_(ctx) {}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(fmt::detail::is_integral<T>::value)>
|
||||
iterator operator()(T value) {
|
||||
// MSVC2013 fails to compile separate overloads for bool and char_type so
|
||||
// use std::is_same instead.
|
||||
if (std::is_same<T, bool>::value) {
|
||||
format_specs& fmt_specs = *this->specs();
|
||||
if (fmt_specs.type != 's') return base::operator()(value ? 1 : 0);
|
||||
fmt_specs.type = 0;
|
||||
this->write(value != 0);
|
||||
} else if (std::is_same<T, char_type>::value) {
|
||||
format_specs& fmt_specs = *this->specs();
|
||||
if (fmt_specs.type && fmt_specs.type != 'c')
|
||||
return (*this)(static_cast<int>(value));
|
||||
fmt_specs.sign = sign::none;
|
||||
fmt_specs.alt = false;
|
||||
fmt_specs.fill[0] = ' '; // Ignore '0' flag for char types.
|
||||
// align::numeric needs to be overwritten here since the '0' flag is
|
||||
// ignored for non-numeric types
|
||||
if (fmt_specs.align == align::none || fmt_specs.align == align::numeric)
|
||||
fmt_specs.align = align::right;
|
||||
return base::operator()(value);
|
||||
} else {
|
||||
return base::operator()(value);
|
||||
}
|
||||
return this->out();
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
|
||||
iterator operator()(T value) {
|
||||
return base::operator()(value);
|
||||
}
|
||||
|
||||
/** Formats a null-terminated C string. */
|
||||
iterator operator()(const char* value) {
|
||||
if (value)
|
||||
base::operator()(value);
|
||||
else if (this->specs()->type == 'p')
|
||||
write_null_pointer(char_type());
|
||||
else
|
||||
this->write("(null)");
|
||||
return this->out();
|
||||
}
|
||||
|
||||
/** Formats a null-terminated wide C string. */
|
||||
iterator operator()(const wchar_t* value) {
|
||||
if (value)
|
||||
base::operator()(value);
|
||||
else if (this->specs()->type == 'p')
|
||||
write_null_pointer(char_type());
|
||||
else
|
||||
this->write(L"(null)");
|
||||
return this->out();
|
||||
}
|
||||
|
||||
iterator operator()(basic_string_view<char_type> value) {
|
||||
return base::operator()(value);
|
||||
}
|
||||
|
||||
iterator operator()(monostate value) { return base::operator()(value); }
|
||||
|
||||
/** Formats a pointer. */
|
||||
iterator operator()(const void* value) {
|
||||
if (value) return base::operator()(value);
|
||||
this->specs()->type = 0;
|
||||
write_null_pointer(char_type());
|
||||
return this->out();
|
||||
}
|
||||
|
||||
/** Formats an argument of a custom (user-defined) type. */
|
||||
iterator operator()(typename basic_format_arg<context_type>::handle handle) {
|
||||
handle.format(context_.parse_context(), context_);
|
||||
return this->out();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> struct printf_formatter {
|
||||
printf_formatter() = delete;
|
||||
|
||||
template <typename ParseContext>
|
||||
auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(const T& value, FormatContext& ctx) -> decltype(ctx.out()) {
|
||||
detail::format_value(detail::get_container(ctx.out()), value);
|
||||
return ctx.out();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
This template formats data and writes the output through an output iterator.
|
||||
*/
|
||||
template <typename OutputIt, typename Char> class basic_printf_context {
|
||||
public:
|
||||
/** The character type for the output. */
|
||||
using char_type = Char;
|
||||
using iterator = OutputIt;
|
||||
using format_arg = basic_format_arg<basic_printf_context>;
|
||||
using parse_context_type = basic_printf_parse_context<Char>;
|
||||
template <typename T> using formatter_type = printf_formatter<T>;
|
||||
|
||||
private:
|
||||
using format_specs = basic_format_specs<char_type>;
|
||||
|
||||
OutputIt out_;
|
||||
basic_format_args<basic_printf_context> args_;
|
||||
parse_context_type parse_ctx_;
|
||||
|
||||
static void parse_flags(format_specs& specs, const Char*& it,
|
||||
const Char* end);
|
||||
|
||||
// Returns the argument with specified index or, if arg_index is -1, the next
|
||||
// argument.
|
||||
format_arg get_arg(int arg_index = -1);
|
||||
|
||||
// Parses argument index, flags and width and returns the argument index.
|
||||
int parse_header(const Char*& it, const Char* end, format_specs& specs);
|
||||
|
||||
public:
|
||||
/**
|
||||
\rst
|
||||
Constructs a ``printf_context`` object. References to the arguments are
|
||||
stored in the context object so make sure they have appropriate lifetimes.
|
||||
\endrst
|
||||
*/
|
||||
basic_printf_context(OutputIt out, basic_string_view<char_type> format_str,
|
||||
basic_format_args<basic_printf_context> args)
|
||||
: out_(out), args_(args), parse_ctx_(format_str) {}
|
||||
|
||||
OutputIt out() { return out_; }
|
||||
void advance_to(OutputIt it) { out_ = it; }
|
||||
|
||||
detail::locale_ref locale() { return {}; }
|
||||
|
||||
format_arg arg(int id) const { return args_.get(id); }
|
||||
|
||||
parse_context_type& parse_context() { return parse_ctx_; }
|
||||
|
||||
FMT_CONSTEXPR void on_error(const char* message) {
|
||||
parse_ctx_.on_error(message);
|
||||
}
|
||||
|
||||
/** Formats stored arguments and writes the output to the range. */
|
||||
template <typename ArgFormatter = printf_arg_formatter<OutputIt, Char>>
|
||||
OutputIt format();
|
||||
};
|
||||
|
||||
template <typename OutputIt, typename Char>
|
||||
void basic_printf_context<OutputIt, Char>::parse_flags(format_specs& specs,
|
||||
const Char*& it,
|
||||
const Char* end) {
|
||||
for (; it != end; ++it) {
|
||||
switch (*it) {
|
||||
case '-':
|
||||
specs.align = align::left;
|
||||
break;
|
||||
case '+':
|
||||
specs.sign = sign::plus;
|
||||
break;
|
||||
case '0':
|
||||
specs.fill[0] = '0';
|
||||
break;
|
||||
case ' ':
|
||||
if (specs.sign != sign::plus) {
|
||||
specs.sign = sign::space;
|
||||
}
|
||||
break;
|
||||
case '#':
|
||||
specs.alt = true;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename Char>
|
||||
typename basic_printf_context<OutputIt, Char>::format_arg
|
||||
basic_printf_context<OutputIt, Char>::get_arg(int arg_index) {
|
||||
if (arg_index < 0)
|
||||
arg_index = parse_ctx_.next_arg_id();
|
||||
else
|
||||
parse_ctx_.check_arg_id(--arg_index);
|
||||
return detail::get_arg(*this, arg_index);
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename Char>
|
||||
int basic_printf_context<OutputIt, Char>::parse_header(const Char*& it,
|
||||
const Char* end,
|
||||
format_specs& specs) {
|
||||
int arg_index = -1;
|
||||
char_type c = *it;
|
||||
if (c >= '0' && c <= '9') {
|
||||
// Parse an argument index (if followed by '$') or a width possibly
|
||||
// preceded with '0' flag(s).
|
||||
detail::error_handler eh;
|
||||
int value = parse_nonnegative_int(it, end, eh);
|
||||
if (it != end && *it == '$') { // value is an argument index
|
||||
++it;
|
||||
arg_index = value;
|
||||
} else {
|
||||
if (c == '0') specs.fill[0] = '0';
|
||||
if (value != 0) {
|
||||
// Nonzero value means that we parsed width and don't need to
|
||||
// parse it or flags again, so return now.
|
||||
specs.width = value;
|
||||
return arg_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
parse_flags(specs, it, end);
|
||||
// Parse width.
|
||||
if (it != end) {
|
||||
if (*it >= '0' && *it <= '9') {
|
||||
detail::error_handler eh;
|
||||
specs.width = parse_nonnegative_int(it, end, eh);
|
||||
} else if (*it == '*') {
|
||||
++it;
|
||||
specs.width = static_cast<int>(visit_format_arg(
|
||||
detail::printf_width_handler<char_type>(specs), get_arg()));
|
||||
}
|
||||
}
|
||||
return arg_index;
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename Char>
|
||||
template <typename ArgFormatter>
|
||||
OutputIt basic_printf_context<OutputIt, Char>::format() {
|
||||
auto out = this->out();
|
||||
const Char* start = parse_ctx_.begin();
|
||||
const Char* end = parse_ctx_.end();
|
||||
auto it = start;
|
||||
while (it != end) {
|
||||
char_type c = *it++;
|
||||
if (c != '%') continue;
|
||||
if (it != end && *it == c) {
|
||||
out = std::copy(start, it, out);
|
||||
start = ++it;
|
||||
continue;
|
||||
}
|
||||
out = std::copy(start, it - 1, out);
|
||||
|
||||
format_specs specs;
|
||||
specs.align = align::right;
|
||||
|
||||
// Parse argument index, flags and width.
|
||||
int arg_index = parse_header(it, end, specs);
|
||||
if (arg_index == 0) on_error("argument not found");
|
||||
|
||||
// Parse precision.
|
||||
if (it != end && *it == '.') {
|
||||
++it;
|
||||
c = it != end ? *it : 0;
|
||||
if ('0' <= c && c <= '9') {
|
||||
detail::error_handler eh;
|
||||
specs.precision = parse_nonnegative_int(it, end, eh);
|
||||
} else if (c == '*') {
|
||||
++it;
|
||||
specs.precision = static_cast<int>(
|
||||
visit_format_arg(detail::printf_precision_handler(), get_arg()));
|
||||
} else {
|
||||
specs.precision = 0;
|
||||
}
|
||||
}
|
||||
|
||||
format_arg arg = get_arg(arg_index);
|
||||
// For d, i, o, u, x, and X conversion specifiers, if a precision is
|
||||
// specified, the '0' flag is ignored
|
||||
if (specs.precision >= 0 && arg.is_integral())
|
||||
specs.fill[0] =
|
||||
' '; // Ignore '0' flag for non-numeric types or if '-' present.
|
||||
if (specs.precision >= 0 && arg.type() == detail::type::cstring_type) {
|
||||
auto str = visit_format_arg(detail::get_cstring<Char>(), arg);
|
||||
auto str_end = str + specs.precision;
|
||||
auto nul = std::find(str, str_end, Char());
|
||||
arg = detail::make_arg<basic_printf_context>(basic_string_view<Char>(
|
||||
str,
|
||||
detail::to_unsigned(nul != str_end ? nul - str : specs.precision)));
|
||||
}
|
||||
if (specs.alt && visit_format_arg(detail::is_zero_int(), arg))
|
||||
specs.alt = false;
|
||||
if (specs.fill[0] == '0') {
|
||||
if (arg.is_arithmetic() && specs.align != align::left)
|
||||
specs.align = align::numeric;
|
||||
else
|
||||
specs.fill[0] = ' '; // Ignore '0' flag for non-numeric types or if '-'
|
||||
// flag is also present.
|
||||
}
|
||||
|
||||
// Parse length and convert the argument to the required type.
|
||||
c = it != end ? *it++ : 0;
|
||||
char_type t = it != end ? *it : 0;
|
||||
using detail::convert_arg;
|
||||
switch (c) {
|
||||
case 'h':
|
||||
if (t == 'h') {
|
||||
++it;
|
||||
t = it != end ? *it : 0;
|
||||
convert_arg<signed char>(arg, t);
|
||||
} else {
|
||||
convert_arg<short>(arg, t);
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
if (t == 'l') {
|
||||
++it;
|
||||
t = it != end ? *it : 0;
|
||||
convert_arg<long long>(arg, t);
|
||||
} else {
|
||||
convert_arg<long>(arg, t);
|
||||
}
|
||||
break;
|
||||
case 'j':
|
||||
convert_arg<intmax_t>(arg, t);
|
||||
break;
|
||||
case 'z':
|
||||
convert_arg<size_t>(arg, t);
|
||||
break;
|
||||
case 't':
|
||||
convert_arg<std::ptrdiff_t>(arg, t);
|
||||
break;
|
||||
case 'L':
|
||||
// printf produces garbage when 'L' is omitted for long double, no
|
||||
// need to do the same.
|
||||
break;
|
||||
default:
|
||||
--it;
|
||||
convert_arg<void>(arg, c);
|
||||
}
|
||||
|
||||
// Parse type.
|
||||
if (it == end) FMT_THROW(format_error("invalid format string"));
|
||||
specs.type = static_cast<char>(*it++);
|
||||
if (arg.is_integral()) {
|
||||
// Normalize type.
|
||||
switch (specs.type) {
|
||||
case 'i':
|
||||
case 'u':
|
||||
specs.type = 'd';
|
||||
break;
|
||||
case 'c':
|
||||
visit_format_arg(detail::char_converter<basic_printf_context>(arg),
|
||||
arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
start = it;
|
||||
|
||||
// Format argument.
|
||||
out = visit_format_arg(ArgFormatter(out, specs, *this), arg);
|
||||
}
|
||||
return std::copy(start, it, out);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
using basic_printf_context_t =
|
||||
basic_printf_context<std::back_insert_iterator<detail::buffer<Char>>, Char>;
|
||||
|
||||
using printf_context = basic_printf_context_t<char>;
|
||||
using wprintf_context = basic_printf_context_t<wchar_t>;
|
||||
|
||||
using printf_args = basic_format_args<printf_context>;
|
||||
using wprintf_args = basic_format_args<wprintf_context>;
|
||||
|
||||
/**
|
||||
\rst
|
||||
Constructs an `~fmt::format_arg_store` object that contains references to
|
||||
arguments and can be implicitly converted to `~fmt::printf_args`.
|
||||
\endrst
|
||||
*/
|
||||
template <typename... Args>
|
||||
inline format_arg_store<printf_context, Args...> make_printf_args(
|
||||
const Args&... args) {
|
||||
return {args...};
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Constructs an `~fmt::format_arg_store` object that contains references to
|
||||
arguments and can be implicitly converted to `~fmt::wprintf_args`.
|
||||
\endrst
|
||||
*/
|
||||
template <typename... Args>
|
||||
inline format_arg_store<wprintf_context, Args...> make_wprintf_args(
|
||||
const Args&... args) {
|
||||
return {args...};
|
||||
}
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline std::basic_string<Char> vsprintf(
|
||||
const S& format,
|
||||
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
vprintf(buffer, to_string_view(format), args);
|
||||
return to_string(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Formats arguments and returns the result as a string.
|
||||
|
||||
**Example**::
|
||||
|
||||
std::string message = fmt::sprintf("The answer is %d", 42);
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
|
||||
inline std::basic_string<Char> sprintf(const S& format, const Args&... args) {
|
||||
using context = basic_printf_context_t<Char>;
|
||||
return vsprintf(to_string_view(format), make_format_args<context>(args...));
|
||||
}
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline int vfprintf(
|
||||
std::FILE* f, const S& format,
|
||||
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
vprintf(buffer, to_string_view(format), args);
|
||||
size_t size = buffer.size();
|
||||
return std::fwrite(buffer.data(), sizeof(Char), size, f) < size
|
||||
? -1
|
||||
: static_cast<int>(size);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Prints formatted data to the file *f*.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::fprintf(stderr, "Don't %s!", "panic");
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
|
||||
inline int fprintf(std::FILE* f, const S& format, const Args&... args) {
|
||||
using context = basic_printf_context_t<Char>;
|
||||
return vfprintf(f, to_string_view(format),
|
||||
make_format_args<context>(args...));
|
||||
}
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline int vprintf(
|
||||
const S& format,
|
||||
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
|
||||
return vfprintf(stdout, to_string_view(format), args);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Prints formatted data to ``stdout``.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::printf("Elapsed time: %.2f seconds", 1.23);
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_string<S>::value)>
|
||||
inline int printf(const S& format_str, const Args&... args) {
|
||||
using context = basic_printf_context_t<char_t<S>>;
|
||||
return vprintf(to_string_view(format_str),
|
||||
make_format_args<context>(args...));
|
||||
}
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline int vfprintf(
|
||||
std::basic_ostream<Char>& os, const S& format,
|
||||
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
|
||||
basic_memory_buffer<Char> buffer;
|
||||
vprintf(buffer, to_string_view(format), args);
|
||||
detail::write_buffer(os, buffer);
|
||||
return static_cast<int>(buffer.size());
|
||||
}
|
||||
|
||||
/** Formats arguments and writes the output to the range. */
|
||||
template <typename ArgFormatter, typename Char,
|
||||
typename Context =
|
||||
basic_printf_context<typename ArgFormatter::iterator, Char>>
|
||||
typename ArgFormatter::iterator vprintf(
|
||||
detail::buffer<Char>& out, basic_string_view<Char> format_str,
|
||||
basic_format_args<type_identity_t<Context>> args) {
|
||||
typename ArgFormatter::iterator iter(out);
|
||||
Context(iter, format_str, args).template format<ArgFormatter>();
|
||||
return iter;
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Prints formatted data to the stream *os*.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::fprintf(cerr, "Don't %s!", "panic");
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args, typename Char = char_t<S>>
|
||||
inline int fprintf(std::basic_ostream<Char>& os, const S& format_str,
|
||||
const Args&... args) {
|
||||
using context = basic_printf_context_t<Char>;
|
||||
return vfprintf(os, to_string_view(format_str),
|
||||
make_format_args<context>(args...));
|
||||
}
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_PRINTF_H_
|
386
external/fmtlib/include/fmt/ranges.h
vendored
Normal file
386
external/fmtlib/include/fmt/ranges.h
vendored
Normal file
@ -0,0 +1,386 @@
|
||||
// Formatting library for C++ - experimental range support
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
//
|
||||
// Copyright (c) 2018 - present, Remotion (Igor Schulz)
|
||||
// All Rights Reserved
|
||||
// {fmt} support for ranges, containers and types tuple interface.
|
||||
|
||||
#ifndef FMT_RANGES_H_
|
||||
#define FMT_RANGES_H_
|
||||
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
|
||||
#include "format.h"
|
||||
|
||||
// output only up to N items from the range.
|
||||
#ifndef FMT_RANGE_OUTPUT_LENGTH_LIMIT
|
||||
# define FMT_RANGE_OUTPUT_LENGTH_LIMIT 256
|
||||
#endif
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
template <typename Char> struct formatting_base {
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return ctx.begin();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename Enable = void>
|
||||
struct formatting_range : formatting_base<Char> {
|
||||
static FMT_CONSTEXPR_DECL const size_t range_length_limit =
|
||||
FMT_RANGE_OUTPUT_LENGTH_LIMIT; // output only up to N items from the
|
||||
// range.
|
||||
Char prefix;
|
||||
Char delimiter;
|
||||
Char postfix;
|
||||
formatting_range() : prefix('{'), delimiter(','), postfix('}') {}
|
||||
static FMT_CONSTEXPR_DECL const bool add_delimiter_spaces = true;
|
||||
static FMT_CONSTEXPR_DECL const bool add_prepostfix_space = false;
|
||||
};
|
||||
|
||||
template <typename Char, typename Enable = void>
|
||||
struct formatting_tuple : formatting_base<Char> {
|
||||
Char prefix;
|
||||
Char delimiter;
|
||||
Char postfix;
|
||||
formatting_tuple() : prefix('('), delimiter(','), postfix(')') {}
|
||||
static FMT_CONSTEXPR_DECL const bool add_delimiter_spaces = true;
|
||||
static FMT_CONSTEXPR_DECL const bool add_prepostfix_space = false;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename RangeT, typename OutputIterator>
|
||||
OutputIterator copy(const RangeT& range, OutputIterator out) {
|
||||
for (auto it = range.begin(), end = range.end(); it != end; ++it)
|
||||
*out++ = *it;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename OutputIterator>
|
||||
OutputIterator copy(const char* str, OutputIterator out) {
|
||||
while (*str) *out++ = *str++;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename OutputIterator>
|
||||
OutputIterator copy(char ch, OutputIterator out) {
|
||||
*out++ = ch;
|
||||
return out;
|
||||
}
|
||||
|
||||
/// Return true value if T has std::string interface, like std::string_view.
|
||||
template <typename T> class is_like_std_string {
|
||||
template <typename U>
|
||||
static auto check(U* p)
|
||||
-> decltype((void)p->find('a'), p->length(), (void)p->data(), int());
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
static FMT_CONSTEXPR_DECL const bool value =
|
||||
is_string<T>::value || !std::is_void<decltype(check<T>(nullptr))>::value;
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
struct is_like_std_string<fmt::basic_string_view<Char>> : std::true_type {};
|
||||
|
||||
template <typename... Ts> struct conditional_helper {};
|
||||
|
||||
template <typename T, typename _ = void> struct is_range_ : std::false_type {};
|
||||
|
||||
#if !FMT_MSC_VER || FMT_MSC_VER > 1800
|
||||
template <typename T>
|
||||
struct is_range_<
|
||||
T, conditional_t<false,
|
||||
conditional_helper<decltype(std::declval<T>().begin()),
|
||||
decltype(std::declval<T>().end())>,
|
||||
void>> : std::true_type {};
|
||||
#endif
|
||||
|
||||
/// tuple_size and tuple_element check.
|
||||
template <typename T> class is_tuple_like_ {
|
||||
template <typename U>
|
||||
static auto check(U* p) -> decltype(std::tuple_size<U>::value, int());
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
static FMT_CONSTEXPR_DECL const bool value =
|
||||
!std::is_void<decltype(check<T>(nullptr))>::value;
|
||||
};
|
||||
|
||||
// Check for integer_sequence
|
||||
#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VER >= 1900
|
||||
template <typename T, T... N>
|
||||
using integer_sequence = std::integer_sequence<T, N...>;
|
||||
template <size_t... N> using index_sequence = std::index_sequence<N...>;
|
||||
template <size_t N> using make_index_sequence = std::make_index_sequence<N>;
|
||||
#else
|
||||
template <typename T, T... N> struct integer_sequence {
|
||||
using value_type = T;
|
||||
|
||||
static FMT_CONSTEXPR size_t size() { return sizeof...(N); }
|
||||
};
|
||||
|
||||
template <size_t... N> using index_sequence = integer_sequence<size_t, N...>;
|
||||
|
||||
template <typename T, size_t N, T... Ns>
|
||||
struct make_integer_sequence : make_integer_sequence<T, N - 1, N - 1, Ns...> {};
|
||||
template <typename T, T... Ns>
|
||||
struct make_integer_sequence<T, 0, Ns...> : integer_sequence<T, Ns...> {};
|
||||
|
||||
template <size_t N>
|
||||
using make_index_sequence = make_integer_sequence<size_t, N>;
|
||||
#endif
|
||||
|
||||
template <class Tuple, class F, size_t... Is>
|
||||
void for_each(index_sequence<Is...>, Tuple&& tup, F&& f) FMT_NOEXCEPT {
|
||||
using std::get;
|
||||
// using free function get<I>(T) now.
|
||||
const int _[] = {0, ((void)f(get<Is>(tup)), 0)...};
|
||||
(void)_; // blocks warnings
|
||||
}
|
||||
|
||||
template <class T>
|
||||
FMT_CONSTEXPR make_index_sequence<std::tuple_size<T>::value> get_indexes(
|
||||
T const&) {
|
||||
return {};
|
||||
}
|
||||
|
||||
template <class Tuple, class F> void for_each(Tuple&& tup, F&& f) {
|
||||
const auto indexes = get_indexes(tup);
|
||||
for_each(indexes, std::forward<Tuple>(tup), std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <typename Arg, FMT_ENABLE_IF(!is_like_std_string<
|
||||
typename std::decay<Arg>::type>::value)>
|
||||
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&) {
|
||||
return add_space ? " {}" : "{}";
|
||||
}
|
||||
|
||||
template <typename Arg, FMT_ENABLE_IF(is_like_std_string<
|
||||
typename std::decay<Arg>::type>::value)>
|
||||
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&) {
|
||||
return add_space ? " \"{}\"" : "\"{}\"";
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const char*) {
|
||||
return add_space ? " \"{}\"" : "\"{}\"";
|
||||
}
|
||||
FMT_CONSTEXPR const wchar_t* format_str_quoted(bool add_space, const wchar_t*) {
|
||||
return add_space ? L" \"{}\"" : L"\"{}\"";
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const char) {
|
||||
return add_space ? " '{}'" : "'{}'";
|
||||
}
|
||||
FMT_CONSTEXPR const wchar_t* format_str_quoted(bool add_space, const wchar_t) {
|
||||
return add_space ? L" '{}'" : L"'{}'";
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T> struct is_tuple_like {
|
||||
static FMT_CONSTEXPR_DECL const bool value =
|
||||
detail::is_tuple_like_<T>::value && !detail::is_range_<T>::value;
|
||||
};
|
||||
|
||||
template <typename TupleT, typename Char>
|
||||
struct formatter<TupleT, Char, enable_if_t<fmt::is_tuple_like<TupleT>::value>> {
|
||||
private:
|
||||
// C++11 generic lambda for format()
|
||||
template <typename FormatContext> struct format_each {
|
||||
template <typename T> void operator()(const T& v) {
|
||||
if (i > 0) {
|
||||
if (formatting.add_prepostfix_space) {
|
||||
*out++ = ' ';
|
||||
}
|
||||
out = detail::copy(formatting.delimiter, out);
|
||||
}
|
||||
out = format_to(out,
|
||||
detail::format_str_quoted(
|
||||
(formatting.add_delimiter_spaces && i > 0), v),
|
||||
v);
|
||||
++i;
|
||||
}
|
||||
|
||||
formatting_tuple<Char>& formatting;
|
||||
size_t& i;
|
||||
typename std::add_lvalue_reference<decltype(
|
||||
std::declval<FormatContext>().out())>::type out;
|
||||
};
|
||||
|
||||
public:
|
||||
formatting_tuple<Char> formatting;
|
||||
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return formatting.parse(ctx);
|
||||
}
|
||||
|
||||
template <typename FormatContext = format_context>
|
||||
auto format(const TupleT& values, FormatContext& ctx) -> decltype(ctx.out()) {
|
||||
auto out = ctx.out();
|
||||
size_t i = 0;
|
||||
detail::copy(formatting.prefix, out);
|
||||
|
||||
detail::for_each(values, format_each<FormatContext>{formatting, i, out});
|
||||
if (formatting.add_prepostfix_space) {
|
||||
*out++ = ' ';
|
||||
}
|
||||
detail::copy(formatting.postfix, out);
|
||||
|
||||
return ctx.out();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Char> struct is_range {
|
||||
static FMT_CONSTEXPR_DECL const bool value =
|
||||
detail::is_range_<T>::value && !detail::is_like_std_string<T>::value &&
|
||||
!std::is_convertible<T, std::basic_string<Char>>::value &&
|
||||
!std::is_constructible<detail::std_string_view<Char>, T>::value;
|
||||
};
|
||||
|
||||
template <typename RangeT, typename Char>
|
||||
struct formatter<RangeT, Char,
|
||||
enable_if_t<fmt::is_range<RangeT, Char>::value>> {
|
||||
formatting_range<Char> formatting;
|
||||
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return formatting.parse(ctx);
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
typename FormatContext::iterator format(const RangeT& values,
|
||||
FormatContext& ctx) {
|
||||
auto out = detail::copy(formatting.prefix, ctx.out());
|
||||
size_t i = 0;
|
||||
auto it = values.begin();
|
||||
auto end = values.end();
|
||||
for (; it != end; ++it) {
|
||||
if (i > 0) {
|
||||
if (formatting.add_prepostfix_space) *out++ = ' ';
|
||||
out = detail::copy(formatting.delimiter, out);
|
||||
}
|
||||
out = format_to(out,
|
||||
detail::format_str_quoted(
|
||||
(formatting.add_delimiter_spaces && i > 0), *it),
|
||||
*it);
|
||||
if (++i > formatting.range_length_limit) {
|
||||
out = format_to(out, " ... <other elements>");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (formatting.add_prepostfix_space) *out++ = ' ';
|
||||
return detail::copy(formatting.postfix, out);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename... T> struct tuple_arg_join : detail::view {
|
||||
const std::tuple<T...>& tuple;
|
||||
basic_string_view<Char> sep;
|
||||
|
||||
tuple_arg_join(const std::tuple<T...>& t, basic_string_view<Char> s)
|
||||
: tuple{t}, sep{s} {}
|
||||
};
|
||||
|
||||
template <typename Char, typename... T>
|
||||
struct formatter<tuple_arg_join<Char, T...>, Char> {
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
typename FormatContext::iterator format(
|
||||
const tuple_arg_join<Char, T...>& value, FormatContext& ctx) {
|
||||
return format(value, ctx, detail::make_index_sequence<sizeof...(T)>{});
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename FormatContext, size_t... N>
|
||||
typename FormatContext::iterator format(
|
||||
const tuple_arg_join<Char, T...>& value, FormatContext& ctx,
|
||||
detail::index_sequence<N...>) {
|
||||
return format_args(value, ctx, std::get<N>(value.tuple)...);
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
typename FormatContext::iterator format_args(
|
||||
const tuple_arg_join<Char, T...>&, FormatContext& ctx) {
|
||||
// NOTE: for compilers that support C++17, this empty function instantiation
|
||||
// can be replaced with a constexpr branch in the variadic overload.
|
||||
return ctx.out();
|
||||
}
|
||||
|
||||
template <typename FormatContext, typename Arg, typename... Args>
|
||||
typename FormatContext::iterator format_args(
|
||||
const tuple_arg_join<Char, T...>& value, FormatContext& ctx,
|
||||
const Arg& arg, const Args&... args) {
|
||||
using base = formatter<typename std::decay<Arg>::type, Char>;
|
||||
auto out = ctx.out();
|
||||
out = base{}.format(arg, ctx);
|
||||
if (sizeof...(Args) > 0) {
|
||||
out = std::copy(value.sep.begin(), value.sep.end(), out);
|
||||
ctx.advance_to(out);
|
||||
return format_args(value, ctx, args...);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
\rst
|
||||
Returns an object that formats `tuple` with elements separated by `sep`.
|
||||
|
||||
**Example**::
|
||||
|
||||
std::tuple<int, char> t = {1, 'a'};
|
||||
fmt::print("{}", fmt::join(t, ", "));
|
||||
// Output: "1, a"
|
||||
\endrst
|
||||
*/
|
||||
template <typename... T>
|
||||
FMT_CONSTEXPR tuple_arg_join<char, T...> join(const std::tuple<T...>& tuple,
|
||||
string_view sep) {
|
||||
return {tuple, sep};
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
FMT_CONSTEXPR tuple_arg_join<wchar_t, T...> join(const std::tuple<T...>& tuple,
|
||||
wstring_view sep) {
|
||||
return {tuple, sep};
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Returns an object that formats `initializer_list` with elements separated by
|
||||
`sep`.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::print("{}", fmt::join({1, 2, 3}, ", "));
|
||||
// Output: "1, 2, 3"
|
||||
\endrst
|
||||
*/
|
||||
template <typename T>
|
||||
arg_join<const T*, const T*, char> join(std::initializer_list<T> list,
|
||||
string_view sep) {
|
||||
return join(std::begin(list), std::end(list), sep);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
arg_join<const T*, const T*, wchar_t> join(std::initializer_list<T> list,
|
||||
wstring_view sep) {
|
||||
return join(std::begin(list), std::end(list), sep);
|
||||
}
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_RANGES_H_
|
4
external/resinsight/LibCore/cvfArray.h
vendored
4
external/resinsight/LibCore/cvfArray.h
vendored
@ -72,13 +72,13 @@ public:
|
||||
void assign(const std::vector<T>& data);
|
||||
void resize(size_t size);
|
||||
void clear();
|
||||
inline size_t size() const override;
|
||||
inline virtual size_t size() const;
|
||||
|
||||
inline void set(size_t index, const T& val);
|
||||
inline void setAll(const T& val);
|
||||
inline void setConsecutive(const T& startVal);
|
||||
inline const T& get(size_t index) const;
|
||||
inline T val(size_t index) const override;
|
||||
inline virtual T val(size_t index) const;
|
||||
|
||||
inline const T* ptr() const;
|
||||
inline T* ptr();
|
||||
|
6
external/resinsight/LibCore/cvfAssert.cpp
vendored
6
external/resinsight/LibCore/cvfAssert.cpp
vendored
@ -46,9 +46,7 @@ namespace cvf {
|
||||
|
||||
// User actions (interactive responses)
|
||||
static const int USERACTION_CONTINUE = 0;
|
||||
#ifdef WIN32
|
||||
static const int USERACTION_DEBUGBREAK = 1;
|
||||
#endif
|
||||
static const int USERACTION_ABORT = 2;
|
||||
|
||||
|
||||
@ -81,7 +79,7 @@ public:
|
||||
class AssertHandlerConsole : public AssertHandler
|
||||
{
|
||||
public:
|
||||
Assert::FailAction handleAssert(const char* fileName, int lineNumber, const char* expr, const char* msg) override;
|
||||
virtual Assert::FailAction handleAssert(const char* fileName, int lineNumber, const char* expr, const char* msg);
|
||||
|
||||
private:
|
||||
static void reportToConsole(const char* fileName, int lineNumber, const char* expr, const char* msg);
|
||||
@ -272,7 +270,7 @@ void AssertHandlerConsole::winCreateConsoleAndRedirectIO(bool redirectInput)
|
||||
class AssertHandlerWinDialog : public AssertHandler
|
||||
{
|
||||
public:
|
||||
Assert::FailAction handleAssert(const char* fileName, int lineNumber, const char* expr, const char* msg) override;
|
||||
virtual Assert::FailAction handleAssert(const char* fileName, int lineNumber, const char* expr, const char* msg);
|
||||
|
||||
private:
|
||||
static int handleUsingDialog(const char* fileName, int lineNumber, const char* expr, const char* msg);
|
||||
|
4
external/resinsight/LibCore/cvfColor3.h
vendored
4
external/resinsight/LibCore/cvfColor3.h
vendored
@ -112,7 +112,7 @@ public:
|
||||
Color3f();
|
||||
Color3f(float r, float g, float b);
|
||||
Color3f(const Color3f& other);
|
||||
explicit Color3f(ColorIdent colorIdent);
|
||||
Color3f(ColorIdent colorIdent);
|
||||
explicit Color3f(const Color3ub& other);
|
||||
|
||||
Color3f& operator=(const Color3f& rhs);
|
||||
@ -158,7 +158,7 @@ public:
|
||||
Color3ub();
|
||||
Color3ub(ubyte r, ubyte g, ubyte b);
|
||||
Color3ub(const Color3ub& other);
|
||||
explicit Color3ub(ColorIdent colorIdent);
|
||||
Color3ub(ColorIdent colorIdent);
|
||||
explicit Color3ub(const Color3f& other);
|
||||
|
||||
Color3ub& operator=(const Color3ub& rhs);
|
||||
|
2
external/resinsight/LibCore/cvfDebugTimer.h
vendored
2
external/resinsight/LibCore/cvfDebugTimer.h
vendored
@ -60,7 +60,7 @@ public:
|
||||
};
|
||||
|
||||
public:
|
||||
explicit DebugTimer(const char* prefix, OperationMode operationMode = NORMAL);
|
||||
DebugTimer(const char* prefix, OperationMode operationMode = NORMAL);
|
||||
~DebugTimer();
|
||||
|
||||
void restart(const char* msg = NULL);
|
||||
|
2
external/resinsight/LibCore/cvfFlags.h
vendored
2
external/resinsight/LibCore/cvfFlags.h
vendored
@ -52,7 +52,7 @@ class Flags
|
||||
public:
|
||||
inline Flags();
|
||||
inline Flags(const Flags& other);
|
||||
explicit inline Flags(FlagEnum flag);
|
||||
inline Flags(FlagEnum flag);
|
||||
|
||||
inline Flags& operator=(const Flags& rhs);
|
||||
inline Flags& operator=(FlagEnum flag);
|
||||
|
4
external/resinsight/LibCore/cvfObject.h
vendored
4
external/resinsight/LibCore/cvfObject.h
vendored
@ -99,7 +99,7 @@ class ref
|
||||
public:
|
||||
ref(T* object = NULL);
|
||||
ref(const ref& other);
|
||||
template<typename T2> explicit ref(const ref<T2>& other);
|
||||
template<typename T2> ref(const ref<T2>& other);
|
||||
~ref();
|
||||
|
||||
ref& operator=(T* rhs);
|
||||
@ -150,7 +150,7 @@ class cref
|
||||
public:
|
||||
cref(const T* object = NULL);
|
||||
cref(const cref& other);
|
||||
template<typename T2> explicit cref(const cref<T2>& other);
|
||||
template<typename T2> cref(const cref<T2>& other);
|
||||
~cref();
|
||||
|
||||
cref& operator=(const T* rhs);
|
||||
|
2
external/resinsight/LibCore/cvfPlane.cpp
vendored
2
external/resinsight/LibCore/cvfPlane.cpp
vendored
@ -374,7 +374,7 @@ bool Plane::intersect(const Plane& other, Vec3d* point, Vec3d* direction) const
|
||||
|
||||
CVF_ASSERT(point);
|
||||
|
||||
double invdet;
|
||||
double invdet = UNDEFINED_DOUBLE;
|
||||
|
||||
Vec3d normal1 = this->normal();
|
||||
Vec3d normal2 = other.normal();
|
||||
|
8
external/resinsight/LibCore/cvfTrace.cpp
vendored
8
external/resinsight/LibCore/cvfTrace.cpp
vendored
@ -72,7 +72,7 @@ namespace cvf {
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Write debug text to console, DevStudio output window and file (future)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Trace::show(const String& message)
|
||||
void Trace::show(String message)
|
||||
{
|
||||
showTraceOutput(message, true);
|
||||
}
|
||||
@ -88,7 +88,7 @@ void Trace::show(const char* format, ...)
|
||||
va_list argList;
|
||||
va_start(argList, format);
|
||||
|
||||
constexpr int maxFormatLength = 4000;
|
||||
const int maxFormatLength = 4000;
|
||||
char temp[maxFormatLength + 1];
|
||||
|
||||
#ifdef WIN32
|
||||
@ -96,7 +96,7 @@ void Trace::show(const char* format, ...)
|
||||
#elif defined(CVF_ANDROID)
|
||||
__android_log_print(ANDROID_LOG_DEBUG, "CVF_TAG", format, argList);
|
||||
#else
|
||||
vsnprintf(temp, maxFormatLength, format, argList);
|
||||
vsprintf(temp, format, argList);
|
||||
#endif
|
||||
|
||||
va_end(argList);
|
||||
@ -124,7 +124,7 @@ void Trace::showFileLineNumber(const String& file, int line, const String& messa
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Show the trace output in console and DevStudio output window
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void Trace::showTraceOutput(const String& text, bool addNewLine)
|
||||
void Trace::showTraceOutput(String text, bool addNewLine)
|
||||
{
|
||||
#ifdef WIN32
|
||||
AllocConsole();
|
||||
|
4
external/resinsight/LibCore/cvfTrace.h
vendored
4
external/resinsight/LibCore/cvfTrace.h
vendored
@ -51,12 +51,12 @@ namespace cvf {
|
||||
class Trace
|
||||
{
|
||||
public:
|
||||
static void show(const String& message);
|
||||
static void show(String message);
|
||||
static void show(const char* format, ...);
|
||||
static void showFileLineNumber(const String& file, int line, const String& message);
|
||||
|
||||
private:
|
||||
static void showTraceOutput(const String& text, bool addNewLine);
|
||||
static void showTraceOutput(String text, bool addNewLine);
|
||||
};
|
||||
|
||||
|
||||
|
1
external/resinsight/LibCore/cvfVector3.cpp
vendored
1
external/resinsight/LibCore/cvfVector3.cpp
vendored
@ -22,6 +22,7 @@
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfVector3.h"
|
||||
|
||||
namespace external {
|
||||
|
5
external/resinsight/LibCore/cvfVector3.h
vendored
5
external/resinsight/LibCore/cvfVector3.h
vendored
@ -158,11 +158,6 @@ typedef Vector3<int> Vec3i; ///< A vector with int components
|
||||
typedef Vector3<uint> Vec3ui; ///< A vector with uint components
|
||||
typedef Vector3<size_t> Vec3st; ///< A vector with size_t components
|
||||
|
||||
template<> Vec3d const Vec3d::UNDEFINED;
|
||||
template<> Vec3f const Vec3f::UNDEFINED;
|
||||
template<> Vec3i const Vec3i::UNDEFINED;
|
||||
template<> Vec3st const Vec3st::UNDEFINED;
|
||||
|
||||
}
|
||||
} //namespace external
|
||||
#include "cvfVector3.inl"
|
||||
|
2
external/resinsight/LibCore/cvfVector4.inl
vendored
2
external/resinsight/LibCore/cvfVector4.inl
vendored
@ -491,7 +491,7 @@ inline void Vector4<S>::setZero()
|
||||
template<typename S>
|
||||
inline bool Vector4<S>::isZero() const
|
||||
{
|
||||
return (m_v[0] == 0) && (m_v[1] == 0) && (m_v[2] == 0) && (m_v[3] == 0);
|
||||
return (m_v[0] == 0) && (m_v[1] == 0) && (m_v[2] == 0) && (m_v[2] == 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -243,6 +243,7 @@ int largestComponent(const cvf::Vec3d v)
|
||||
|
||||
if (v.z() > maxLength)
|
||||
{
|
||||
maxLength = v.z();
|
||||
idx = 2;
|
||||
}
|
||||
|
||||
@ -786,11 +787,8 @@ void AABBTree::deleteInternalNodesBottomUp(AABBTreeNode* node)
|
||||
auto internalNode = dynamic_cast<AABBTreeNodeInternal*>(node);
|
||||
CVF_ASSERT(internalNode);
|
||||
|
||||
if (internalNode)
|
||||
{
|
||||
AABBTree::deleteInternalNodesBottomUp(internalNode->left());
|
||||
AABBTree::deleteInternalNodesBottomUp(internalNode->right());
|
||||
}
|
||||
AABBTree::deleteInternalNodesBottomUp(internalNode->left());
|
||||
AABBTree::deleteInternalNodesBottomUp(internalNode->right());
|
||||
|
||||
delete internalNode;
|
||||
}
|
||||
|
10
external/resinsight/LibGeometry/cvfRay.cpp
vendored
10
external/resinsight/LibGeometry/cvfRay.cpp
vendored
@ -283,8 +283,8 @@ bool Ray::boxIntersect(const BoundingBox& box, Vec3d* intersectionPoint) const
|
||||
|
||||
// Find candidate planes; this loop can be avoided if rays cast all from the eye(assume perpsective view)
|
||||
bool inside = true;
|
||||
char quadrant[3]{};
|
||||
double candidatePlane[3] = {0.0, 0.0, 0.0};
|
||||
char quadrant[3];
|
||||
double candidatePlane[3];
|
||||
|
||||
Vec3d min = box.min();
|
||||
Vec3d max = box.max();
|
||||
@ -320,13 +320,17 @@ bool Ray::boxIntersect(const BoundingBox& box, Vec3d* intersectionPoint) const
|
||||
}
|
||||
|
||||
// Calculate T distances to candidate planes
|
||||
double maxT[3]{-1.0f, -1.0f, -1.0f};
|
||||
double maxT[3];
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (quadrant[i] != MIDDLE && m_direction[i] !=0.0f)
|
||||
{
|
||||
maxT[i] = (candidatePlane[i] - m_origin[i]) / m_direction[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
maxT[i] = -1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Get largest of the maxT's for final choice of intersection
|
||||
|
@ -30,9 +30,9 @@ namespace external {
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWellPath::RigWellPath()
|
||||
: cvf::Object()
|
||||
, objectBeingDeleted( this )
|
||||
, m_hasDatumElevation( false )
|
||||
, m_datumElevation( 0.0 )
|
||||
, objectBeingDeleted( this )
|
||||
, m_uniqueStartIndex( 0u )
|
||||
, m_uniqueEndIndex( std::numeric_limits<size_t>::max() )
|
||||
{
|
||||
@ -43,13 +43,13 @@ RigWellPath::RigWellPath()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWellPath::RigWellPath( const RigWellPath& rhs )
|
||||
: cvf::Object()
|
||||
, objectBeingDeleted( this )
|
||||
, m_wellPathPoints( rhs.m_wellPathPoints )
|
||||
, m_measuredDepths( rhs.m_measuredDepths )
|
||||
, m_hasDatumElevation( rhs.m_hasDatumElevation )
|
||||
, m_datumElevation( rhs.m_datumElevation )
|
||||
, m_uniqueStartIndex( rhs.m_uniqueStartIndex )
|
||||
, m_uniqueEndIndex( rhs.m_uniqueEndIndex )
|
||||
, objectBeingDeleted( this )
|
||||
{
|
||||
CVF_ASSERT( m_wellPathPoints.size() == m_measuredDepths.size() );
|
||||
}
|
||||
@ -59,12 +59,12 @@ RigWellPath::RigWellPath( const RigWellPath& rhs )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWellPath::RigWellPath( const std::vector<cvf::Vec3d>& wellPathPoints, const std::vector<double>& measuredDepths )
|
||||
: cvf::Object()
|
||||
, objectBeingDeleted( this )
|
||||
, m_wellPathPoints( wellPathPoints )
|
||||
, m_measuredDepths( measuredDepths )
|
||||
, m_hasDatumElevation( false )
|
||||
, m_datumElevation( 0.0 )
|
||||
, m_uniqueStartIndex( 0u )
|
||||
, objectBeingDeleted( this )
|
||||
, m_uniqueEndIndex( std::numeric_limits<size_t>::max() )
|
||||
{
|
||||
CVF_ASSERT( m_wellPathPoints.size() == m_measuredDepths.size() );
|
||||
|
@ -166,7 +166,7 @@ bool HexGridIntersectionTools::planeTriangleIntersection( const cvf::Plane& plan
|
||||
if ( onPosSide[2] ) topVx = 3;
|
||||
|
||||
// Case 3a: Two negative distances and the last is within tolerance of zero.
|
||||
if ( topVx > 0 && sqrSignedDistances[topVx - 1] < sqrDistanceTolerance )
|
||||
if ( sqrSignedDistances[topVx - 1] < sqrDistanceTolerance )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -178,7 +178,7 @@ bool HexGridIntersectionTools::planeTriangleIntersection( const cvf::Plane& plan
|
||||
if ( !onPosSide[2] ) topVx = 3;
|
||||
|
||||
// Case 3a: Two positive distances and the last is within tolerance of zero.
|
||||
if ( topVx > 0 && sqrSignedDistances[topVx - 1] > -sqrDistanceTolerance )
|
||||
if ( sqrSignedDistances[topVx - 1] > -sqrDistanceTolerance )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -1084,7 +1084,7 @@ int HexGridIntersectionTools::planeHexIntersectionMC( const cvf::Plane& plane
|
||||
}
|
||||
|
||||
cvf::Vec3d edgeIntersections[12];
|
||||
double normDistAlongEdge[12]{};
|
||||
double normDistAlongEdge[12];
|
||||
|
||||
// Compute vertex coordinates on the edges where we have intersections
|
||||
if ( cubeIdxToCutEdgeBitfield[cubeIndex] & 1 )
|
||||
|
2
external/resinsight/cafPdmCore/cafSignal.h
vendored
2
external/resinsight/cafPdmCore/cafSignal.h
vendored
@ -108,7 +108,7 @@ public:
|
||||
using MemberCallbackAndActiveFlag = std::pair<MemberCallback, bool>;
|
||||
|
||||
public:
|
||||
explicit Signal( const SignalEmitter* emitter )
|
||||
Signal( const SignalEmitter* emitter )
|
||||
: m_emitter( emitter )
|
||||
{
|
||||
m_emitter->addEmittedSignal( this );
|
||||
|
@ -123,9 +123,9 @@ function build_module {
|
||||
TESTTHREADS=${TESTTHREADS:-1}
|
||||
if test -z "$CTEST_CONFIGURATION"
|
||||
then
|
||||
ctest -T Test --no-compress-output -j$TESTTHREADS -LE "gpu_.*"
|
||||
ctest -T Test --no-compress-output -j$TESTTHREADS
|
||||
else
|
||||
ctest -j$TESTTHREADS -C $CTEST_CONFIGURATION --timeout 5000 -T Test --no-compress-output -LE "gpu_.*"
|
||||
ctest -j$TESTTHREADS -C $CTEST_CONFIGURATION --timeout 5000 -T Test --no-compress-output
|
||||
fi
|
||||
|
||||
# Convert to junit format
|
||||
|
@ -45,10 +45,7 @@ private:
|
||||
|
||||
void run_step(WellTestState& wtest_state, UDQState& udq_state, data::Solution& sol, data::Wells& well_data, data::GroupAndNetworkValues& group_nwrk_data, size_t report_step, EclipseIO& io);
|
||||
void run_step(WellTestState& wtest_state, UDQState& udq_state, data::Solution& sol, data::Wells& well_data, data::GroupAndNetworkValues& group_nwrk_data, size_t report_step, double dt, EclipseIO& io);
|
||||
void output(const WellTestState& wtest_state, const UDQState& udq_state,
|
||||
size_t report_step, bool substep, double seconds_elapsed,
|
||||
const data::Solution& sol, const data::Wells& well_data,
|
||||
const data::GroupAndNetworkValues& group_data, EclipseIO& io);
|
||||
void output(WellTestState& wtest_state, const UDQState& udq_state, size_t report_step, bool substep, double seconds_elapsed, const data::Solution& sol, const data::Wells& well_data, const data::GroupAndNetworkValues& group_data, EclipseIO& io);
|
||||
void simulate(data::Solution& sol, data::Wells& well_data, data::GroupAndNetworkValues& group_nwrk_data, size_t report_step, double seconds_elapsed, double time_step);
|
||||
|
||||
EclipseState state;
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <opm/input/eclipse/Schedule/Action/SimulatorUpdate.hpp>
|
||||
#include <opm/input/eclipse/Schedule/UDQ/UDQState.hpp>
|
||||
#include <opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/PAvgCalculatorCollection.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/Well.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/WellMatcher.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/WellTestState.hpp>
|
||||
@ -121,19 +122,13 @@ void msim::run_step(WellTestState& wtest_state, UDQState& udq_state, data::Solut
|
||||
report_step,
|
||||
seconds_elapsed,
|
||||
well_data,
|
||||
/* wbp = */ {},
|
||||
group_nwrk_data,
|
||||
/* sing_values = */ {},
|
||||
/* initial_inplace = */ {},
|
||||
/* inplace = */ {});
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{});
|
||||
|
||||
this->schedule.getUDQConfig(report_step - 1)
|
||||
.eval(report_step,
|
||||
this->schedule,
|
||||
this->schedule.wellMatcher(report_step),
|
||||
this->schedule.segmentMatcherFactory(report_step),
|
||||
this->st,
|
||||
udq_state);
|
||||
this->schedule.getUDQConfig( report_step ).eval(report_step, schedule.wellMatcher(report_step), this->st, udq_state);
|
||||
|
||||
this->output(wtest_state,
|
||||
udq_state,
|
||||
@ -149,10 +144,7 @@ void msim::run_step(WellTestState& wtest_state, UDQState& udq_state, data::Solut
|
||||
|
||||
|
||||
|
||||
void msim::output(const WellTestState& wtest_state, const UDQState& udq_state,
|
||||
size_t report_step, bool substep, double seconds_elapsed,
|
||||
const data::Solution& sol, const data::Wells& well_data,
|
||||
const data::GroupAndNetworkValues& group_nwrk_data, EclipseIO& io) {
|
||||
void msim::output(WellTestState& wtest_state, const UDQState& udq_state, size_t report_step, bool substep, double seconds_elapsed, const data::Solution& sol, const data::Wells& well_data, const data::GroupAndNetworkValues& group_nwrk_data, EclipseIO& io) {
|
||||
RestartValue value(sol, well_data, group_nwrk_data, {});
|
||||
io.writeTimeStep(this->action_state,
|
||||
wtest_state,
|
||||
|
@ -66,13 +66,6 @@ public:
|
||||
: NumericalProblem(message)
|
||||
{}
|
||||
};
|
||||
class TimeSteppingBreakdown : public NumericalProblem
|
||||
{
|
||||
public:
|
||||
explicit TimeSteppingBreakdown(const std::string &message)
|
||||
: NumericalProblem(message)
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // OPM_EXCEPTIONS_HPP
|
||||
|
@ -19,27 +19,8 @@
|
||||
#ifndef OPM_TIMINGMACROS_HPP
|
||||
#define OPM_TIMINGMACROS_HPP
|
||||
|
||||
// This file defines macros
|
||||
// OPM_TIMEBLOCK - time block of main part of codes which do not effect performance
|
||||
// OPM_TIMEFUNCTION - time block of main part of codes which do not effect performance with name from function
|
||||
// OPM_TIMEBLOCK_LOCAL - detailed timing which may effect performance
|
||||
// OPM_TIMEFUNCTION_LOCAL - detailed timing which may effect performance with name from function
|
||||
|
||||
#ifndef DETAILED_PROFILING
|
||||
#define DETAILED_PROFILING 0 // set to 1 to enable invasive profiling
|
||||
#endif
|
||||
|
||||
#if USE_TRACY
|
||||
#define TRACY_ENABLE 1
|
||||
#include <tracy/Tracy.hpp>
|
||||
#define OPM_TIMEBLOCK(blockname) ZoneNamedN(blockname, #blockname, true)
|
||||
#define OPM_TIMEFUNCTION() ZoneNamedN(myname, __func__, true)
|
||||
#if DETAILED_PROFILING
|
||||
#define OPM_TIMEBLOCK_LOCAL(blockname) ZoneNamedN(blockname, #blockname, true)
|
||||
#define OPM_TIMEFUNCTION_LOCAL() ZoneNamedN(myname, __func__, true)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// macros used to time blocks for example with tracy
|
||||
// time block of main part of codes which do not effect performance
|
||||
#ifndef OPM_TIMEBLOCK
|
||||
#define OPM_TIMEBLOCK(x)\
|
||||
do { /* nothing */ } while (false)
|
||||
@ -51,14 +32,4 @@
|
||||
do { /* nothing */ } while (false)
|
||||
#endif
|
||||
|
||||
#ifndef OPM_TIMEFUNCTION
|
||||
#define OPM_TIMEFUNCTION()\
|
||||
do { /* nothing */ } while (false)
|
||||
#endif
|
||||
|
||||
#ifndef OPM_TIMEFUNCTION_LOCAL
|
||||
#define OPM_TIMEFUNCTION_LOCAL()\
|
||||
do { /* nothing */ } while (false)
|
||||
#endif
|
||||
|
||||
#endif // OPM_TIMINGMACROS_HPP
|
||||
|
@ -1,532 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 SINTEF ICT, Applied Mathematics.
|
||||
Copyright 2016 Statoil ASA.
|
||||
Copyright 2022 Equinor ASA
|
||||
|
||||
This file is part of the Open Porous Media Project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_UTILITY_CSRGRAPHFROMCOORDINATES_HPP
|
||||
#define OPM_UTILITY_CSRGRAPHFROMCOORDINATES_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
/// \file
|
||||
///
|
||||
/// Facility for converting collection of region ID pairs into a sparse
|
||||
/// (CSR) adjacency matrix representation of a graph. Supports O(nnz)
|
||||
/// compression.
|
||||
|
||||
namespace Opm { namespace utility {
|
||||
|
||||
/// Form CSR adjacency matrix representation of unstructured graphs.
|
||||
/// Optionally maps vertex pairs to compressed indices to enable O(1)
|
||||
/// per-element lookup in assembly-like operations.
|
||||
///
|
||||
/// \tparam VertexID ID type of an abstract vertex in the graph. Could
|
||||
/// for instance be used to represent a cell index or a region index.
|
||||
/// Must be an integral type.
|
||||
///
|
||||
/// \tparam TrackCompressedIdx Whether or not to form a mapping relation
|
||||
/// for vertex pairs to compressed indices. Default value, false,
|
||||
/// bypasses this mapping relation and conserves memory.
|
||||
///
|
||||
/// \tparam PermitSelfConnections Whether or not to allow connections of
|
||||
/// the form i->i--i.e., diagonal elements. Default value, \c false,
|
||||
/// does not generate connections from a vertex to itself.
|
||||
template <typename VertexID = int, bool TrackCompressedIdx = false, bool PermitSelfConnections = false>
|
||||
class CSRGraphFromCoordinates
|
||||
{
|
||||
private:
|
||||
using BaseVertexID = std::remove_cv_t<VertexID>;
|
||||
|
||||
static_assert(std::is_integral_v<BaseVertexID>,
|
||||
"The VertexID must be an integral type");
|
||||
|
||||
public:
|
||||
/// Representation of neighbouring regions.
|
||||
using Neighbours = std::vector<BaseVertexID>;
|
||||
|
||||
/// Offset into neighbour array.
|
||||
using Offset = typename Neighbours::size_type;
|
||||
|
||||
/// CSR start pointers.
|
||||
using Start = std::vector<Offset>;
|
||||
|
||||
/// Clear all internal buffers, but preserve allocated capacity.
|
||||
void clear();
|
||||
|
||||
/// Add flow rate connection between regions.
|
||||
///
|
||||
/// \param[in] v1 First vertex in vertex pair. Used as row index.
|
||||
///
|
||||
/// \param[in] v2 Second vertex in vertex pair. Used as column index.
|
||||
///
|
||||
/// If both vertex IDs are the same, and class template argument \c
|
||||
/// PermitSelfConnections is in its default state of \c false, then
|
||||
/// this function does nothing.
|
||||
void addConnection(VertexID v1, VertexID v2);
|
||||
|
||||
/// Form CSR adjacency matrix representation of input graph from
|
||||
/// connections established in previous calls to addConnection().
|
||||
///
|
||||
/// \param[in] maxNumVertices Number of rows in resulting CSR
|
||||
/// matrix. If prior calls to addConnection() supply vertex IDs
|
||||
/// (row indices) greater than or equal to \p maxNumVertices,
|
||||
/// then method compress() will throw \code
|
||||
/// std::invalid_argument \endcode.
|
||||
///
|
||||
/// \param[in] expandExistingIdxMap Whether or not preserve and
|
||||
/// update the existing compressed index map. This is
|
||||
/// potentially useful for the case of adding new connections to
|
||||
/// an already compressed graph. The default setting, \c false,
|
||||
/// will disregard any existing index map and create the index
|
||||
/// map from scratch. This runtime parameter is unused if the
|
||||
/// class is not configured to track compressed indices through
|
||||
/// the TrackCompressedIdx class parameter.
|
||||
void compress(Offset maxNumVertices,
|
||||
bool expandExistingIdxMap = false);
|
||||
|
||||
/// Retrieve number of rows (source entities) in input graph.
|
||||
/// Corresponds to value of argument passed to compress(). Valid
|
||||
/// only after calling compress().
|
||||
Offset numVertices() const;
|
||||
|
||||
/// Retrieve number of edges (non-zero matrix elements) in input
|
||||
/// graph.
|
||||
Offset numEdges() const;
|
||||
|
||||
/// Read-only access to compressed structure's start pointers.
|
||||
const Start& startPointers() const
|
||||
{
|
||||
return this->csr_.startPointers();
|
||||
}
|
||||
|
||||
/// Read-only access to compressed structure's column indices,
|
||||
/// ascendingly sorted per row.
|
||||
const Neighbours& columnIndices() const
|
||||
{
|
||||
return this->csr_.columnIndices();
|
||||
}
|
||||
|
||||
/// Read-only access to mapping from input order vertex pairs to
|
||||
/// compressed structure's edge index (location in ja/sa).
|
||||
///
|
||||
/// Available only if client code sets TrackCompressedIdx=true.
|
||||
/// Compiler diagnostic, typically referring to 'enable_if', if
|
||||
/// client code tries to call this function without setting
|
||||
/// class parameter TrackCompressedIdx=true.
|
||||
template <typename Ret = const Start&>
|
||||
std::enable_if_t<TrackCompressedIdx, Ret> compressedIndexMap() const
|
||||
{
|
||||
return this->csr_.compressedIndexMap();
|
||||
}
|
||||
|
||||
// MessageBufferType API should be similar to Dune::MessageBufferIF
|
||||
template <class MessageBufferType>
|
||||
void write(MessageBufferType& buffer) const
|
||||
{
|
||||
this->csr_.write(buffer);
|
||||
}
|
||||
|
||||
// MessageBufferType API should be similar to Dune::MessageBufferIF
|
||||
template <class MessageBufferType>
|
||||
void read(MessageBufferType& buffer)
|
||||
{
|
||||
auto other = CSR{};
|
||||
other.read(buffer);
|
||||
|
||||
this->uncompressed_
|
||||
.add(other.maxRowID(),
|
||||
other.maxColID(),
|
||||
other.coordinateFormatRowIndices(),
|
||||
other.columnIndices());
|
||||
}
|
||||
|
||||
private:
|
||||
/// Coordinate format representation of individual contributions to
|
||||
/// inter-region flows.
|
||||
class Connections
|
||||
{
|
||||
public:
|
||||
/// Add contributions from a single inter-region connection.
|
||||
///
|
||||
/// \param[in] r1 Source region. Zero-based region index/ID.
|
||||
///
|
||||
/// \param[in] r2 Destination region. Zero-based region index.
|
||||
void add(VertexID v1, VertexID v2);
|
||||
|
||||
/// Add contributions from multiple inter-region connections.
|
||||
///
|
||||
/// \param[in] maxRowIdx Maximum row (source region) index
|
||||
/// across all new inter-region connection contributions.
|
||||
///
|
||||
/// \param[in] maxColIdx Maximum column (destination region)
|
||||
/// index across all new inter-region contributions.
|
||||
///
|
||||
/// \param[in] rows Source region indices for all new
|
||||
/// inter-region connection contributions.
|
||||
///
|
||||
/// \param[in] cols Destination region indices for all new
|
||||
/// inter-region connection contributions.
|
||||
void add(VertexID maxRowIdx,
|
||||
VertexID maxColIdx,
|
||||
const Neighbours& rows,
|
||||
const Neighbours& cols);
|
||||
|
||||
/// Clear internal tables. Preserve allocated capacity.
|
||||
void clear();
|
||||
|
||||
/// Predicate.
|
||||
///
|
||||
/// \return Whether or not internal tables are empty.
|
||||
bool empty() const;
|
||||
|
||||
/// Whether or not internal tables meet size consistency
|
||||
/// requirements.
|
||||
bool isValid() const;
|
||||
|
||||
/// Maximum zero-based row index.
|
||||
std::optional<BaseVertexID> maxRow() const;
|
||||
|
||||
/// Maximum zero-based column index.
|
||||
std::optional<BaseVertexID> maxCol() const;
|
||||
|
||||
/// Number of uncompressed contributions in internal tables.
|
||||
typename Neighbours::size_type numContributions() const;
|
||||
|
||||
/// Read-only access to uncompressed row indices.
|
||||
const Neighbours& rowIndices() const;
|
||||
|
||||
/// Read-only access to uncompressed column indices.
|
||||
const Neighbours& columnIndices() const;
|
||||
|
||||
private:
|
||||
/// Zero-based row/source region indices.
|
||||
Neighbours i_{};
|
||||
|
||||
/// Zero-based column/destination region indices.
|
||||
Neighbours j_{};
|
||||
|
||||
/// Maximum row index in \code this->i_ \endcode.
|
||||
std::optional<VertexID> max_i_{};
|
||||
|
||||
/// Maximum column index in \code this->j_ \endcode.
|
||||
std::optional<VertexID> max_j_{};
|
||||
};
|
||||
|
||||
/// Compressed sparse row representation of inter-region flow rates
|
||||
///
|
||||
/// Row and column indices are zero-based vertex IDs. Column
|
||||
/// indices ascendingly sorted per row.
|
||||
class CSR
|
||||
{
|
||||
public:
|
||||
/// Merge coordinate format into existing CSR map.
|
||||
///
|
||||
/// \param[in] conns Coordinate representation of new
|
||||
/// contributions.
|
||||
///
|
||||
/// \param[in] maxNumVertices Maximum number of vertices.
|
||||
///
|
||||
/// \param[in] expandExistingIdxMap Whether or not preserve and
|
||||
/// update the existing compressed index map. This is
|
||||
/// potentially useful for the case of adding new connections
|
||||
/// to an already compressed graph. The default setting, \c
|
||||
/// false, will disregard any existing index map and create
|
||||
/// the index map from scratch. This runtime parameter is
|
||||
/// unused if the class is not configured to track compressed
|
||||
/// indices through the TrackCompressedIdx class parameter.
|
||||
void merge(const Connections& conns,
|
||||
const Offset maxNumVertices,
|
||||
const bool expandExistingIdxMap);
|
||||
|
||||
/// Total number of rows in compressed map structure.
|
||||
Offset numRows() const;
|
||||
|
||||
/// Maximum zero-based row index encountered in mapped structure.
|
||||
BaseVertexID maxRowID() const;
|
||||
|
||||
/// Maximum zero-based column index encountered in mapped structure.
|
||||
BaseVertexID maxColID() const;
|
||||
|
||||
/// Read-only access to compressed structure's start pointers.
|
||||
const Start& startPointers() const;
|
||||
|
||||
/// Read-only access to compressed structure's column indices,
|
||||
/// ascendingly sorted per rwo.
|
||||
const Neighbours& columnIndices() const;
|
||||
|
||||
/// Coordinate format row index vector. Expanded from \code
|
||||
/// startPointers() \endcode.
|
||||
Neighbours coordinateFormatRowIndices() const;
|
||||
|
||||
template <typename Ret = const Start&>
|
||||
std::enable_if_t<TrackCompressedIdx, Ret> compressedIndexMap() const
|
||||
{
|
||||
return this->compressedIdx_;
|
||||
}
|
||||
|
||||
// MessageBufferType API should be similar to Dune::MessageBufferIF
|
||||
template <class MessageBufferType>
|
||||
void write(MessageBufferType& buffer) const
|
||||
{
|
||||
this->writeVector(this->ia_, buffer);
|
||||
this->writeVector(this->ja_, buffer);
|
||||
|
||||
if constexpr (TrackCompressedIdx) {
|
||||
this->writeVector(this->compressedIdx_, buffer);
|
||||
}
|
||||
|
||||
buffer.write(this->numRows_);
|
||||
buffer.write(this->numCols_);
|
||||
}
|
||||
|
||||
// MessageBufferType API should be similar to Dune::MessageBufferIF
|
||||
template <class MessageBufferType>
|
||||
void read(MessageBufferType& buffer)
|
||||
{
|
||||
this->readVector(buffer, this->ia_);
|
||||
this->readVector(buffer, this->ja_);
|
||||
|
||||
if constexpr (TrackCompressedIdx) {
|
||||
this->readVector(buffer, this->compressedIdx_);
|
||||
}
|
||||
|
||||
buffer.read(this->numRows_);
|
||||
buffer.read(this->numCols_);
|
||||
}
|
||||
|
||||
/// Clear internal tables. Preserve allocated capacity.
|
||||
void clear();
|
||||
|
||||
private:
|
||||
struct EmptyPlaceHolder {};
|
||||
|
||||
/// Start pointers.
|
||||
Start ia_{};
|
||||
|
||||
/// Column indices. Ascendingly sorted per row once structure
|
||||
/// is fully established.
|
||||
Neighbours ja_{};
|
||||
|
||||
/// Destination index in compressed representation. Vector of
|
||||
/// size equal to number of \c addConnection() calls if client
|
||||
/// code requests that compressed indices be tracked (i.e., when
|
||||
/// parameter TrackCompressedIdx == true); Empty structure
|
||||
/// otherwise (default setting).
|
||||
std::conditional_t<TrackCompressedIdx, Start, EmptyPlaceHolder> compressedIdx_{};
|
||||
|
||||
/// Number of active rows in compressed map structure.
|
||||
BaseVertexID numRows_{};
|
||||
|
||||
/// Number of active columns in compressed map structure.
|
||||
/// Tracked as the maximum column index plus one.
|
||||
BaseVertexID numCols_{};
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Implementation of read()/write()
|
||||
// ---------------------------------------------------------
|
||||
|
||||
template <typename T, class A, class MessageBufferType>
|
||||
void writeVector(const std::vector<T,A>& vec,
|
||||
MessageBufferType& buffer) const
|
||||
{
|
||||
const auto n = vec.size();
|
||||
buffer.write(n);
|
||||
|
||||
for (const auto& x : vec) {
|
||||
buffer.write(x);
|
||||
}
|
||||
}
|
||||
|
||||
template <class MessageBufferType, typename T, class A>
|
||||
void readVector(MessageBufferType& buffer,
|
||||
std::vector<T,A>& vec)
|
||||
{
|
||||
auto n = 0 * vec.size();
|
||||
buffer.read(n);
|
||||
|
||||
vec.resize(n);
|
||||
|
||||
for (auto& x : vec) {
|
||||
buffer.read(x);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Implementation of merge()
|
||||
// ---------------------------------------------------------
|
||||
|
||||
/// Incorporate new, coordinate format contributions into
|
||||
/// existing, possibly empty, CSR mapping structure.
|
||||
///
|
||||
/// On exit the ia_ array holds the proper start pointers while
|
||||
/// ja_ holds the corresponding column indices albeit possibly
|
||||
/// repeated and unsorted.
|
||||
///
|
||||
/// \param[in] rows Row indices of all, possibly repeated,
|
||||
/// coordinate format input contributions. Start pointers \c
|
||||
/// ia_ updated to account for new entries.
|
||||
///
|
||||
/// \param[in] cols Column index of coordinate format intput
|
||||
/// structure. Inserted into \c ja_ according to its
|
||||
/// corresponding row index.
|
||||
///
|
||||
/// \param[in] maxRowID Maximum index in \p rows. Needed to
|
||||
/// ensure proper size of \c ia_.
|
||||
///
|
||||
/// \param[in] maxColID Maximum index in \p cols.
|
||||
///
|
||||
/// \param[in] expandExistingIdxMap Whether or not preserve and
|
||||
/// update the existing compressed index map. This is
|
||||
/// potentially useful for the case of adding new connections
|
||||
/// to an already compressed graph. The default setting, \c
|
||||
/// false, will disregard any existing index map and create
|
||||
/// the index map from scratch. This runtime parameter is
|
||||
/// unused if the class is not configured to track compressed
|
||||
/// indices through the TrackCompressedIdx class parameter.
|
||||
void assemble(const Neighbours& rows,
|
||||
const Neighbours& cols,
|
||||
BaseVertexID maxRowID,
|
||||
BaseVertexID maxColID,
|
||||
bool expandExistingIdxMap);
|
||||
|
||||
/// Sort column indices per row and compress repeated column
|
||||
/// indices down to a single unique element per row. Sum
|
||||
/// repeated values
|
||||
///
|
||||
/// On exit the \c ia_ and \c ja_ arrays all have their
|
||||
/// expected, canonical structure.
|
||||
///
|
||||
/// \param[in] maxNumVertices Maximum number of vertices
|
||||
/// supported by final compressed mapping structure. Ignored
|
||||
/// if less than active number of rows.
|
||||
void compress(const Offset maxNumVertices);
|
||||
|
||||
/// Sort column indices within each mapped row.
|
||||
///
|
||||
/// On exit \c ja_ has ascendingly sorted column indices, albeit
|
||||
/// possibly with repeated entries. This function also updates
|
||||
/// \c compressedIdx_, if applicable, to account for the new
|
||||
/// locations of the non-zero elements in the grouped structure.
|
||||
void sortColumnIndicesPerRow();
|
||||
|
||||
/// Condense repeated column indices per row down to a single
|
||||
/// unique entry for each.
|
||||
///
|
||||
/// Assumes that each row has ascendingly sorted column indices
|
||||
/// in \c ja_ and must therefore be called after member function
|
||||
/// sortColumnIndicesPerRow(). On exit, \c ja_ has its final
|
||||
/// canonical structure and \c compressedIdx_, if applicable,
|
||||
/// knows the final location of each non-zero contribution in
|
||||
/// the input coordinate format.
|
||||
void condenseDuplicates();
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Implementation of assemble()
|
||||
// ---------------------------------------------------------
|
||||
|
||||
/// Position end pointers at start of row to prepare for column
|
||||
/// index grouping by corresponding row index.
|
||||
///
|
||||
/// Also counts total number of non-zero elements, possibly
|
||||
/// including repetitions, in \code this->ia_[0] \endcode.
|
||||
///
|
||||
/// \param[in] numRows Number of rows in final compressed
|
||||
/// structure. Used to allocate \code this->ia_ \endcode.
|
||||
///
|
||||
/// \param[in] rowIdx Row indices of all, possibly repeated,
|
||||
/// coordinate format input contributions. Needed to count
|
||||
/// the number of possibly repeated column index entries per
|
||||
/// row.
|
||||
void preparePushbackRowGrouping(const int numRows,
|
||||
const Neighbours& rowIdx);
|
||||
|
||||
/// Group column indices by corresponding row index and track
|
||||
/// grouped location of original coordinate format element
|
||||
///
|
||||
/// Appends grouped location to \c compressedIdx_ if needed.
|
||||
///
|
||||
/// \param[in] rowIdx Row index of coordinate format input
|
||||
/// structure. Used as grouping key.
|
||||
///
|
||||
/// \param[in] colIdx Column index of coordinate format intput
|
||||
/// structure. Inserted into \c ja_ according to its
|
||||
/// corresponding row index.
|
||||
void groupAndTrackColumnIndicesByRow(const Neighbours& rowIdx,
|
||||
const Neighbours& colIdx);
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// General utilities
|
||||
// ---------------------------------------------------------
|
||||
|
||||
/// Transpose connectivity structure.
|
||||
///
|
||||
/// Essentially swaps the roles of rows and columns. Also used
|
||||
/// as a basic building block for sortColumnIndicesPerRow().
|
||||
void transpose();
|
||||
|
||||
/// Condense sequences of repeated column indices in a single
|
||||
/// map row down to a single copy of each unique column index.
|
||||
///
|
||||
/// Appends new unique column indices to \code ja_ \endcode
|
||||
///
|
||||
/// Assumes that the map row has ascendingly sorted column
|
||||
/// indices and therefore has the same requirements as
|
||||
/// std::unique. Will also update the internal compressedIdx_
|
||||
/// mapping, if needed, to record new compressed locations for
|
||||
/// the current, uncompressed, non-zero map elements.
|
||||
///
|
||||
/// \param[in] begin Start of map row that contains possibly
|
||||
/// repeated column indices.
|
||||
///
|
||||
/// \param[in] end One-past-end of map row that contains
|
||||
/// possibly repeated column indices.
|
||||
void condenseAndTrackUniqueColumnsForSingleRow(typename Neighbours::const_iterator begin,
|
||||
typename Neighbours::const_iterator end);
|
||||
|
||||
/// Update \c compressedIdx_ mapping, if needed, to account for
|
||||
/// column index reshuffling.
|
||||
///
|
||||
/// \param[in] compressedIdx New compressed index locations of
|
||||
/// the non-zero map entries.
|
||||
///
|
||||
/// \param[in] numOrigNNZ Number of existing, unique NNZs
|
||||
/// (edges) in graph. Needed to support calling add() after
|
||||
/// compress() when TrackCompressedIdx is true.
|
||||
void remapCompressedIndex(Start&& compressedIdx,
|
||||
std::optional<typename Start::size_type> numOrigNNZ = std::nullopt);
|
||||
};
|
||||
|
||||
/// Accumulated coordinate format contributions that have not yet
|
||||
/// been added to the final CSR structure.
|
||||
Connections uncompressed_;
|
||||
|
||||
/// Canonical representation of unique inter-region flow rates.
|
||||
CSR csr_;
|
||||
};
|
||||
|
||||
}} // namespace Opm::utility
|
||||
|
||||
// Actual implementation of member functions in _impl.hpp file.
|
||||
#include <opm/common/utility/CSRGraphFromCoordinates_impl.hpp>
|
||||
|
||||
#endif // OPM_UTILITY_CSRGRAPHFROMCOORDINATES_HPP
|
@ -1,610 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 SINTEF ICT, Applied Mathematics.
|
||||
Copyright 2016 Statoil ASA.
|
||||
Copyright 2022 Equinor ASA
|
||||
|
||||
This file is part of the Open Porous Media Project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <exception>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Class Opm::utility::CSRGraphFromCoordinates::Connections
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
void
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
Connections::add(const VertexID v1, const VertexID v2)
|
||||
{
|
||||
this->i_.push_back(v1);
|
||||
this->j_.push_back(v2);
|
||||
|
||||
this->max_i_ = std::max(this->max_i_.value_or(BaseVertexID{}), this->i_.back());
|
||||
this->max_j_ = std::max(this->max_j_.value_or(BaseVertexID{}), this->j_.back());
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
void
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
Connections::add(VertexID maxRowIdx,
|
||||
VertexID maxColIdx,
|
||||
const Neighbours& rows,
|
||||
const Neighbours& cols)
|
||||
{
|
||||
if (cols.size() != rows.size()) {
|
||||
throw std::invalid_argument {
|
||||
"Coordinate format column index table size does not match "
|
||||
"row index table size"
|
||||
};
|
||||
}
|
||||
|
||||
this->i_.insert(this->i_.end(), rows .begin(), rows .end());
|
||||
this->j_.insert(this->j_.end(), cols .begin(), cols .end());
|
||||
|
||||
this->max_i_ = std::max(this->max_i_.value_or(BaseVertexID{}), maxRowIdx);
|
||||
this->max_j_ = std::max(this->max_j_.value_or(BaseVertexID{}), maxColIdx);
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
void
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
Connections::clear()
|
||||
{
|
||||
this->j_.clear();
|
||||
this->i_.clear();
|
||||
|
||||
this->max_i_.reset();
|
||||
this->max_j_.reset();
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
bool
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
Connections::empty() const
|
||||
{
|
||||
return this->i_.empty();
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
bool
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
Connections::isValid() const
|
||||
{
|
||||
return this->i_.size() == this->j_.size();
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
std::optional<typename Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::BaseVertexID>
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
Connections::maxRow() const
|
||||
{
|
||||
return this->max_i_;
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
std::optional<typename Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::BaseVertexID>
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
Connections::maxCol() const
|
||||
{
|
||||
return this->max_j_;
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
typename Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::Neighbours::size_type
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
Connections::numContributions() const
|
||||
{
|
||||
return this->i_.size();
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
const typename Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::Neighbours&
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
Connections::rowIndices() const
|
||||
{
|
||||
return this->i_;
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
const typename Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::Neighbours&
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
Connections::columnIndices() const
|
||||
{
|
||||
return this->j_;
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Class Opm::utility::CSRGraphFromCoordinates::CSR
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
void
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
CSR::merge(const Connections& conns,
|
||||
const Offset maxNumVertices,
|
||||
const bool expandExistingIdxMap)
|
||||
{
|
||||
const auto maxRow = conns.maxRow();
|
||||
|
||||
if (maxRow.has_value() &&
|
||||
(static_cast<Offset>(*maxRow) >= maxNumVertices))
|
||||
{
|
||||
throw std::invalid_argument {
|
||||
"Number of vertices in input graph (" +
|
||||
std::to_string(*maxRow) + ") "
|
||||
"exceeds maximum graph size implied by explicit size of "
|
||||
"adjacency matrix (" + std::to_string(maxNumVertices) + ')'
|
||||
};
|
||||
}
|
||||
|
||||
this->assemble(conns.rowIndices(), conns.columnIndices(),
|
||||
maxRow.value_or(BaseVertexID{0}),
|
||||
conns.maxCol().value_or(BaseVertexID{0}),
|
||||
expandExistingIdxMap);
|
||||
|
||||
this->compress(maxNumVertices);
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
typename Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::Offset
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
CSR::numRows() const
|
||||
{
|
||||
return this->startPointers().empty()
|
||||
? 0 : this->startPointers().size() - 1;
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
typename Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::BaseVertexID
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
CSR::maxRowID() const
|
||||
{
|
||||
return this->numRows_ - 1;
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
typename Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::BaseVertexID
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
CSR::maxColID() const
|
||||
{
|
||||
return this->numCols_ - 1;
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
const typename Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::Start&
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
CSR::startPointers() const
|
||||
{
|
||||
return this->ia_;
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
const typename Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::Neighbours&
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
CSR::columnIndices() const
|
||||
{
|
||||
return this->ja_;
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
typename Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::Neighbours
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
CSR::coordinateFormatRowIndices() const
|
||||
{
|
||||
auto rowIdx = Neighbours{};
|
||||
|
||||
if (this->ia_.empty()) {
|
||||
return rowIdx;
|
||||
}
|
||||
|
||||
rowIdx.reserve(this->ia_.back());
|
||||
|
||||
auto row = BaseVertexID{};
|
||||
|
||||
const auto m = this->ia_.size() - 1;
|
||||
for (auto i = 0*m; i < m; ++i, ++row) {
|
||||
const auto n = this->ia_[i + 1] - this->ia_[i + 0];
|
||||
|
||||
rowIdx.insert(rowIdx.end(), n, row);
|
||||
}
|
||||
|
||||
return rowIdx;
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
void
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
CSR::clear()
|
||||
{
|
||||
this->ia_.clear();
|
||||
this->ja_.clear();
|
||||
|
||||
if constexpr (TrackCompressedIdx) {
|
||||
this->compressedIdx_.clear();
|
||||
}
|
||||
|
||||
this->numRows_ = 0;
|
||||
this->numCols_ = 0;
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
void
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
CSR::assemble(const Neighbours& rows,
|
||||
const Neighbours& cols,
|
||||
const BaseVertexID maxRowIdx,
|
||||
const BaseVertexID maxColIdx,
|
||||
[[maybe_unused]] const bool expandExistingIdxMap)
|
||||
{
|
||||
[[maybe_unused]] auto compressedIdx = this->compressedIdx_;
|
||||
[[maybe_unused]] const auto numOrigNNZ = this->ja_.size();
|
||||
|
||||
auto i = this->coordinateFormatRowIndices();
|
||||
i.insert(i.end(), rows.begin(), rows.end());
|
||||
|
||||
auto j = this->ja_;
|
||||
j.insert(j.end(), cols.begin(), cols.end());
|
||||
|
||||
const auto thisNumRows = std::max(this->numRows_, maxRowIdx + 1);
|
||||
const auto thisNumCols = std::max(this->numCols_, maxColIdx + 1);
|
||||
|
||||
this->preparePushbackRowGrouping(thisNumRows, i);
|
||||
|
||||
this->groupAndTrackColumnIndicesByRow(i, j);
|
||||
|
||||
if constexpr (TrackCompressedIdx) {
|
||||
if (expandExistingIdxMap) {
|
||||
this->remapCompressedIndex(std::move(compressedIdx), numOrigNNZ);
|
||||
}
|
||||
}
|
||||
|
||||
this->numRows_ = thisNumRows;
|
||||
this->numCols_ = thisNumCols;
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
void
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
CSR::compress(const Offset maxNumVertices)
|
||||
{
|
||||
if (this->numRows() > maxNumVertices) {
|
||||
throw std::invalid_argument {
|
||||
"Number of vertices in input graph (" +
|
||||
std::to_string(this->numRows()) + ") "
|
||||
"exceeds maximum graph size implied by explicit size of "
|
||||
"adjacency matrix (" + std::to_string(maxNumVertices) + ')'
|
||||
};
|
||||
}
|
||||
|
||||
this->sortColumnIndicesPerRow();
|
||||
|
||||
// Must be called *after* sortColumnIndicesPerRow().
|
||||
this->condenseDuplicates();
|
||||
|
||||
const auto nRows = this->startPointers().size() - 1;
|
||||
if (nRows < maxNumVertices) {
|
||||
this->ia_.insert(this->ia_.end(),
|
||||
maxNumVertices - nRows,
|
||||
this->startPointers().back());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
void
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
CSR::sortColumnIndicesPerRow()
|
||||
{
|
||||
// Transposition is, in this context, effectively a linear time (O(nnz))
|
||||
// bucket insertion procedure. In other words transposing the structure
|
||||
// twice creates a structure with column indices in (ascendingly) sorted
|
||||
// order.
|
||||
|
||||
this->transpose();
|
||||
this->transpose();
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
void
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
CSR::condenseDuplicates()
|
||||
{
|
||||
// Note: Must be called *after* sortColumnIndicesPerRow().
|
||||
|
||||
const auto colIdx = this->ja_;
|
||||
auto end = colIdx.begin();
|
||||
|
||||
this->ja_.clear();
|
||||
|
||||
[[maybe_unused]] auto compressedIdx = this->compressedIdx_;
|
||||
if constexpr (TrackCompressedIdx) {
|
||||
this->compressedIdx_.clear();
|
||||
}
|
||||
|
||||
const auto numRows = this->ia_.size() - 1;
|
||||
for (auto row = 0*numRows; row < numRows; ++row) {
|
||||
auto begin = end;
|
||||
|
||||
std::advance(end, this->ia_[row + 1] - this->ia_[row + 0]);
|
||||
|
||||
const auto q = this->ja_.size();
|
||||
|
||||
this->condenseAndTrackUniqueColumnsForSingleRow(begin, end);
|
||||
|
||||
this->ia_[row + 0] = q;
|
||||
}
|
||||
|
||||
if constexpr (TrackCompressedIdx) {
|
||||
this->remapCompressedIndex(std::move(compressedIdx));
|
||||
}
|
||||
|
||||
// Record final table sizes.
|
||||
this->ia_.back() = this->ja_.size();
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
void
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
CSR::preparePushbackRowGrouping(const int numRows,
|
||||
const Neighbours& rowIdx)
|
||||
{
|
||||
assert (numRows >= 0);
|
||||
|
||||
this->ia_.assign(numRows + 1, 0);
|
||||
|
||||
// Count number of neighbouring vertices for each row. Accumulate in
|
||||
// "next" bin since we're positioning the end pointers.
|
||||
for (const auto& row : rowIdx) {
|
||||
this->ia_[row + 1] += 1;
|
||||
}
|
||||
|
||||
// Position "end" pointers.
|
||||
//
|
||||
// After this loop, ia_[i + 1] points to the *start* of the range of the
|
||||
// column indices/neighbouring vertices of vertex 'i'. This, in turn,
|
||||
// enables using the statement ja_[ia_[i+1]++] = v in groupAndTrack()
|
||||
// to insert vertex 'v' as a neighbour, at the end of the range of known
|
||||
// neighbours, *and* advance the end pointer of row/vertex 'i'. We use
|
||||
// ia_[0] as an accumulator for the total number of neighbouring
|
||||
// vertices in the graph.
|
||||
//
|
||||
// Note index range: 1..numRows inclusive.
|
||||
for (typename Start::size_type i = 1, n = numRows; i <= n; ++i) {
|
||||
this->ia_[0] += this->ia_[i];
|
||||
this->ia_[i] = this->ia_[0] - this->ia_[i];
|
||||
}
|
||||
|
||||
assert (this->ia_[0] == rowIdx.size());
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
void
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
CSR::groupAndTrackColumnIndicesByRow(const Neighbours& rowIdx,
|
||||
const Neighbours& colIdx)
|
||||
{
|
||||
assert (this->ia_[0] == rowIdx.size());
|
||||
|
||||
const auto nnz = rowIdx.size();
|
||||
|
||||
this->ja_.resize(nnz);
|
||||
|
||||
if constexpr (TrackCompressedIdx) {
|
||||
this->compressedIdx_.clear();
|
||||
this->compressedIdx_.reserve(nnz);
|
||||
}
|
||||
|
||||
// Group/insert column indices according to their associate vertex/row
|
||||
// index.
|
||||
//
|
||||
// At the start of the loop the end pointers ia_[i+1], formed in
|
||||
// preparePushback(), are positioned at the *start* of the column index
|
||||
// range associated to vertex 'i'. After this loop all vertices
|
||||
// neighbouring vertex 'i' will be placed consecutively, in order of
|
||||
// appearance, into ja_. Furthermore, the row pointers ia_ will have
|
||||
// their final position.
|
||||
//
|
||||
// The statement ja_[ia_[i+1]++] = v, split into two statements using
|
||||
// the helper object 'k', inserts 'v' as a neighbouring vertex of vertex
|
||||
// 'i' *and* advances the end pointer ia_[i+1] of that vertex. We use
|
||||
// and maintain the invariant that ia_[i+1] at all times records the
|
||||
// insertion point of the next neighbouring vertex of vertex 'i'. When
|
||||
// the list of neighbouring vertices for vertex 'i' has been exhausted,
|
||||
// ia_[i+1] will hold the start position for in ja_ for vertex i+1.
|
||||
for (auto nz = 0*nnz; nz < nnz; ++nz) {
|
||||
const auto k = this->ia_[rowIdx[nz] + 1] ++;
|
||||
|
||||
this->ja_[k] = colIdx[nz];
|
||||
|
||||
if constexpr (TrackCompressedIdx) {
|
||||
this->compressedIdx_.push_back(k);
|
||||
}
|
||||
}
|
||||
|
||||
this->ia_[0] = 0;
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
void
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
CSR::transpose()
|
||||
{
|
||||
[[maybe_unused]] auto compressedIdx = this->compressedIdx_;
|
||||
|
||||
{
|
||||
const auto rowIdx = this->coordinateFormatRowIndices();
|
||||
const auto colIdx = this->ja_;
|
||||
|
||||
this->preparePushbackRowGrouping(this->numCols_, colIdx);
|
||||
|
||||
// Note parameter order. Transposition switches role of rows and
|
||||
// columns.
|
||||
this->groupAndTrackColumnIndicesByRow(colIdx, rowIdx);
|
||||
}
|
||||
|
||||
if constexpr (TrackCompressedIdx) {
|
||||
this->remapCompressedIndex(std::move(compressedIdx));
|
||||
}
|
||||
|
||||
std::swap(this->numRows_, this->numCols_);
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
void
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
CSR::condenseAndTrackUniqueColumnsForSingleRow(typename Neighbours::const_iterator begin,
|
||||
typename Neighbours::const_iterator end)
|
||||
{
|
||||
// We assume that we're only called *after* sortColumnIndicesPerRow()
|
||||
// whence duplicate elements appear consecutively in [begin, end).
|
||||
//
|
||||
// Note: This is essentially the same as std::unique(begin, end) save
|
||||
// for the return value and the fact that we additionally record the
|
||||
// 'compressedIdx_' mapping. That mapping enables subsequent, decoupled
|
||||
// accumulation of the 'sa_' contributions.
|
||||
|
||||
while (begin != end) {
|
||||
// Note: Order of ja_ and compressedIdx_ matters here.
|
||||
|
||||
if constexpr (TrackCompressedIdx) {
|
||||
this->compressedIdx_.push_back(this->ja_.size());
|
||||
}
|
||||
|
||||
this->ja_.push_back(*begin);
|
||||
|
||||
auto next_unique =
|
||||
std::find_if(begin, end, [last = this->ja_.back()]
|
||||
(const auto j) { return j != last; });
|
||||
|
||||
if constexpr (TrackCompressedIdx) {
|
||||
// Number of duplicate elements in [begin, next_unique).
|
||||
const auto ndup = std::distance(begin, next_unique);
|
||||
|
||||
if (ndup > 1) {
|
||||
// Insert ndup - 1 copies of .back() to represent the
|
||||
// duplicate pairs in [begin, next_unique). We subtract one
|
||||
// to account for .push_back() above representing *begin.
|
||||
this->compressedIdx_.insert(this->compressedIdx_.end(),
|
||||
ndup - 1,
|
||||
this->compressedIdx_.back());
|
||||
}
|
||||
}
|
||||
|
||||
begin = next_unique;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
void
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::CSR::
|
||||
remapCompressedIndex([[maybe_unused]] Start&& compressedIdx,
|
||||
[[maybe_unused]] std::optional<typename Start::size_type> numOrig)
|
||||
{
|
||||
if constexpr (TrackCompressedIdx) {
|
||||
for (auto& i : compressedIdx) {
|
||||
i = this->compressedIdx_[i];
|
||||
}
|
||||
|
||||
if (numOrig.has_value() && (*numOrig < this->compressedIdx_.size())) {
|
||||
// Client called add() after compress(). Remap existing portion
|
||||
// of compressedIdx (above), and append new entries (here).
|
||||
compressedIdx
|
||||
.insert(compressedIdx.end(),
|
||||
this->compressedIdx_.begin() + *numOrig,
|
||||
this->compressedIdx_.end());
|
||||
}
|
||||
|
||||
this->compressedIdx_.swap(compressedIdx);
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Class Opm::utility::CSRGraphFromCoordinates
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
void Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::clear()
|
||||
{
|
||||
this->uncompressed_.clear();
|
||||
this->csr_.clear();
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
void
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
addConnection(const VertexID v1, const VertexID v2)
|
||||
{
|
||||
if ((v1 < 0) || (v2 < 0)) {
|
||||
throw std::invalid_argument {
|
||||
"Vertex IDs must be non-negative. Got (v1,v2) = ("
|
||||
+ std::to_string(v1) + ", " + std::to_string(v2)
|
||||
+ ')'
|
||||
};
|
||||
}
|
||||
|
||||
if constexpr (! PermitSelfConnections) {
|
||||
if (v1 == v2) {
|
||||
// Ignore self connections.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this->uncompressed_.add(v1, v2);
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
void
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::
|
||||
compress(const Offset maxNumVertices, const bool expandExistingIdxMap)
|
||||
{
|
||||
if (! this->uncompressed_.isValid()) {
|
||||
throw std::logic_error {
|
||||
"Cannot compress invalid connection list"
|
||||
};
|
||||
}
|
||||
|
||||
this->csr_.merge(this->uncompressed_, maxNumVertices, expandExistingIdxMap);
|
||||
|
||||
this->uncompressed_.clear();
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
typename Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::Offset
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::numVertices() const
|
||||
{
|
||||
return this->csr_.numRows();
|
||||
}
|
||||
|
||||
template <typename VertexID, bool TrackCompressedIdx, bool PermitSelfConnections>
|
||||
typename Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::Offset
|
||||
Opm::utility::CSRGraphFromCoordinates<VertexID, TrackCompressedIdx, PermitSelfConnections>::numEdges() const
|
||||
{
|
||||
const auto& ia = this->startPointers();
|
||||
|
||||
return ia.empty() ? 0 : ia.back();
|
||||
}
|
@ -20,12 +20,11 @@
|
||||
#ifndef COMMON_UTIL_NUMERIC_CMP
|
||||
#define COMMON_UTIL_NUMERIC_CMP
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include <type_traits>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
@ -110,7 +109,7 @@ namespace Opm {
|
||||
|
||||
template<typename T>
|
||||
bool array_equal(const T* p1, const T* p2, size_t num_elements, T abs_eps, T rel_eps) {
|
||||
if (std::memcmp(p1 , p2 , num_elements * sizeof * p1) == 0)
|
||||
if (memcmp(p1 , p2 , num_elements * sizeof * p1) == 0)
|
||||
return true;
|
||||
else {
|
||||
size_t index;
|
||||
|
@ -22,80 +22,86 @@
|
||||
#define OPM_LINEARINTERPOLATION_HEADER_INCLUDED
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
namespace Opm
|
||||
{
|
||||
|
||||
//! \brief Returns an index in an ordered table such that x is between
|
||||
//! table[j] and table[j+1].
|
||||
//! \details If x is out of bounds, it returns a clamped index
|
||||
inline int tableIndex(const std::vector<double>& table, double x)
|
||||
{
|
||||
if (table.size() < 2)
|
||||
return 0;
|
||||
|
||||
const auto lower = std::lower_bound(table.begin(), table.end(), x);
|
||||
|
||||
if (lower == table.end())
|
||||
return table.size()-2;
|
||||
else if (lower == table.begin())
|
||||
return 0;
|
||||
else
|
||||
return std::distance(table.begin(), lower)-1;
|
||||
}
|
||||
|
||||
inline std::pair<double, int>
|
||||
linearInterpolationSlope(const std::vector<double>& xv,
|
||||
const std::vector<double>& yv,
|
||||
const double x)
|
||||
{
|
||||
const auto i = Opm::tableIndex(xv, x);
|
||||
return { (yv[i + 1] - yv[i]) / (xv[i + 1] - xv[i]), i };
|
||||
}
|
||||
|
||||
|
||||
inline double linearInterpolationDerivative(const std::vector<double>& xv,
|
||||
const std::vector<double>& yv, double x)
|
||||
{
|
||||
// Extrapolates if x is outside xv
|
||||
return linearInterpolationSlope(xv, yv, x).first;
|
||||
}
|
||||
|
||||
inline double linearInterpolation(const std::vector<double>& xv,
|
||||
const std::vector<double>& yv, double x)
|
||||
{
|
||||
// Extrapolates if x is outside xv
|
||||
const auto& [t, i] = linearInterpolationSlope(xv, yv, x);
|
||||
return t * (x - xv[i]) + yv[i];
|
||||
}
|
||||
|
||||
inline double linearInterpolationNoExtrapolation(const std::vector<double>& xv,
|
||||
const std::vector<double>& yv, double x)
|
||||
{
|
||||
// Return end values if x is outside xv
|
||||
if (x < xv.front()) {
|
||||
return yv.front();
|
||||
}
|
||||
if (x > xv.back()) {
|
||||
return yv.back();
|
||||
inline int tableIndex(const std::vector<double>& table, double x)
|
||||
{
|
||||
// Returns an index in an ordered table such that x is between
|
||||
// table[j] and table[j+1]. If x is out of range, first or last
|
||||
// interval is returned; Binary search.
|
||||
int n = table.size() - 1;
|
||||
if (n < 2) {
|
||||
return 0;
|
||||
}
|
||||
int jl = 0;
|
||||
int ju = n;
|
||||
bool ascend = (table[n] > table[0]);
|
||||
while (ju - jl > 1) {
|
||||
int jm = (ju + jl)/2; // Compute a midpoint
|
||||
if ( (x >= table[jm]) == ascend) {
|
||||
jl = jm; // Replace lower limit
|
||||
} else {
|
||||
ju = jm; // Replace upper limit
|
||||
}
|
||||
}
|
||||
return jl;
|
||||
}
|
||||
|
||||
|
||||
inline double linearInterpolationDerivative(const std::vector<double>& xv,
|
||||
const std::vector<double>& yv, double x)
|
||||
{
|
||||
// Extrapolates if x is outside xv
|
||||
int ix1 = tableIndex(xv, x);
|
||||
int ix2 = ix1 + 1;
|
||||
return (yv[ix2] - yv[ix1])/(xv[ix2] - xv[ix1]);
|
||||
}
|
||||
|
||||
inline double linearInterpolation(const std::vector<double>& xv,
|
||||
const std::vector<double>& yv, double x)
|
||||
{
|
||||
// Extrapolates if x is outside xv
|
||||
int ix1 = tableIndex(xv, x);
|
||||
int ix2 = ix1 + 1;
|
||||
return (yv[ix2] - yv[ix1])/(xv[ix2] - xv[ix1])*(x - xv[ix1]) + yv[ix1];
|
||||
}
|
||||
|
||||
inline double linearInterpolationNoExtrapolation(const std::vector<double>& xv,
|
||||
const std::vector<double>& yv, double x)
|
||||
{
|
||||
// Return end values if x is outside xv
|
||||
if (x < xv.front()) {
|
||||
return yv.front();
|
||||
}
|
||||
if (x > xv.back()) {
|
||||
return yv.back();
|
||||
}
|
||||
|
||||
int ix1 = tableIndex(xv, x);
|
||||
int ix2 = ix1 + 1;
|
||||
return (yv[ix2] - yv[ix1])/(xv[ix2] - xv[ix1])*(x - xv[ix1]) + yv[ix1];
|
||||
}
|
||||
|
||||
inline double linearInterpolation(const std::vector<double>& xv,
|
||||
const std::vector<double>& yv,
|
||||
double x, int& ix1)
|
||||
{
|
||||
// Extrapolates if x is outside xv
|
||||
ix1 = tableIndex(xv, x);
|
||||
int ix2 = ix1 + 1;
|
||||
return (yv[ix2] - yv[ix1])/(xv[ix2] - xv[ix1])*(x - xv[ix1]) + yv[ix1];
|
||||
}
|
||||
|
||||
return linearInterpolation(xv, yv, x);
|
||||
}
|
||||
|
||||
inline double linearInterpolation(const std::vector<double>& xv,
|
||||
const std::vector<double>& yv,
|
||||
double x, int& ix1)
|
||||
{
|
||||
// Extrapolates if x is outside xv
|
||||
double t;
|
||||
std::tie(t, ix1) = linearInterpolationSlope(xv, yv, x);
|
||||
return t * (x - xv[ix1]) + yv[ix1];
|
||||
}
|
||||
|
||||
} // namespace Opm
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // OPM_LINEARINTERPOLATION_HEADER_INCLUDED
|
||||
|
@ -52,7 +52,7 @@ namespace Opm {
|
||||
/// @brief
|
||||
/// @todo Doc me!
|
||||
/// @return
|
||||
std::string getTag() const override { return ID_xmltag__param; }
|
||||
virtual std::string getTag() const {return ID_xmltag__param;}
|
||||
/// @brief
|
||||
/// @todo Doc me!
|
||||
/// @param
|
||||
|
@ -93,7 +93,7 @@ namespace Opm {
|
||||
|
||||
// From ParameterMapItem
|
||||
virtual ~ParameterGroup();
|
||||
std::string getTag() const override;
|
||||
virtual std::string getTag() const;
|
||||
|
||||
/// \brief A constructor typically used to initialize a
|
||||
/// ParameterGroup from command-line arguments.
|
||||
|
@ -34,7 +34,7 @@ namespace Opm {
|
||||
typedef std::vector< DeckItem >::const_iterator const_iterator;
|
||||
|
||||
DeckRecord() = default;
|
||||
explicit DeckRecord( std::vector< DeckItem >&& items, const bool check_for_duplicate_names = true );
|
||||
DeckRecord( std::vector< DeckItem >&& items, const bool check_for_duplicate_names = true );
|
||||
|
||||
static DeckRecord serializationTestObject();
|
||||
|
||||
|
@ -27,7 +27,6 @@
|
||||
namespace Opm {
|
||||
|
||||
class Deck;
|
||||
class ErrorGuard;
|
||||
|
||||
enum class Section {
|
||||
RUNSPEC,
|
||||
@ -64,7 +63,6 @@ class DeckSection : public DeckView {
|
||||
// the right order
|
||||
static bool checkSectionTopology(const Deck& deck,
|
||||
const Parser&,
|
||||
ErrorGuard& errorGuard,
|
||||
bool ensureKeywordSectionAffiliation = false);
|
||||
|
||||
|
||||
|
@ -38,7 +38,7 @@ namespace Opm {
|
||||
class DeckTree {
|
||||
public:
|
||||
DeckTree() = default;
|
||||
explicit DeckTree(const std::string&);
|
||||
DeckTree(const std::string&);
|
||||
|
||||
const std::string& parent(const std::string& fname) const;
|
||||
bool includes(const std::string& parent_file, const std::string& include_file) const;
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
|
||||
|
||||
struct Iterator : public storage_type::iterator {
|
||||
explicit Iterator(storage_type::const_iterator inner_iter) :
|
||||
Iterator(storage_type::const_iterator inner_iter) :
|
||||
inner(inner_iter)
|
||||
{}
|
||||
|
||||
|
@ -124,7 +124,7 @@ namespace Opm {
|
||||
|
||||
AquiferCT() = default;
|
||||
AquiferCT(const TableManager& tables, const Deck& deck);
|
||||
explicit AquiferCT(const std::vector<AquiferCT::AQUCT_data>& data);
|
||||
AquiferCT(const std::vector<AquiferCT::AQUCT_data>& data);
|
||||
|
||||
void loadFromRestart(const RestartIO::RstAquifer& rst,
|
||||
const TableManager& tables);
|
||||
|
@ -20,15 +20,13 @@
|
||||
#ifndef OPM_NUMERICALAQUIFERS_HPP
|
||||
#define OPM_NUMERICALAQUIFERS_HPP
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/Aquifer/NumericalAquifer/SingleNumericalAquifer.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/Aquifer/NumericalAquifer/SingleNumericalAquifer.hpp>
|
||||
|
||||
namespace Opm {
|
||||
class Deck;
|
||||
class EclipseGrid;
|
||||
@ -48,7 +46,6 @@ namespace Opm {
|
||||
bool operator==(const NumericalAquifers& other) const;
|
||||
|
||||
std::unordered_map<size_t, const NumericalAquiferCell*> allAquiferCells() const;
|
||||
std::vector<std::size_t> allAquiferCellIds() const;
|
||||
|
||||
std::unordered_map<size_t, double> aquiferCellVolumes() const;
|
||||
|
||||
|
@ -21,7 +21,6 @@
|
||||
#define OPM_ECLIPSE_CONFIG_HPP
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/InitConfig/InitConfig.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/IOConfig/FIPConfig.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/IOConfig/IOConfig.hpp>
|
||||
|
||||
namespace Opm {
|
||||
@ -33,9 +32,7 @@ namespace Opm {
|
||||
public:
|
||||
EclipseConfig() = default;
|
||||
explicit EclipseConfig(const Deck& deck);
|
||||
EclipseConfig(const InitConfig& initConfig,
|
||||
const FIPConfig& fip_conf,
|
||||
const IOConfig& io_conf);
|
||||
EclipseConfig(const InitConfig& initConfig, const IOConfig& io_conf);
|
||||
|
||||
static EclipseConfig serializationTestObject();
|
||||
|
||||
@ -43,7 +40,6 @@ namespace Opm {
|
||||
IOConfig& io();
|
||||
const IOConfig& io() const;
|
||||
const InitConfig& init() const;
|
||||
const FIPConfig& fip() const;
|
||||
|
||||
bool operator==(const EclipseConfig& data) const;
|
||||
static bool rst_cmp(const EclipseConfig& full_config, const EclipseConfig& rst_config);
|
||||
@ -51,13 +47,11 @@ namespace Opm {
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(m_initConfig);
|
||||
serializer(fip_config);
|
||||
serializer(io_config);
|
||||
}
|
||||
|
||||
private:
|
||||
InitConfig m_initConfig;
|
||||
FIPConfig fip_config;
|
||||
IOConfig io_config;
|
||||
};
|
||||
}
|
||||
|
@ -23,19 +23,16 @@
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferConfig.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/EclipseConfig.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/TracerConfig.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/MICPpara.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/WagHysteresisConfig.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/FaultCollection.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/NNC.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/TransMult.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/LgrCollection.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Runspec.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Tables/TableManager.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/SimulationConfig/SimulationConfig.hpp>
|
||||
@ -51,7 +48,6 @@ namespace Opm {
|
||||
|
||||
namespace Opm { namespace RestartIO {
|
||||
class RstAquifer;
|
||||
class RstNetwork;
|
||||
}} // namespace Opm::RestartIO
|
||||
|
||||
namespace Opm {
|
||||
@ -98,9 +94,6 @@ namespace Opm {
|
||||
const EclipseConfig& cfg() const;
|
||||
const GridDims& gridDims() const;
|
||||
|
||||
const LgrCollection& getLgrs() const;
|
||||
bool hasInputLGR() const;
|
||||
|
||||
// the unit system used by the deck. note that it is rarely needed
|
||||
// to convert units because internally to opm-parser everything is
|
||||
// represented by SI units.
|
||||
@ -115,7 +108,6 @@ namespace Opm {
|
||||
const AquiferConfig& aquifer() const;
|
||||
const TracerConfig& tracer() const;
|
||||
const MICPpara& getMICPpara() const;
|
||||
const WagHysteresisConfig& getWagHysteresis() const;
|
||||
|
||||
void reset_actnum(const std::vector<int>& new_actnum);
|
||||
void pruneDeactivatedAquiferConnections(const std::vector<std::size_t>& deactivated_cells);
|
||||
@ -126,9 +118,6 @@ namespace Opm {
|
||||
// When we know and decide to handle the same for AQUFETP and AQUCT, this part will be refactored
|
||||
void appendAqufluxSchedule(const std::unordered_set<int>& ids);
|
||||
|
||||
void loadRestartNetworkPressures(const RestartIO::RstNetwork& network);
|
||||
const std::optional<std::map<std::string, double> >& getRestartNetworkPressures() const { return this->m_restart_network_pressures; }
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
@ -140,7 +129,6 @@ namespace Opm {
|
||||
serializer(m_deckUnitSystem);
|
||||
serializer(m_inputNnc);
|
||||
serializer(m_gridDims);
|
||||
serializer(m_lgrs);
|
||||
serializer(m_simulationConfig);
|
||||
serializer(aquifer_config);
|
||||
serializer(m_transMult);
|
||||
@ -148,7 +136,6 @@ namespace Opm {
|
||||
serializer(m_title);
|
||||
serializer(tracer_config);
|
||||
serializer(m_micppara);
|
||||
serializer(wag_hyst_config);
|
||||
}
|
||||
|
||||
static bool rst_cmp(const EclipseState& full_state, const EclipseState& rst_state);
|
||||
@ -158,13 +145,12 @@ namespace Opm {
|
||||
void initIOConfigPostSchedule(const Deck& deck);
|
||||
void assignRunTitle(const Deck& deck);
|
||||
void reportNumberOfActivePhases() const;
|
||||
void initLgrs(const Deck& deck);
|
||||
void conveyNumericalAquiferEffects();
|
||||
void applyMULTXYZ();
|
||||
void initFaults(const Deck& deck);
|
||||
void initPara(const Deck& deck);
|
||||
|
||||
void setMULTFLT(const Opm::DeckSection& section, bool edit = false);
|
||||
void setMULTFLT(const Opm::DeckSection& section);
|
||||
|
||||
void complainAboutAmbiguousKeyword(const Deck& deck,
|
||||
const std::string& keywordName);
|
||||
@ -178,18 +164,14 @@ namespace Opm {
|
||||
NNC m_inputNnc;
|
||||
GridDims m_gridDims;
|
||||
FieldPropsManager field_props;
|
||||
LgrCollection m_lgrs;
|
||||
SimulationConfig m_simulationConfig;
|
||||
AquiferConfig aquifer_config;
|
||||
TransMult m_transMult;
|
||||
TracerConfig tracer_config;
|
||||
MICPpara m_micppara;
|
||||
WagHysteresisConfig wag_hyst_config;
|
||||
|
||||
std::string m_title{};
|
||||
FaultCollection m_faults{};
|
||||
|
||||
std::optional<std::map<std::string, double> > m_restart_network_pressures{std::nullopt};
|
||||
};
|
||||
} // namespace Opm
|
||||
|
||||
|
@ -55,7 +55,6 @@ namespace Opm
|
||||
{}
|
||||
};
|
||||
|
||||
Carfin() = default;
|
||||
|
||||
explicit Carfin(const GridDims& gridDims,
|
||||
IsActive isActive,
|
||||
@ -94,15 +93,6 @@ namespace Opm
|
||||
int NY() const;
|
||||
int NZ() const;
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(m_dims);
|
||||
serializer(m_offset);
|
||||
serializer(m_end_offset);
|
||||
serializer(name_grid);
|
||||
}
|
||||
|
||||
private:
|
||||
GridDims m_globalGridDims_{};
|
||||
IsActive m_globalIsActive_{};
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <stdexcept>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
@ -65,8 +64,7 @@ namespace Opm {
|
||||
EclipseGrid(const EclipseGrid& src, const double* zcorn, const std::vector<int>& actnum);
|
||||
|
||||
EclipseGrid(size_t nx, size_t ny, size_t nz,
|
||||
double dx = 1.0, double dy = 1.0, double dz = 1.0,
|
||||
double top = 0.0);
|
||||
double dx = 1.0, double dy = 1.0, double dz = 1.0);
|
||||
explicit EclipseGrid(const GridDims& gd);
|
||||
|
||||
EclipseGrid(const std::array<int, 3>& dims ,
|
||||
@ -77,7 +75,7 @@ namespace Opm {
|
||||
|
||||
/// EclipseGrid ignores ACTNUM in Deck, and therefore needs ACTNUM
|
||||
/// explicitly. If a null pointer is passed, every cell is active.
|
||||
explicit EclipseGrid(const Deck& deck, const int * actnum = nullptr);
|
||||
EclipseGrid(const Deck& deck, const int * actnum = nullptr);
|
||||
|
||||
static bool hasGDFILE(const Deck& deck);
|
||||
static bool hasCylindricalKeywords(const Deck& deck);
|
||||
@ -256,15 +254,12 @@ namespace Opm {
|
||||
std::vector<int> m_global_to_active;
|
||||
// Numerical aquifer cells, needs to be active
|
||||
std::unordered_set<size_t> m_aquifer_cells;
|
||||
// Keep track of aquifer cell depths
|
||||
std::map<size_t, double> m_aquifer_cell_depths;
|
||||
|
||||
// Radial grids need this for volume calculations.
|
||||
std::optional<std::vector<double>> m_thetav;
|
||||
std::optional<std::vector<double>> m_rv;
|
||||
|
||||
void updateNumericalAquiferCells(const Deck&);
|
||||
double computeCellGeometricDepth(size_t globalIndex) const;
|
||||
|
||||
void initGridFromEGridFile(Opm::EclIO::EclFile& egridfile, std::string fileName);
|
||||
void resetACTNUM( const int* actnum);
|
||||
|
@ -19,33 +19,23 @@
|
||||
#ifndef FIELDPROPS_HPP
|
||||
#define FIELDPROPS_HPP
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/Grid/Box.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/FieldData.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/Keywords.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/TranCalculator.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Runspec.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Util/OrderedMap.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Tables/TableManager.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Units/UnitSystem.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Deck/DeckSection.hpp>
|
||||
#include <opm/input/eclipse/Deck/value_status.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <opm/input/eclipse/Deck/value_status.hpp>
|
||||
#include <opm/input/eclipse/Deck/DeckSection.hpp>
|
||||
#include <opm/input/eclipse/Units/UnitSystem.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/Box.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Tables/TableManager.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Runspec.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/Keywords.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/TranCalculator.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/FieldData.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class Deck;
|
||||
@ -130,8 +120,7 @@ namespace ALIAS {
|
||||
|
||||
|
||||
namespace GRID {
|
||||
static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{"DISPERC",keyword_info<double>{}.unit_string("Length")},
|
||||
{"MULTPV", keyword_info<double>{}.init(1.0)},
|
||||
static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{"MULTPV", keyword_info<double>{}.init(1.0)},
|
||||
{"NTG", keyword_info<double>{}.init(1.0)},
|
||||
{"PORO", keyword_info<double>{}.distribute_top(true)},
|
||||
{"PERMX", keyword_info<double>{}.unit_string("Permeability").distribute_top(true)},
|
||||
@ -148,12 +137,6 @@ static const std::unordered_map<std::string, keyword_info<double>> double_keywor
|
||||
{"THCOIL", keyword_info<double>{}.unit_string("Energy/AbsoluteTemperature*Length*Time")},
|
||||
{"THCGAS", keyword_info<double>{}.unit_string("Energy/AbsoluteTemperature*Length*Time")},
|
||||
{"THCWATER",keyword_info<double>{}.unit_string("Energy/AbsoluteTemperature*Length*Time")},
|
||||
{"YMODULE", keyword_info<double>{}.unit_string("Giga*Pascal")},
|
||||
{"PRATIO", keyword_info<double>{}.unit_string("1")},
|
||||
{"BIOTCOEF", keyword_info<double>{}.unit_string("1")},
|
||||
{"POELCOEF", keyword_info<double>{}.unit_string("1")},
|
||||
{"THERMEXR", keyword_info<double>{}.unit_string("1/AbsoluteTemperature")},
|
||||
{"THELCOEF", keyword_info<double>{}.unit_string("Pressure/AbsoluteTemperature")},
|
||||
{"MULTX", keyword_info<double>{}.init(1.0).mult(true)},
|
||||
{"MULTX-", keyword_info<double>{}.init(1.0).mult(true)},
|
||||
{"MULTY", keyword_info<double>{}.init(1.0).mult(true)},
|
||||
@ -192,11 +175,7 @@ static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {
|
||||
}
|
||||
|
||||
namespace PROPS {
|
||||
static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{"SWATINIT", keyword_info<double>{}},
|
||||
{"PCG", keyword_info<double>{}.unit_string("Pressure")},
|
||||
{"IPCG", keyword_info<double>{}.unit_string("Pressure")},
|
||||
{"PCW", keyword_info<double>{}.unit_string("Pressure")},
|
||||
{"IPCW", keyword_info<double>{}.unit_string("Pressure")}};
|
||||
static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{"SWATINIT", keyword_info<double>{}}};
|
||||
static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {};
|
||||
|
||||
#define dirfunc(base) base, base "X", base "X-", base "Y", base "Y-", base "Z", base "Z-"
|
||||
@ -218,6 +197,10 @@ static const std::set<std::string> satfunc = {"SWLPC", "ISWLPC", "SGLPC", "ISGLP
|
||||
dirfunc("ISOGCR"),
|
||||
dirfunc("SWCR"),
|
||||
dirfunc("ISWCR"),
|
||||
dirfunc("PCW"),
|
||||
dirfunc("IPCW"),
|
||||
dirfunc("PCG"),
|
||||
dirfunc("IPCG"),
|
||||
dirfunc("KRW"),
|
||||
dirfunc("IKRW"),
|
||||
dirfunc("KRWR"),
|
||||
@ -233,7 +216,21 @@ static const std::set<std::string> satfunc = {"SWLPC", "ISWLPC", "SGLPC", "ISGLP
|
||||
dirfunc("KRGR"),
|
||||
dirfunc("IKRGR")};
|
||||
|
||||
#undef dirfunc
|
||||
static const std::map<std::string,std::string> sogcr_shift = {{"SOGCR", "SWL"},
|
||||
{"SOGCRX", "SWLX"},
|
||||
{"SOGCRX-", "SWLX-"},
|
||||
{"SOGCRY", "SWLY"},
|
||||
{"SOGCRY-", "SWLY-"},
|
||||
{"SOGCRZ", "SWLZ"},
|
||||
{"SOGCRZ-", "SWLZ-"},
|
||||
{"ISOGCR", "ISWL"},
|
||||
{"ISOGCRX", "ISWLX"},
|
||||
{"ISOGCRX-", "ISWLX-"},
|
||||
{"ISOGCRY", "ISWLY"},
|
||||
{"ISOGCRY-", "ISWLY-"},
|
||||
{"ISOGCRZ", "ISWLZ"},
|
||||
{"ISOGCRZ-", "ISWLZ-"}};
|
||||
|
||||
}
|
||||
|
||||
namespace REGIONS {
|
||||
@ -243,7 +240,6 @@ static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {
|
||||
{"FIPNUM", keyword_info<int>{}.init(1)},
|
||||
{"IMBNUM", keyword_info<int>{}.init(1)},
|
||||
{"OPERNUM", keyword_info<int>{}},
|
||||
{"STRESSEQUILNUM", keyword_info<int>{}.init(1)},
|
||||
{"MISCNUM", keyword_info<int>{}},
|
||||
{"MISCNUM", keyword_info<int>{}},
|
||||
{"PVTNUM", keyword_info<int>{}.init(1)},
|
||||
@ -298,7 +294,6 @@ static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {
|
||||
template <typename T>
|
||||
keyword_info<T> global_kw_info(const std::string& name, bool allow_unsupported = false);
|
||||
|
||||
bool is_oper_keyword(const std::string& name);
|
||||
} // end namespace keywords
|
||||
|
||||
} // end namespace FieldProps
|
||||
@ -328,6 +323,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum class GetStatus {
|
||||
OK = 1,
|
||||
INVALID_DATA = 2, // std::runtime_error
|
||||
@ -335,6 +332,8 @@ public:
|
||||
NOT_SUPPPORTED_KEYWORD = 4 // std::logic_error
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct FieldDataManager {
|
||||
const std::string& keyword;
|
||||
@ -385,9 +384,10 @@ public:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Normal constructor for FieldProps.
|
||||
FieldProps(const Deck& deck, const Phases& phases, const EclipseGrid& grid, const TableManager& table_arg);
|
||||
|
||||
/// Special case constructor used to process ACTNUM only.
|
||||
FieldProps(const Deck& deck, const EclipseGrid& grid);
|
||||
|
||||
@ -409,121 +409,102 @@ public:
|
||||
template <typename T>
|
||||
std::vector<std::string> keys() const;
|
||||
|
||||
|
||||
template <typename T>
|
||||
FieldDataManager<T>
|
||||
try_get(const std::string& keyword, const bool allow_unsupported = false)
|
||||
{
|
||||
if (!allow_unsupported && !FieldProps::template supported<T>(keyword)) {
|
||||
return { keyword, GetStatus::NOT_SUPPPORTED_KEYWORD, nullptr };
|
||||
FieldDataManager<T> try_get(const std::string& keyword,
|
||||
bool allow_unsupported=false) {
|
||||
if (!allow_unsupported && !FieldProps::supported<T>(keyword))
|
||||
return FieldDataManager<T>(keyword, GetStatus::NOT_SUPPPORTED_KEYWORD, nullptr);
|
||||
|
||||
const Fieldprops::FieldData<T> * field_data;
|
||||
bool has0 = this->has<T>(keyword);
|
||||
|
||||
field_data = std::addressof(this->init_get<T>(keyword,
|
||||
std::is_same<T,double>::value && allow_unsupported));
|
||||
if (field_data->valid() || allow_unsupported)
|
||||
return FieldDataManager<T>(keyword, GetStatus::OK, field_data);
|
||||
|
||||
if (!has0) {
|
||||
this->erase<T>(keyword);
|
||||
return FieldDataManager<T>(keyword, GetStatus::MISSING_KEYWORD, nullptr);
|
||||
}
|
||||
|
||||
const auto has0 = this->template has<T>(keyword);
|
||||
return FieldDataManager<T>(keyword, GetStatus::INVALID_DATA, nullptr);
|
||||
}
|
||||
|
||||
const auto& field_data =
|
||||
this->template init_get<T>(keyword, std::is_same<T,double>::value && allow_unsupported);
|
||||
|
||||
if (field_data.valid() || allow_unsupported) {
|
||||
// Note: FieldDataManager depends on init_get<>() producing a
|
||||
// long-lived FieldData instance.
|
||||
return { keyword, GetStatus::OK, &field_data };
|
||||
}
|
||||
|
||||
if (! has0) {
|
||||
this->template erase<T>(keyword);
|
||||
|
||||
return { keyword, GetStatus::MISSING_KEYWORD, nullptr };
|
||||
}
|
||||
|
||||
return { keyword, GetStatus::INVALID_DATA, nullptr };
|
||||
template <typename T>
|
||||
const std::vector<T>& get(const std::string& keyword) {
|
||||
const auto& data = this->try_get<T>(keyword);
|
||||
return data.data();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const std::vector<T>& get(const std::string& keyword)
|
||||
{
|
||||
return this->template try_get<T>(keyword).data();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> get_global(const std::string& keyword)
|
||||
{
|
||||
const auto managed_field_data = this->template try_get<T>(keyword);
|
||||
std::vector<T> get_global(const std::string& keyword) {
|
||||
const auto& managed_field_data = this->try_get<T>(keyword);
|
||||
const auto& field_data = managed_field_data.field_data();
|
||||
|
||||
const auto& kw_info = Fieldprops::keywords::
|
||||
template global_kw_info<T>(keyword);
|
||||
|
||||
return kw_info.global
|
||||
? *field_data.global_data
|
||||
: this->global_copy(field_data.data, kw_info.scalar_init);
|
||||
const auto& kw_info = Fieldprops::keywords::global_kw_info<T>(keyword);
|
||||
if (kw_info.global)
|
||||
return *field_data.global_data;
|
||||
else
|
||||
return this->global_copy(field_data.data, kw_info.scalar_init);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> get_copy(const std::string& keyword, bool global)
|
||||
{
|
||||
const auto has0 = this->template has<T>(keyword);
|
||||
|
||||
// Recall: FieldDataManager::field_data() will throw various
|
||||
// exception types if the 'status' is anything other than 'OK'.
|
||||
//
|
||||
// Get_copy() depends on this behaviour to not proceed to extracting
|
||||
// values in such cases. In other words, get_copy() uses exceptions
|
||||
// for control flow, and we cannot move this try_get() call into the
|
||||
// 'has0' branch even though the actual 'field_data' object returned
|
||||
// from try_get() is only needed/used there.
|
||||
const auto& field_data = this->template try_get<T>(keyword).field_data();
|
||||
template <typename T>
|
||||
std::vector<T> get_copy(const std::string& keyword, bool global) {
|
||||
bool has0 = this->has<T>(keyword);
|
||||
const auto& field_data = this->try_get<T>(keyword).field_data();
|
||||
|
||||
if (has0) {
|
||||
return this->get_copy(field_data.data, field_data.kw_info.scalar_init, global);
|
||||
if (global)
|
||||
return this->global_copy(field_data.data, field_data.kw_info.scalar_init);
|
||||
else
|
||||
return field_data.data;
|
||||
} else {
|
||||
if (global) {
|
||||
const auto& kw_info = Fieldprops::keywords::global_kw_info<T>(keyword);
|
||||
return this->global_copy(this->extract<T>(keyword), kw_info.scalar_init);
|
||||
} else
|
||||
return this->extract<T>(keyword);
|
||||
}
|
||||
|
||||
const auto initial_value = Fieldprops::keywords::
|
||||
template global_kw_info<T>(keyword).scalar_init;
|
||||
|
||||
return this->get_copy(this->template extract<T>(keyword), initial_value, global);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
std::vector<bool> defaulted(const std::string& keyword)
|
||||
{
|
||||
const auto& field = this->template init_get<T>(keyword);
|
||||
std::vector<bool> defaulted(const std::string& keyword) {
|
||||
const auto& field = this->init_get<T>(keyword);
|
||||
std::vector<bool> def(field.size());
|
||||
|
||||
for (std::size_t i = 0; i < def.size(); ++i) {
|
||||
def[i] = value::defaulted(field.value_status[i]);
|
||||
}
|
||||
for (std::size_t i=0; i < def.size(); i++)
|
||||
def[i] = value::defaulted( field.value_status[i]);
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> global_copy(const std::vector<T>& data,
|
||||
const std::optional<T>& default_value) const
|
||||
{
|
||||
const T fill_value = default_value.has_value() ? *default_value : 0;
|
||||
|
||||
std::vector<T> global_copy(const std::vector<T>& data, const std::optional<T>& default_value) const {
|
||||
T fill_value = default_value.has_value() ? *default_value : 0;
|
||||
std::vector<T> global_data(this->global_size, fill_value);
|
||||
|
||||
std::size_t i = 0;
|
||||
for (std::size_t g = 0; g < this->global_size; g++) {
|
||||
if (this->m_actnum[g]) {
|
||||
global_data[g] = data[i];
|
||||
++i;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return global_data;
|
||||
}
|
||||
|
||||
std::size_t active_size;
|
||||
std::size_t global_size;
|
||||
|
||||
std::size_t num_int() const
|
||||
{
|
||||
std::size_t num_int() const {
|
||||
return this->int_data.size();
|
||||
}
|
||||
|
||||
std::size_t num_double() const
|
||||
{
|
||||
std::size_t num_double() const {
|
||||
return this->double_data.size();
|
||||
}
|
||||
|
||||
@ -553,22 +534,6 @@ private:
|
||||
template <typename T>
|
||||
std::vector<T> extract(const std::string& keyword);
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> get_copy(const std::vector<T>& x,
|
||||
const std::optional<T>& initial_value,
|
||||
const bool global) const
|
||||
{
|
||||
return (! global) ? x : this->global_copy(x, initial_value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> get_copy(std::vector<T>&& x,
|
||||
const std::optional<T>& initial_value,
|
||||
const bool global) const
|
||||
{
|
||||
return (! global) ? std::move(x) : this->global_copy(x, initial_value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void operate(const DeckRecord& record, Fieldprops::FieldData<T>& target_data, const Fieldprops::FieldData<T>& src_data, const std::vector<Box::cell_index>& index_list);
|
||||
|
||||
@ -598,8 +563,6 @@ private:
|
||||
void init_satfunc(const std::string& keyword, Fieldprops::FieldData<double>& satfunc);
|
||||
void init_porv(Fieldprops::FieldData<double>& porv);
|
||||
void init_tempi(Fieldprops::FieldData<double>& tempi);
|
||||
std::string canonical_fipreg_name(const std::string& fipreg);
|
||||
const std::string& canonical_fipreg_name(const std::string& fipreg) const;
|
||||
|
||||
const UnitSystem unit_system;
|
||||
std::size_t nx,ny,nz;
|
||||
@ -615,7 +578,6 @@ private:
|
||||
std::vector<MultregpRecord> multregp;
|
||||
std::unordered_map<std::string, Fieldprops::FieldData<int>> int_data;
|
||||
std::unordered_map<std::string, Fieldprops::FieldData<double>> double_data;
|
||||
std::unordered_map<std::string, std::string> fipreg_shortname_translation{};
|
||||
|
||||
std::unordered_map<std::string,Fieldprops::TranCalculator> tran;
|
||||
};
|
||||
|
@ -69,7 +69,6 @@ public:
|
||||
|
||||
bool operator==(const FieldPropsManager& other) const;
|
||||
static bool rst_cmp(const FieldPropsManager& full_arg, const FieldPropsManager& rst_arg);
|
||||
|
||||
/*
|
||||
Because the FieldProps class can autocreate properties the semantics of
|
||||
get() and has() is slightly non intuitve:
|
||||
@ -137,8 +136,8 @@ public:
|
||||
contain said keyword, or if the keyword has not been fully initialized. If
|
||||
you ask for a totally unknown keyword the method will return nullptr.
|
||||
*/
|
||||
template <typename T>
|
||||
const std::vector<T>* try_get(const std::string& keyword) const;
|
||||
template <typename T> const std::vector<T>* try_get(const
|
||||
std::string& keyword) const;
|
||||
|
||||
/*
|
||||
You can ask whether the elements in the keyword have a default value -
|
||||
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2023 Equinor
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_PARSER_LGR_COLLECTION_HPP
|
||||
#define OPM_PARSER_LGR_COLLECTION_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/Util/OrderedMap.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/CarfinManager.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/Carfin.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class DeckRecord;
|
||||
class GridDims;
|
||||
class GRIDSection;
|
||||
|
||||
|
||||
class LgrCollection {
|
||||
public:
|
||||
LgrCollection();
|
||||
LgrCollection(const GRIDSection& gridSection, const EclipseGrid& grid);
|
||||
|
||||
static LgrCollection serializationTestObject();
|
||||
|
||||
explicit LgrCollection(const Deck& deck);
|
||||
|
||||
size_t size() const;
|
||||
bool hasLgr(const std::string& lgrName) const;
|
||||
Carfin& getLgr(const std::string& lgrName);
|
||||
const Carfin& getLgr(const std::string& lgrName) const;
|
||||
Carfin& getLgr(size_t lgrIndex);
|
||||
const Carfin& getLgr(size_t lgrIndex) const;
|
||||
|
||||
void addLgr(const EclipseGrid& grid, const DeckRecord& lgrRecord);
|
||||
|
||||
bool operator==(const LgrCollection& data) const;
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(m_lgrs);
|
||||
}
|
||||
|
||||
private:
|
||||
OrderedMap<Carfin, 8> m_lgrs;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // OPM_PARSER_LGR_COLLECTION_HPP
|
@ -17,31 +17,23 @@
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef OPM_PARSER_MULTREGTSCANNER_HPP
|
||||
#define OPM_PARSER_MULTREGTSCANNER_HPP
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/Grid/FaceDir.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/GridDims.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class DeckRecord;
|
||||
class DeckKeyword;
|
||||
class FieldPropsManager;
|
||||
|
||||
} // namespace Opm
|
||||
|
||||
namespace Opm {
|
||||
class GridDims;
|
||||
|
||||
namespace MULTREGT {
|
||||
enum class NNCBehaviourEnum
|
||||
{
|
||||
|
||||
|
||||
enum NNCBehaviourEnum {
|
||||
NNC = 1,
|
||||
NONNC = 2,
|
||||
ALL = 3,
|
||||
@ -50,10 +42,12 @@ namespace Opm {
|
||||
|
||||
std::string RegionNameFromDeckValue(const std::string& stringValue);
|
||||
NNCBehaviourEnum NNCBehaviourFromString(const std::string& stringValue);
|
||||
} // namespace MULTREGT
|
||||
}
|
||||
|
||||
struct MULTREGTRecord
|
||||
{
|
||||
|
||||
|
||||
|
||||
struct MULTREGTRecord {
|
||||
int src_value;
|
||||
int target_value;
|
||||
double trans_mult;
|
||||
@ -61,15 +55,13 @@ namespace Opm {
|
||||
MULTREGT::NNCBehaviourEnum nnc_behaviour;
|
||||
std::string region_name;
|
||||
|
||||
bool operator==(const MULTREGTRecord& data) const
|
||||
{
|
||||
return (src_value == data.src_value)
|
||||
&& (target_value == data.target_value)
|
||||
&& (trans_mult == data.trans_mult)
|
||||
&& (directions == data.directions)
|
||||
&& (nnc_behaviour == data.nnc_behaviour)
|
||||
&& (region_name == data.region_name)
|
||||
;
|
||||
bool operator==(const MULTREGTRecord& data) const {
|
||||
return src_value == data.src_value &&
|
||||
target_value == data.target_value &&
|
||||
trans_mult == data.trans_mult &&
|
||||
directions == data.directions &&
|
||||
nnc_behaviour == data.nnc_behaviour &&
|
||||
region_name == data.region_name;
|
||||
}
|
||||
|
||||
template<class Serializer>
|
||||
@ -84,62 +76,58 @@ namespace Opm {
|
||||
}
|
||||
};
|
||||
|
||||
class MULTREGTScanner
|
||||
{
|
||||
typedef std::map< std::pair<int , int> , const MULTREGTRecord * > MULTREGTSearchMap;
|
||||
typedef std::tuple<size_t , FaceDir::DirEnum , double> MULTREGTConnection;
|
||||
|
||||
|
||||
|
||||
class MULTREGTScanner {
|
||||
|
||||
public:
|
||||
using ExternalSearchMap = std::map<std::string, std::map<std::pair<int,int>, int>>;
|
||||
|
||||
MULTREGTScanner() = default;
|
||||
MULTREGTScanner(const MULTREGTScanner& data);
|
||||
MULTREGTScanner(const GridDims& grid,
|
||||
const FieldPropsManager* fp_arg,
|
||||
const std::vector<const DeckKeyword*>& keywords);
|
||||
const std::vector< const DeckKeyword* >& keywords);
|
||||
|
||||
static MULTREGTScanner serializationTestObject();
|
||||
|
||||
double getRegionMultiplier(size_t globalCellIdx1, size_t globalCellIdx2, FaceDir::DirEnum faceDir) const;
|
||||
|
||||
bool operator==(const MULTREGTScanner& data) const;
|
||||
MULTREGTScanner& operator=(const MULTREGTScanner& data);
|
||||
|
||||
void applyNumericalAquifer(const std::vector<std::size_t>& aquifer_cells);
|
||||
|
||||
double getRegionMultiplier(std::size_t globalCellIdx1,
|
||||
std::size_t globalCellIdx2,
|
||||
FaceDir::DirEnum faceDir) const;
|
||||
|
||||
double getRegionMultiplierNNC(std::size_t globalCellIdx1,
|
||||
std::size_t globalCellIdx2) const;
|
||||
|
||||
template <class Serializer>
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(gridDims);
|
||||
|
||||
serializer(nx);
|
||||
serializer(ny);
|
||||
serializer(nz);
|
||||
serializer(m_records);
|
||||
serializer(m_searchMap);
|
||||
|
||||
ExternalSearchMap searchMap = getSearchMap();
|
||||
serializer(searchMap);
|
||||
if (m_searchMap.empty())
|
||||
constructSearchMap(searchMap);
|
||||
serializer(regions);
|
||||
serializer(aquifer_cells);
|
||||
serializer(default_region);
|
||||
}
|
||||
|
||||
private:
|
||||
using MULTREGTSearchMap = std::map<
|
||||
std::pair<int, int>,
|
||||
std::vector<MULTREGTRecord>::size_type
|
||||
>;
|
||||
ExternalSearchMap getSearchMap() const;
|
||||
void constructSearchMap(const ExternalSearchMap& searchMap);
|
||||
|
||||
GridDims gridDims{};
|
||||
const FieldPropsManager* fp{nullptr};
|
||||
|
||||
std::vector<MULTREGTRecord> m_records{};
|
||||
std::map<std::string, MULTREGTSearchMap> m_searchMap{};
|
||||
std::map<std::string, std::vector<int>> regions{};
|
||||
std::vector<std::size_t> aquifer_cells{};
|
||||
|
||||
void addKeyword(const DeckKeyword& deckKeyword);
|
||||
void addKeyword( const DeckKeyword& deckKeyword, const std::string& defaultRegion);
|
||||
void assertKeywordSupported(const DeckKeyword& deckKeyword);
|
||||
|
||||
bool isAquNNC(std::size_t globalCellIdx1, std::size_t globalCellIdx2) const;
|
||||
bool isAquCell(std::size_t globalCellIdx) const;
|
||||
std::size_t nx = 0,ny = 0, nz = 0;
|
||||
const FieldPropsManager* fp = nullptr;
|
||||
std::vector< MULTREGTRecord > m_records;
|
||||
std::map<std::string , MULTREGTSearchMap> m_searchMap;
|
||||
std::map<std::string, std::vector<int>> regions;
|
||||
std::string default_region;
|
||||
};
|
||||
|
||||
} // namespace Opm
|
||||
}
|
||||
|
||||
#endif // OPM_PARSER_MULTREGTSCANNER_HPP
|
||||
|
@ -56,11 +56,9 @@ namespace Opm {
|
||||
double getMultiplier(size_t globalIndex, FaceDir::DirEnum faceDir) const;
|
||||
double getMultiplier(size_t i , size_t j , size_t k, FaceDir::DirEnum faceDir) const;
|
||||
double getRegionMultiplier( size_t globalCellIndex1, size_t globalCellIndex2, FaceDir::DirEnum faceDir) const;
|
||||
double getRegionMultiplierNNC(std::size_t globalCellIndex1, std::size_t globalCellIndex2) const;
|
||||
void applyMULT(const std::vector<double>& srcMultProp, FaceDir::DirEnum faceDir);
|
||||
void applyMULTFLT(const FaultCollection& faults);
|
||||
void applyMULTFLT(const Fault& fault);
|
||||
void applyNumericalAquifer(const std::vector<std::size_t>& aquifer_cells);
|
||||
|
||||
bool operator==(const TransMult& data) const;
|
||||
|
||||
|
@ -1,94 +0,0 @@
|
||||
/*
|
||||
Copyright 2023 SINTEF Digital
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_FIP_CONFIG_HPP
|
||||
#define OPM_FIP_CONFIG_HPP
|
||||
|
||||
#include <bitset>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class Deck;
|
||||
class DeckKeyword;
|
||||
class RPTConfig;
|
||||
|
||||
//! \brief Class holding FIP configuration from RPTSOL/RPTSCHED keyword.
|
||||
class FIPConfig {
|
||||
public:
|
||||
//! \brief Enumeration of FIP report outputs.
|
||||
enum class OutputField {
|
||||
FIELD = 0, //!< Whole field
|
||||
FIPNUM = 1, //!< FIPNUM regions
|
||||
FIP = 2, //!< FIP defined regions
|
||||
FOAM_FIELD = 3, //!< Foam field report
|
||||
FOAM_REGION = 4, //!< Foam region report
|
||||
POLYMER_FIELD = 5, //!< Polymer field report
|
||||
POLYMER_REGION = 6, //!< Polymer region report
|
||||
RESV = 7, //!< RESV report
|
||||
SOLVENT_FIELD = 8, //!< Solvent field report
|
||||
SOLVENT_REGION = 9, //!< Solvent region report
|
||||
TEMPERATURE_FIELD = 10, //!< Temperature field report
|
||||
TEMPERATURE_REGION = 11, //!< Temperature region report
|
||||
SURF_FIELD = 12, //!< Surfacant field report
|
||||
SURF_REGION = 13, //!< Surfacant region report
|
||||
TRACER_FIELD = 14, //!< Tracer field report
|
||||
TRACER_REGION = 15, //!< Tracer region report
|
||||
VE = 16, //!< VE (oil, water, gas) zone report
|
||||
NUM_FIP_REPORT = 17, //!< Number of configuration flags
|
||||
};
|
||||
|
||||
//! \brief Default constructor.
|
||||
FIPConfig() = default;
|
||||
|
||||
//! \brief Construct from RPTSOL keyword if deck holds one.
|
||||
explicit FIPConfig(const Deck& deck);
|
||||
|
||||
//! \brief Construct from given keyword (RPTSOL or RPTSCHED).
|
||||
explicit FIPConfig(const DeckKeyword& keyword);
|
||||
|
||||
//! \brief Construct from given RTPConfig.
|
||||
explicit FIPConfig(const RPTConfig& rptConfig);
|
||||
|
||||
//! \brief Returns a test object used for serialization tests.
|
||||
static FIPConfig serializationTestObject();
|
||||
|
||||
//! \brief (De-)serialization handler.
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(m_flags);
|
||||
}
|
||||
|
||||
//! \brief Query if FIP output is enabled for a given field.
|
||||
bool output(OutputField field) const;
|
||||
|
||||
//! \brief Comparison operator.
|
||||
bool operator==(const FIPConfig& rhs) const;
|
||||
|
||||
private:
|
||||
//! \brief Initialize flags based on mnemonics in a RPTConfig instance.
|
||||
void parseRPT(const RPTConfig& rptConfig);
|
||||
|
||||
//! \brief Bitset holding enable status for fields
|
||||
std::bitset<static_cast<int>(OutputField::NUM_FIP_REPORT)> m_flags = {};
|
||||
};
|
||||
|
||||
} //namespace Opm
|
||||
|
||||
#endif
|
@ -6,21 +6,8 @@
|
||||
|
||||
namespace Opm {
|
||||
class DeckKeyword;
|
||||
class DeckRecord;
|
||||
|
||||
class EquilRecord {
|
||||
public:
|
||||
EquilRecord() = default;
|
||||
EquilRecord(double datum_depth_arg, double datum_depth_pc_arg,
|
||||
double woc_depth, double woc_pc,
|
||||
double goc_depth, double goc_pc,
|
||||
bool live_oil_init,
|
||||
bool wet_gas_init,
|
||||
int target_accuracy,
|
||||
bool humid_gas_init);
|
||||
explicit EquilRecord(const DeckRecord& record);
|
||||
|
||||
static EquilRecord serializationTestObject();
|
||||
double datumDepth() const;
|
||||
double datumDepthPressure() const;
|
||||
double waterOilContactDepth() const;
|
||||
@ -33,6 +20,10 @@ namespace Opm {
|
||||
int initializationTargetAccuracy() const;
|
||||
bool humidGasInitConstantRvw() const;
|
||||
|
||||
EquilRecord();
|
||||
|
||||
EquilRecord( double datum_depth_arg, double datum_depth_pc_arg, double woc_depth, double woc_pc, double goc_depth, double goc_pc, bool live_oil_init, bool wet_gas_init, int target_accuracy, bool humid_gas_init);
|
||||
|
||||
bool operator==(const EquilRecord& data) const;
|
||||
|
||||
template<class Serializer>
|
||||
@ -51,75 +42,29 @@ namespace Opm {
|
||||
}
|
||||
|
||||
private:
|
||||
double datum_depth = 0.0;
|
||||
double datum_depth_ps = 0.0;
|
||||
double water_oil_contact_depth = 0.0;
|
||||
double water_oil_contact_capillary_pressure = 0.0;
|
||||
double gas_oil_contact_depth = 0.0;
|
||||
double gas_oil_contact_capillary_pressure = 0.0;
|
||||
double datum_depth;
|
||||
double datum_depth_ps;
|
||||
double water_oil_contact_depth;
|
||||
double water_oil_contact_capillary_pressure;
|
||||
double gas_oil_contact_depth;
|
||||
double gas_oil_contact_capillary_pressure;
|
||||
|
||||
bool live_oil_init_proc = false;
|
||||
bool wet_gas_init_proc = false;
|
||||
int init_target_accuracy = 0;
|
||||
bool humid_gas_init_proc = false;
|
||||
bool live_oil_init_proc;
|
||||
bool wet_gas_init_proc;
|
||||
int init_target_accuracy;
|
||||
bool humid_gas_init_proc;
|
||||
};
|
||||
|
||||
class StressEquilRecord {
|
||||
class Equil {
|
||||
public:
|
||||
StressEquilRecord() = default;
|
||||
explicit StressEquilRecord(const DeckRecord& record);
|
||||
using const_iterator = std::vector< EquilRecord >::const_iterator;
|
||||
|
||||
static StressEquilRecord serializationTestObject();
|
||||
Equil() = default;
|
||||
explicit Equil( const DeckKeyword& );
|
||||
|
||||
bool operator==(const StressEquilRecord& data) const;
|
||||
static Equil serializationTestObject();
|
||||
|
||||
double datumDepth() const;
|
||||
double datumPosX() const;
|
||||
double datumPosY() const;
|
||||
double stressXX() const;
|
||||
double stressXX_grad() const;
|
||||
double stressYY() const;
|
||||
double stressYY_grad() const;
|
||||
double stressZZ() const;
|
||||
double stressZZ_grad() const;
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(datum_depth);
|
||||
serializer(datum_posx);
|
||||
serializer(datum_posy);
|
||||
serializer(stress_xx);
|
||||
serializer(stress_xx_grad);
|
||||
serializer(stress_yy);
|
||||
serializer(stress_yy_grad);
|
||||
serializer(stress_zz);
|
||||
serializer(stress_zz_grad);
|
||||
}
|
||||
|
||||
private:
|
||||
double datum_depth = 0.0;
|
||||
double datum_posx = 0.0;
|
||||
double datum_posy = 0.0;
|
||||
double stress_xx = 0.0;
|
||||
double stress_xx_grad = 0.0;
|
||||
double stress_yy = 0.0;
|
||||
double stress_yy_grad = 0.0;
|
||||
double stress_zz = 0.0;
|
||||
double stress_zz_grad = 0.0;
|
||||
};
|
||||
|
||||
template<class RecordType>
|
||||
class EquilContainer {
|
||||
public:
|
||||
using const_iterator = typename std::vector<RecordType>::const_iterator;
|
||||
|
||||
EquilContainer() = default;
|
||||
explicit EquilContainer( const DeckKeyword& );
|
||||
|
||||
static EquilContainer serializationTestObject();
|
||||
|
||||
const RecordType& getRecord(std::size_t id) const;
|
||||
const EquilRecord& getRecord( size_t id ) const;
|
||||
|
||||
size_t size() const;
|
||||
bool empty() const;
|
||||
@ -127,7 +72,7 @@ namespace Opm {
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
||||
bool operator==(const EquilContainer& data) const;
|
||||
bool operator==(const Equil& data) const;
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
@ -136,11 +81,9 @@ namespace Opm {
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<RecordType> m_records;
|
||||
std::vector< EquilRecord > m_records;
|
||||
};
|
||||
|
||||
using Equil = EquilContainer<EquilRecord>;
|
||||
using StressEquil = EquilContainer<StressEquilRecord>;
|
||||
}
|
||||
|
||||
#endif //OPM_EQUIL_HPP
|
||||
|
@ -45,9 +45,6 @@ namespace Opm {
|
||||
bool hasEquil() const;
|
||||
const Equil& getEquil() const;
|
||||
|
||||
bool hasStressEquil() const;
|
||||
const StressEquil& getStressEquil() const;
|
||||
|
||||
bool hasGravity() const;
|
||||
|
||||
bool hasFoamConfig() const;
|
||||
@ -67,7 +64,6 @@ namespace Opm {
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(equil);
|
||||
serializer(stress_equil);
|
||||
serializer(foamconfig);
|
||||
serializer(m_filleps);
|
||||
serializer(m_gravity);
|
||||
@ -78,7 +74,6 @@ namespace Opm {
|
||||
|
||||
private:
|
||||
Equil equil;
|
||||
StressEquil stress_equil;
|
||||
FoamConfig foamconfig;
|
||||
bool m_filleps;
|
||||
bool m_gravity = true;
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <string>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class Deck;
|
||||
|
||||
class Phases {
|
||||
@ -94,8 +95,7 @@ public:
|
||||
return this->nDynWlistMax;
|
||||
}
|
||||
|
||||
const std::optional<KeywordLocation>& location() const
|
||||
{
|
||||
const std::optional<KeywordLocation>& location() const {
|
||||
return this->m_location;
|
||||
}
|
||||
|
||||
@ -113,6 +113,7 @@ public:
|
||||
rst_cmp(*this, data);
|
||||
}
|
||||
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
@ -142,6 +143,7 @@ public:
|
||||
|
||||
static WellSegmentDims serializationTestObject();
|
||||
|
||||
|
||||
int maxSegmentedWells() const
|
||||
{
|
||||
return this->nSegWellMax;
|
||||
@ -157,11 +159,6 @@ public:
|
||||
return this->nLatBranchMax;
|
||||
}
|
||||
|
||||
const std::optional<KeywordLocation>& location() const
|
||||
{
|
||||
return this->location_;
|
||||
}
|
||||
|
||||
bool operator==(const WellSegmentDims& data) const;
|
||||
|
||||
template<class Serializer>
|
||||
@ -170,14 +167,12 @@ public:
|
||||
serializer(nSegWellMax);
|
||||
serializer(nSegmentMax);
|
||||
serializer(nLatBranchMax);
|
||||
serializer(location_);
|
||||
}
|
||||
|
||||
private:
|
||||
int nSegWellMax;
|
||||
int nSegmentMax;
|
||||
int nLatBranchMax;
|
||||
std::optional<KeywordLocation> location_;
|
||||
};
|
||||
|
||||
class NetworkDims {
|
||||
@ -299,11 +294,6 @@ public:
|
||||
*/
|
||||
double curvatureCapPrs() const;
|
||||
|
||||
/*!
|
||||
* \brief Wag hysteresis.
|
||||
*/
|
||||
bool activeWag() const;
|
||||
|
||||
bool operator==(const EclHysterConfig& data) const;
|
||||
|
||||
template<class Serializer>
|
||||
@ -314,7 +304,6 @@ public:
|
||||
serializer(krHystMod);
|
||||
serializer(modParamTrappedValue);
|
||||
serializer(curvatureCapPrsValue);
|
||||
serializer(activeWagHyst);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -328,9 +317,6 @@ private:
|
||||
double modParamTrappedValue { 0.1 };
|
||||
// curvature parameter for capillary pressure
|
||||
double curvatureCapPrsValue { 0.1 };
|
||||
|
||||
// enable WAG hysteresis
|
||||
bool activeWagHyst { false };
|
||||
};
|
||||
|
||||
class SatFuncControls {
|
||||
@ -343,9 +329,8 @@ public:
|
||||
|
||||
enum class KeywordFamily {
|
||||
Family_I, // SGOF, SWOF, SLGOF
|
||||
Family_II, // SGFN, SOF{2,3}, SWFN, SGWFN
|
||||
Family_III, // GSF, WSF
|
||||
|
||||
Family_II, // SGFN, SOF{2,3}, SWFN
|
||||
Family_III, // GSF, WSF
|
||||
Undefined,
|
||||
};
|
||||
|
||||
@ -470,9 +455,7 @@ public:
|
||||
const Nupcol& nupcol() const noexcept;
|
||||
const Tracers& tracers() const;
|
||||
bool co2Storage() const noexcept;
|
||||
bool h2Storage() const noexcept;
|
||||
bool micp() const noexcept;
|
||||
bool mech() const noexcept;
|
||||
|
||||
bool operator==(const Runspec& data) const;
|
||||
static bool rst_cmp(const Runspec& full_state, const Runspec& rst_state);
|
||||
@ -495,9 +478,7 @@ public:
|
||||
serializer(m_sfuncctrl);
|
||||
serializer(m_nupcol);
|
||||
serializer(m_co2storage);
|
||||
serializer(m_h2storage);
|
||||
serializer(m_micp);
|
||||
serializer(m_mech);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -517,9 +498,7 @@ private:
|
||||
Nupcol m_nupcol;
|
||||
Tracers m_tracers;
|
||||
bool m_co2storage;
|
||||
bool m_h2storage;
|
||||
bool m_micp;
|
||||
bool m_mech;
|
||||
};
|
||||
|
||||
|
||||
|
@ -33,34 +33,59 @@ namespace Opm {
|
||||
class Deck;
|
||||
class DeckRecord;
|
||||
|
||||
enum class BCType {
|
||||
RATE,
|
||||
FREE,
|
||||
DIRICHLET,
|
||||
THERMAL
|
||||
};
|
||||
|
||||
enum class BCComponent {
|
||||
OIL,
|
||||
GAS,
|
||||
WATER,
|
||||
SOLVENT,
|
||||
POLYMER,
|
||||
NONE
|
||||
};
|
||||
|
||||
|
||||
class BCConfig {
|
||||
public:
|
||||
|
||||
struct BCRegion {
|
||||
int index;
|
||||
struct BCFace {
|
||||
int i1,i2;
|
||||
int j1,j2;
|
||||
int k1,k2;
|
||||
BCType bctype;
|
||||
FaceDir::DirEnum dir;
|
||||
BCComponent component;
|
||||
double rate;
|
||||
std::optional<double> pressure;
|
||||
std::optional<double> temperature;
|
||||
|
||||
BCRegion() = default;
|
||||
explicit BCRegion(const DeckRecord& record, const GridDims& grid);
|
||||
BCFace() = default;
|
||||
explicit BCFace(const DeckRecord& record, const GridDims& grid);
|
||||
|
||||
static BCRegion serializationTestObject();
|
||||
static BCFace serializationTestObject();
|
||||
|
||||
bool operator==(const BCRegion& other) const;
|
||||
bool operator==(const BCFace& other) const;
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(index);
|
||||
serializer(i1);
|
||||
serializer(i2);
|
||||
serializer(j1);
|
||||
serializer(j2);
|
||||
serializer(k1);
|
||||
serializer(k2);
|
||||
serializer(bctype);
|
||||
serializer(dir);
|
||||
serializer(component);
|
||||
serializer(rate);
|
||||
serializer(pressure);
|
||||
serializer(temperature);
|
||||
}
|
||||
};
|
||||
|
||||
@ -71,8 +96,8 @@ public:
|
||||
static BCConfig serializationTestObject();
|
||||
|
||||
std::size_t size() const;
|
||||
std::vector<BCRegion>::const_iterator begin() const;
|
||||
std::vector<BCRegion>::const_iterator end() const;
|
||||
std::vector<BCFace>::const_iterator begin() const;
|
||||
std::vector<BCFace>::const_iterator end() const;
|
||||
bool operator==(const BCConfig& other) const;
|
||||
|
||||
template<class Serializer>
|
||||
@ -82,7 +107,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<BCRegion> m_faces;
|
||||
std::vector<BCFace> m_faces;
|
||||
};
|
||||
|
||||
} //namespace Opm
|
||||
|
@ -20,7 +20,6 @@
|
||||
#ifndef OPM_ROCK_CONFIG_HPP
|
||||
#define OPM_ROCK_CONFIG_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -29,36 +28,36 @@ namespace Opm {
|
||||
class Deck;
|
||||
class FieldPropsManager;
|
||||
|
||||
class RockConfig
|
||||
{
|
||||
class RockConfig {
|
||||
public:
|
||||
enum class Hysteresis
|
||||
|
||||
enum class Hysteresis {
|
||||
REVERS = 1,
|
||||
IRREVERS = 2,
|
||||
HYSTER = 3,
|
||||
BOBERG = 4,
|
||||
REVLIMIT = 5,
|
||||
PALM_MAN = 6,
|
||||
NONE = 7
|
||||
};
|
||||
|
||||
|
||||
struct RockComp {
|
||||
double pref;
|
||||
double compressibility;
|
||||
|
||||
RockComp() = default;
|
||||
RockComp(double pref_arg, double comp_arg);
|
||||
bool operator==(const RockComp& other) const;
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
REVERS = 1,
|
||||
IRREVERS = 2,
|
||||
HYSTER = 3,
|
||||
BOBERG = 4,
|
||||
REVLIMIT = 5,
|
||||
PALM_MAN = 6,
|
||||
NONE = 7,
|
||||
};
|
||||
serializer(pref);
|
||||
serializer(compressibility);
|
||||
}
|
||||
};
|
||||
|
||||
struct RockComp
|
||||
{
|
||||
double pref{};
|
||||
double compressibility{};
|
||||
|
||||
RockComp() = default;
|
||||
RockComp(double pref_arg, double comp_arg);
|
||||
bool operator==(const RockComp& other) const;
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(pref);
|
||||
serializer(compressibility);
|
||||
}
|
||||
};
|
||||
|
||||
RockConfig();
|
||||
RockConfig(const Deck& deck, const FieldPropsManager& fp);
|
||||
@ -71,7 +70,6 @@ public:
|
||||
std::size_t num_rock_tables() const;
|
||||
Hysteresis hysteresis_mode() const;
|
||||
bool water_compaction() const;
|
||||
bool dispersion() const;
|
||||
|
||||
bool operator==(const RockConfig& other) const;
|
||||
|
||||
@ -84,7 +82,6 @@ public:
|
||||
serializer(num_tables);
|
||||
serializer(m_water_compaction);
|
||||
serializer(hyst_mode);
|
||||
serializer(m_dispersion);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -94,9 +91,8 @@ private:
|
||||
std::size_t num_tables = 0;
|
||||
bool m_water_compaction = false;
|
||||
Hysteresis hyst_mode = Hysteresis::REVERS;
|
||||
bool m_dispersion = false;
|
||||
};
|
||||
|
||||
} //namespace Opm
|
||||
|
||||
#endif // OPM_ROCK_CONFIG_HPP
|
||||
#endif
|
||||
|
@ -96,6 +96,12 @@ struct GravityTable : public FlatTableWithCopy<GRAVITYRecord>
|
||||
{
|
||||
return GravityTable({{1.0, 2.0, 3.0}});
|
||||
}
|
||||
|
||||
template <class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
FlatTableWithCopy::serializeOp(serializer);
|
||||
}
|
||||
};
|
||||
|
||||
struct DENSITYRecord {
|
||||
@ -131,6 +137,12 @@ struct DensityTable : public FlatTableWithCopy<DENSITYRecord>
|
||||
{
|
||||
return DensityTable({{1.0, 2.0, 3.0}});
|
||||
}
|
||||
|
||||
template <class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
FlatTableWithCopy::serializeOp(serializer);
|
||||
}
|
||||
};
|
||||
|
||||
struct DiffCoeffRecord {
|
||||
@ -274,6 +286,12 @@ struct PvtwTable : public FlatTableWithCopy<PVTWRecord>
|
||||
{
|
||||
return PvtwTable({{1.0, 2.0, 3.0, 4.0, 5.0}});
|
||||
}
|
||||
|
||||
template <class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
FlatTableWithCopy::serializeOp(serializer);
|
||||
}
|
||||
};
|
||||
|
||||
struct ROCKRecord {
|
||||
@ -295,11 +313,8 @@ struct ROCKRecord {
|
||||
}
|
||||
};
|
||||
|
||||
struct RockTable : public FlatTableWithCopy<ROCKRecord>
|
||||
{
|
||||
RockTable() = default;
|
||||
explicit RockTable(const DeckKeyword& kw);
|
||||
explicit RockTable(std::initializer_list<ROCKRecord> records);
|
||||
struct RockTable : public FlatTable< ROCKRecord > {
|
||||
using FlatTable< ROCKRecord >::FlatTable;
|
||||
|
||||
static RockTable serializationTestObject()
|
||||
{
|
||||
|
@ -24,14 +24,15 @@
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class Deck;
|
||||
class DeckItem;
|
||||
|
||||
class GasvisctTable : public SimpleTable {
|
||||
public:
|
||||
GasvisctTable( const DeckItem& item, const int tableID );
|
||||
GasvisctTable( const Deck& deck, const DeckItem& deckItem );
|
||||
|
||||
const TableColumn& getTemperatureColumn() const;
|
||||
const TableColumn& getGasViscosityColumn() const;
|
||||
const TableColumn& getGasViscosityColumn(size_t compIdx) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ namespace Opm {
|
||||
class PlymaxTable : public SimpleTable {
|
||||
public:
|
||||
|
||||
explicit PlymaxTable(const DeckRecord& record);
|
||||
PlymaxTable( const DeckRecord& record );
|
||||
|
||||
const TableColumn& getPolymerConcentrationColumn() const;
|
||||
const TableColumn& getMaxPolymerConcentrationColumn() const;
|
||||
|
@ -23,13 +23,13 @@
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class DeckRecord;
|
||||
class DeckReckord;
|
||||
|
||||
class PlyrockTable : public SimpleTable {
|
||||
public:
|
||||
|
||||
// This is not really a table; every column has only one element.
|
||||
explicit PlyrockTable(const DeckRecord& record);
|
||||
PlyrockTable( const DeckRecord& record );
|
||||
|
||||
// since this keyword is not necessarily monotonic, it cannot be evaluated!
|
||||
//using SimpleTable::evaluate;
|
||||
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2023 Equinor
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef PPCWMAX_HPP
|
||||
#define PPCWMAX_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
class Deck;
|
||||
|
||||
struct PpcwmaxRecord {
|
||||
double max_cap_pres;
|
||||
bool option;
|
||||
|
||||
PpcwmaxRecord() = default;
|
||||
PpcwmaxRecord(double pres, bool optn) :
|
||||
max_cap_pres(pres),
|
||||
option(optn)
|
||||
{};
|
||||
|
||||
bool operator==(const PpcwmaxRecord& other) const {
|
||||
return this->max_cap_pres == other.max_cap_pres &&
|
||||
this->option == other.option;
|
||||
}
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(max_cap_pres);
|
||||
serializer(option);
|
||||
}
|
||||
};
|
||||
|
||||
class Ppcwmax {
|
||||
public:
|
||||
Ppcwmax() = default;
|
||||
explicit Ppcwmax(const Deck& deck);
|
||||
explicit Ppcwmax(std::initializer_list<PpcwmaxRecord> records);
|
||||
static Ppcwmax serializationTestObject();
|
||||
std::size_t size() const;
|
||||
bool empty() const;
|
||||
std::vector< PpcwmaxRecord >::const_iterator begin() const;
|
||||
std::vector< PpcwmaxRecord >::const_iterator end() const;
|
||||
const PpcwmaxRecord& operator[](const std::size_t index) const;
|
||||
|
||||
bool operator==(const Ppcwmax& other) const {
|
||||
return this->data == other.data;
|
||||
}
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(data);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<PpcwmaxRecord> data;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -57,7 +57,6 @@
|
||||
#include <opm/input/eclipse/EclipseState/Tables/Eqldims.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Tables/Regdims.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Tables/TLMixpar.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Tables/Ppcwmax.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
@ -79,7 +78,6 @@ namespace Opm {
|
||||
const Aqudims& getAqudims() const;
|
||||
const Regdims& getRegdims() const;
|
||||
const TLMixpar& getTLMixpar() const;
|
||||
const Ppcwmax& getPpcwmax() const;
|
||||
/*
|
||||
WIll return max{ Tabdims::NTFIP , Regdims::NTFIP }.
|
||||
*/
|
||||
@ -262,7 +260,6 @@ namespace Opm {
|
||||
serializer(m_rtemp);
|
||||
serializer(m_salinity);
|
||||
serializer(m_tlmixpar);
|
||||
serializer(m_ppcwmax);
|
||||
if (!serializer.isSerializing()) {
|
||||
m_simpleTables = simpleTables;
|
||||
if (split.plyshMax > 0) {
|
||||
@ -292,6 +289,7 @@ namespace Opm {
|
||||
void initRTempTables(const Deck& deck);
|
||||
void initDims(const Deck& deck);
|
||||
void initRocktabTables(const Deck& deck);
|
||||
void initGasvisctTables(const Deck& deck);
|
||||
|
||||
void initPlymaxTables(const Deck& deck);
|
||||
void initPlyrockTables(const Deck& deck);
|
||||
@ -394,7 +392,6 @@ namespace Opm {
|
||||
Eqldims m_eqldims;
|
||||
Aqudims m_aqudims;
|
||||
TLMixpar m_tlmixpar;
|
||||
Ppcwmax m_ppcwmax;
|
||||
|
||||
bool hasImptvd = false;// if deck has keyword IMPTVD
|
||||
bool hasEnptvd = false;// if deck has keyword ENPTVD
|
||||
|
@ -20,19 +20,14 @@
|
||||
#ifndef OPM_ORDERED_MAP_HPP
|
||||
#define OPM_ORDERED_MAP_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <cctype>
|
||||
#include <algorithm>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
@ -73,11 +68,11 @@ findSimilarStrings(std::string str,
|
||||
return concatedStr.substr(0, concatedStr.size()-2);
|
||||
}
|
||||
|
||||
template<std::string_view::size_type MAX_CHARS>
|
||||
template<std::size_t MAX_CHARS>
|
||||
class TruncatedStringHash
|
||||
{
|
||||
public:
|
||||
std::size_t operator()(std::string_view key) const
|
||||
std::size_t operator()(const std::string_view& key) const
|
||||
{
|
||||
return hasher(key.substr(0, MAX_CHARS));
|
||||
}
|
||||
@ -87,13 +82,13 @@ private:
|
||||
|
||||
|
||||
template<>
|
||||
class TruncatedStringHash<std::string_view::npos> : public std::hash<std::string_view>
|
||||
class TruncatedStringHash<std::string::npos> : public std::hash<std::string_view>
|
||||
{};
|
||||
|
||||
template<std::string_view::size_type MAX_CHARS>
|
||||
template<std::size_t MAX_CHARS>
|
||||
struct TruncatedStringEquals
|
||||
{
|
||||
bool operator()(std::string_view str1, std::string_view str2) const
|
||||
bool operator()(const std::string& str1, const std::string& str2) const
|
||||
{
|
||||
return str1.substr(0, MAX_CHARS) == str2.substr(0, MAX_CHARS);
|
||||
}
|
||||
@ -107,23 +102,21 @@ struct TruncatedStringEquals<std::string::npos> : public std::equal_to<std::stri
|
||||
|
||||
/// \brief A map with iteration in the order of insertion.
|
||||
///
|
||||
/// Each entry has an associated index indicating when a value with that key
|
||||
/// was first inserted. When iterating over the entries, elements with a
|
||||
/// lower insertion index are traversed before elements with a higher
|
||||
/// insertion index.
|
||||
/// Each entry has an associated index indicating when a value with that key was
|
||||
/// first inserted. When itering over it's entries values with lower insertion index
|
||||
/// are traversed before ones with an higher insertion index.
|
||||
///
|
||||
/// \tparam T Element type. The map's value type is \code pair<string, T> \endcode.
|
||||
///
|
||||
/// \tparam MAX_CHARS Maximum number of characters used in key comparisons.
|
||||
/// Default value honors all characters. Keys with the
|
||||
/// \tparam MAX_CHARS The maximum number of characters that are use a keys. Default is
|
||||
/// std::string::npos, which honors all characters. Any keys with the
|
||||
/// same first MAX_CHARS characters are considered equal.
|
||||
template <typename T, std::string_view::size_type MAX_CHARS = std::string_view::npos>
|
||||
///
|
||||
template <typename T, std::size_t MAX_CHARS = std::string::npos>
|
||||
class OrderedMap {
|
||||
public:
|
||||
using storage_type = std::vector<std::pair<std::string, T>>;
|
||||
using index_type = std::unordered_map<std::string, typename storage_type::size_type,
|
||||
OrderedMapDetail::TruncatedStringHash<MAX_CHARS>,
|
||||
OrderedMapDetail::TruncatedStringEquals<MAX_CHARS>>;
|
||||
using storage_type = typename std::vector<std::pair<std::string,T>>;
|
||||
using index_type = typename std::unordered_map<std::string,std::size_t,
|
||||
Opm::OrderedMapDetail::TruncatedStringHash<MAX_CHARS>,
|
||||
Opm::OrderedMapDetail::TruncatedStringEquals<MAX_CHARS>>;
|
||||
using iter_type = typename storage_type::iterator;
|
||||
using const_iter_type = typename storage_type::const_iterator;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user