Added profile calculation
This commit is contained in:
@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.30)
|
cmake_minimum_required(VERSION 3.30)
|
||||||
project(Sim_C__)
|
project(Sim_C__)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 26)
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "-static")
|
set(CMAKE_EXE_LINKER_FLAGS "-static")
|
||||||
add_executable(Sim_C__
|
add_executable(Sim_C__
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
@ -42,6 +42,10 @@ add_executable(Sim_C__
|
|||||||
src/helper/CsvBinary.cpp
|
src/helper/CsvBinary.cpp
|
||||||
src/helper/CsvBinary.h
|
src/helper/CsvBinary.h
|
||||||
tests/helper/test_CsvBinary.cpp
|
tests/helper/test_CsvBinary.cpp
|
||||||
|
src/helper/CalculateProfile.cpp
|
||||||
|
src/helper/CalculateProfile.h
|
||||||
|
src/singelton/UsageProfile.cpp
|
||||||
|
src/singelton/UsageProfile.h
|
||||||
)
|
)
|
||||||
find_package(doctest CONFIG REQUIRED)
|
find_package(doctest CONFIG REQUIRED)
|
||||||
find_package(spdlog CONFIG REQUIRED)
|
find_package(spdlog CONFIG REQUIRED)
|
||||||
|
|||||||
@ -1,679 +0,0 @@
|
|||||||
# This file is managed by Conan, contents will be overwritten.
|
|
||||||
# To keep your changes, remove these comment lines, but the plugin won't be able to modify your requirements
|
|
||||||
|
|
||||||
# The MIT License (MIT)
|
|
||||||
#
|
|
||||||
# Copyright (c) 2024 JFrog
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
set(CONAN_MINIMUM_VERSION 2.0.5)
|
|
||||||
|
|
||||||
# Create a new policy scope and set the minimum required cmake version so the
|
|
||||||
# features behind a policy setting like if(... IN_LIST ...) behaves as expected
|
|
||||||
# even if the parent project does not specify a minimum cmake version or a minimum
|
|
||||||
# version less than this module requires (e.g. 3.0) before the first project() call.
|
|
||||||
# (see: https://cmake.org/cmake/help/latest/variable/CMAKE_PROJECT_TOP_LEVEL_INCLUDES.html)
|
|
||||||
#
|
|
||||||
# The policy-affecting calls like cmake_policy(SET...) or `cmake_minimum_required` only
|
|
||||||
# affects the current policy scope, i.e. between the PUSH and POP in this case.
|
|
||||||
#
|
|
||||||
# https://cmake.org/cmake/help/book/mastering-cmake/chapter/Policies.html#the-policy-stack
|
|
||||||
cmake_policy(PUSH)
|
|
||||||
cmake_minimum_required(VERSION 3.24)
|
|
||||||
|
|
||||||
|
|
||||||
function(detect_os os os_api_level os_sdk os_subsystem os_version)
|
|
||||||
# it could be cross compilation
|
|
||||||
message(STATUS "CMake-Conan: cmake_system_name=${CMAKE_SYSTEM_NAME}")
|
|
||||||
if(CMAKE_SYSTEM_NAME AND NOT CMAKE_SYSTEM_NAME STREQUAL "Generic")
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
|
||||||
set(${os} Macos PARENT_SCOPE)
|
|
||||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX")
|
|
||||||
set(${os} Neutrino PARENT_SCOPE)
|
|
||||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "CYGWIN")
|
|
||||||
set(${os} Windows PARENT_SCOPE)
|
|
||||||
set(${os_subsystem} cygwin PARENT_SCOPE)
|
|
||||||
elseif(CMAKE_SYSTEM_NAME MATCHES "^MSYS")
|
|
||||||
set(${os} Windows PARENT_SCOPE)
|
|
||||||
set(${os_subsystem} msys2 PARENT_SCOPE)
|
|
||||||
else()
|
|
||||||
set(${os} ${CMAKE_SYSTEM_NAME} PARENT_SCOPE)
|
|
||||||
endif()
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
|
||||||
if(DEFINED ANDROID_PLATFORM)
|
|
||||||
string(REGEX MATCH "[0-9]+" _os_api_level ${ANDROID_PLATFORM})
|
|
||||||
elseif(DEFINED CMAKE_SYSTEM_VERSION)
|
|
||||||
set(_os_api_level ${CMAKE_SYSTEM_VERSION})
|
|
||||||
endif()
|
|
||||||
message(STATUS "CMake-Conan: android api level=${_os_api_level}")
|
|
||||||
set(${os_api_level} ${_os_api_level} PARENT_SCOPE)
|
|
||||||
endif()
|
|
||||||
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS")
|
|
||||||
# CMAKE_OSX_SYSROOT contains the full path to the SDK for MakeFile/Ninja
|
|
||||||
# generators, but just has the original input string for Xcode.
|
|
||||||
if(NOT IS_DIRECTORY ${CMAKE_OSX_SYSROOT})
|
|
||||||
set(_os_sdk ${CMAKE_OSX_SYSROOT})
|
|
||||||
else()
|
|
||||||
if(CMAKE_OSX_SYSROOT MATCHES Simulator)
|
|
||||||
set(apple_platform_suffix simulator)
|
|
||||||
else()
|
|
||||||
set(apple_platform_suffix os)
|
|
||||||
endif()
|
|
||||||
if(CMAKE_OSX_SYSROOT MATCHES AppleTV)
|
|
||||||
set(_os_sdk "appletv${apple_platform_suffix}")
|
|
||||||
elseif(CMAKE_OSX_SYSROOT MATCHES iPhone)
|
|
||||||
set(_os_sdk "iphone${apple_platform_suffix}")
|
|
||||||
elseif(CMAKE_OSX_SYSROOT MATCHES Watch)
|
|
||||||
set(_os_sdk "watch${apple_platform_suffix}")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
if(DEFINED os_sdk)
|
|
||||||
message(STATUS "CMake-Conan: cmake_osx_sysroot=${CMAKE_OSX_SYSROOT}")
|
|
||||||
set(${os_sdk} ${_os_sdk} PARENT_SCOPE)
|
|
||||||
endif()
|
|
||||||
if(DEFINED CMAKE_OSX_DEPLOYMENT_TARGET)
|
|
||||||
message(STATUS "CMake-Conan: cmake_osx_deployment_target=${CMAKE_OSX_DEPLOYMENT_TARGET}")
|
|
||||||
set(${os_version} ${CMAKE_OSX_DEPLOYMENT_TARGET} PARENT_SCOPE)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
|
|
||||||
function(detect_arch arch)
|
|
||||||
# CMAKE_OSX_ARCHITECTURES can contain multiple architectures, but Conan only supports one.
|
|
||||||
# Therefore this code only finds one. If the recipes support multiple architectures, the
|
|
||||||
# build will work. Otherwise, there will be a linker error for the missing architecture(s).
|
|
||||||
if(DEFINED CMAKE_OSX_ARCHITECTURES)
|
|
||||||
string(REPLACE " " ";" apple_arch_list "${CMAKE_OSX_ARCHITECTURES}")
|
|
||||||
list(LENGTH apple_arch_list apple_arch_count)
|
|
||||||
if(apple_arch_count GREATER 1)
|
|
||||||
message(WARNING "CMake-Conan: Multiple architectures detected, this will only work if Conan recipe(s) produce fat binaries.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS" AND NOT CMAKE_OSX_ARCHITECTURES STREQUAL "")
|
|
||||||
set(host_arch ${CMAKE_OSX_ARCHITECTURES})
|
|
||||||
elseif(MSVC)
|
|
||||||
set(host_arch ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID})
|
|
||||||
else()
|
|
||||||
set(host_arch ${CMAKE_SYSTEM_PROCESSOR})
|
|
||||||
endif()
|
|
||||||
if(host_arch MATCHES "aarch64|arm64|ARM64")
|
|
||||||
set(_arch armv8)
|
|
||||||
elseif(host_arch MATCHES "armv7|armv7-a|armv7l|ARMV7")
|
|
||||||
set(_arch armv7)
|
|
||||||
elseif(host_arch MATCHES armv7s)
|
|
||||||
set(_arch armv7s)
|
|
||||||
elseif(host_arch MATCHES "i686|i386|X86")
|
|
||||||
set(_arch x86)
|
|
||||||
elseif(host_arch MATCHES "AMD64|amd64|x86_64|x64")
|
|
||||||
set(_arch x86_64)
|
|
||||||
endif()
|
|
||||||
message(STATUS "CMake-Conan: cmake_system_processor=${_arch}")
|
|
||||||
set(${arch} ${_arch} PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
|
|
||||||
function(detect_cxx_standard cxx_standard)
|
|
||||||
set(${cxx_standard} ${CMAKE_CXX_STANDARD} PARENT_SCOPE)
|
|
||||||
if(CMAKE_CXX_EXTENSIONS)
|
|
||||||
set(${cxx_standard} "gnu${CMAKE_CXX_STANDARD}" PARENT_SCOPE)
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
|
|
||||||
macro(detect_gnu_libstdcxx)
|
|
||||||
# _conan_is_gnu_libstdcxx true if GNU libstdc++
|
|
||||||
check_cxx_source_compiles("
|
|
||||||
#include <cstddef>
|
|
||||||
#if !defined(__GLIBCXX__) && !defined(__GLIBCPP__)
|
|
||||||
static_assert(false);
|
|
||||||
#endif
|
|
||||||
int main(){}" _conan_is_gnu_libstdcxx)
|
|
||||||
|
|
||||||
# _conan_gnu_libstdcxx_is_cxx11_abi true if C++11 ABI
|
|
||||||
check_cxx_source_compiles("
|
|
||||||
#include <string>
|
|
||||||
static_assert(sizeof(std::string) != sizeof(void*), \"using libstdc++\");
|
|
||||||
int main () {}" _conan_gnu_libstdcxx_is_cxx11_abi)
|
|
||||||
|
|
||||||
set(_conan_gnu_libstdcxx_suffix "")
|
|
||||||
if(_conan_gnu_libstdcxx_is_cxx11_abi)
|
|
||||||
set(_conan_gnu_libstdcxx_suffix "11")
|
|
||||||
endif()
|
|
||||||
unset (_conan_gnu_libstdcxx_is_cxx11_abi)
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
|
|
||||||
macro(detect_libcxx)
|
|
||||||
# _conan_is_libcxx true if LLVM libc++
|
|
||||||
check_cxx_source_compiles("
|
|
||||||
#include <cstddef>
|
|
||||||
#if !defined(_LIBCPP_VERSION)
|
|
||||||
static_assert(false);
|
|
||||||
#endif
|
|
||||||
int main(){}" _conan_is_libcxx)
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
|
|
||||||
function(detect_lib_cxx lib_cxx)
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
|
||||||
message(STATUS "CMake-Conan: android_stl=${CMAKE_ANDROID_STL_TYPE}")
|
|
||||||
set(${lib_cxx} ${CMAKE_ANDROID_STL_TYPE} PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(CheckCXXSourceCompiles)
|
|
||||||
|
|
||||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
|
||||||
detect_gnu_libstdcxx()
|
|
||||||
set(${lib_cxx} "libstdc++${_conan_gnu_libstdcxx_suffix}" PARENT_SCOPE)
|
|
||||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
|
|
||||||
set(${lib_cxx} "libc++" PARENT_SCOPE)
|
|
||||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
|
|
||||||
# Check for libc++
|
|
||||||
detect_libcxx()
|
|
||||||
if(_conan_is_libcxx)
|
|
||||||
set(${lib_cxx} "libc++" PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Check for libstdc++
|
|
||||||
detect_gnu_libstdcxx()
|
|
||||||
if(_conan_is_gnu_libstdcxx)
|
|
||||||
set(${lib_cxx} "libstdc++${_conan_gnu_libstdcxx_suffix}" PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# TODO: it would be an error if we reach this point
|
|
||||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
|
||||||
# Do nothing - compiler.runtime and compiler.runtime_type
|
|
||||||
# should be handled separately: https://github.com/conan-io/cmake-conan/pull/516
|
|
||||||
return()
|
|
||||||
else()
|
|
||||||
# TODO: unable to determine, ask user to provide a full profile file instead
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
|
|
||||||
function(detect_compiler compiler compiler_version compiler_runtime compiler_runtime_type)
|
|
||||||
if(DEFINED CMAKE_CXX_COMPILER_ID)
|
|
||||||
set(_compiler ${CMAKE_CXX_COMPILER_ID})
|
|
||||||
set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION})
|
|
||||||
else()
|
|
||||||
if(NOT DEFINED CMAKE_C_COMPILER_ID)
|
|
||||||
message(FATAL_ERROR "C or C++ compiler not defined")
|
|
||||||
endif()
|
|
||||||
set(_compiler ${CMAKE_C_COMPILER_ID})
|
|
||||||
set(_compiler_version ${CMAKE_C_COMPILER_VERSION})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
message(STATUS "CMake-Conan: CMake compiler=${_compiler}")
|
|
||||||
message(STATUS "CMake-Conan: CMake compiler version=${_compiler_version}")
|
|
||||||
|
|
||||||
if(_compiler MATCHES MSVC)
|
|
||||||
set(_compiler "msvc")
|
|
||||||
string(SUBSTRING ${MSVC_VERSION} 0 3 _compiler_version)
|
|
||||||
# Configure compiler.runtime and compiler.runtime_type settings for MSVC
|
|
||||||
if(CMAKE_MSVC_RUNTIME_LIBRARY)
|
|
||||||
set(_msvc_runtime_library ${CMAKE_MSVC_RUNTIME_LIBRARY})
|
|
||||||
else()
|
|
||||||
set(_msvc_runtime_library MultiThreaded$<$<CONFIG:Debug>:Debug>DLL) # default value documented by CMake
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(_KNOWN_MSVC_RUNTIME_VALUES "")
|
|
||||||
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded MultiThreadedDLL)
|
|
||||||
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreadedDebug MultiThreadedDebugDLL)
|
|
||||||
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded$<$<CONFIG:Debug>:Debug> MultiThreaded$<$<CONFIG:Debug>:Debug>DLL)
|
|
||||||
|
|
||||||
# only accept the 6 possible values, otherwise we don't don't know to map this
|
|
||||||
if(NOT _msvc_runtime_library IN_LIST _KNOWN_MSVC_RUNTIME_VALUES)
|
|
||||||
message(FATAL_ERROR "CMake-Conan: unable to map MSVC runtime: ${_msvc_runtime_library} to Conan settings")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Runtime is "dynamic" in all cases if it ends in DLL
|
|
||||||
if(_msvc_runtime_library MATCHES ".*DLL$")
|
|
||||||
set(_compiler_runtime "dynamic")
|
|
||||||
else()
|
|
||||||
set(_compiler_runtime "static")
|
|
||||||
endif()
|
|
||||||
message(STATUS "CMake-Conan: CMake compiler.runtime=${_compiler_runtime}")
|
|
||||||
|
|
||||||
# Only define compiler.runtime_type when explicitly requested
|
|
||||||
# If a generator expression is used, let Conan handle it conditional on build_type
|
|
||||||
if(NOT _msvc_runtime_library MATCHES "<CONFIG:Debug>:Debug>")
|
|
||||||
if(_msvc_runtime_library MATCHES "Debug")
|
|
||||||
set(_compiler_runtime_type "Debug")
|
|
||||||
else()
|
|
||||||
set(_compiler_runtime_type "Release")
|
|
||||||
endif()
|
|
||||||
message(STATUS "CMake-Conan: CMake compiler.runtime_type=${_compiler_runtime_type}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
unset(_KNOWN_MSVC_RUNTIME_VALUES)
|
|
||||||
|
|
||||||
elseif(_compiler MATCHES AppleClang)
|
|
||||||
set(_compiler "apple-clang")
|
|
||||||
string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION})
|
|
||||||
list(GET VERSION_LIST 0 _compiler_version)
|
|
||||||
elseif(_compiler MATCHES Clang)
|
|
||||||
set(_compiler "clang")
|
|
||||||
string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION})
|
|
||||||
list(GET VERSION_LIST 0 _compiler_version)
|
|
||||||
elseif(_compiler MATCHES GNU)
|
|
||||||
set(_compiler "gcc")
|
|
||||||
string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION})
|
|
||||||
list(GET VERSION_LIST 0 _compiler_version)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
message(STATUS "CMake-Conan: [settings] compiler=${_compiler}")
|
|
||||||
message(STATUS "CMake-Conan: [settings] compiler.version=${_compiler_version}")
|
|
||||||
if (_compiler_runtime)
|
|
||||||
message(STATUS "CMake-Conan: [settings] compiler.runtime=${_compiler_runtime}")
|
|
||||||
endif()
|
|
||||||
if (_compiler_runtime_type)
|
|
||||||
message(STATUS "CMake-Conan: [settings] compiler.runtime_type=${_compiler_runtime_type}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(${compiler} ${_compiler} PARENT_SCOPE)
|
|
||||||
set(${compiler_version} ${_compiler_version} PARENT_SCOPE)
|
|
||||||
set(${compiler_runtime} ${_compiler_runtime} PARENT_SCOPE)
|
|
||||||
set(${compiler_runtime_type} ${_compiler_runtime_type} PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
|
|
||||||
function(detect_build_type build_type)
|
|
||||||
get_property(multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
|
||||||
if(NOT multiconfig_generator)
|
|
||||||
# Only set when we know we are in a single-configuration generator
|
|
||||||
# Note: we may want to fail early if `CMAKE_BUILD_TYPE` is not defined
|
|
||||||
set(${build_type} ${CMAKE_BUILD_TYPE} PARENT_SCOPE)
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
|
|
||||||
macro(set_conan_compiler_if_appleclang lang command output_variable)
|
|
||||||
if(CMAKE_${lang}_COMPILER_ID STREQUAL "AppleClang")
|
|
||||||
execute_process(COMMAND xcrun --find ${command}
|
|
||||||
OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
cmake_path(GET _xcrun_out PARENT_PATH _xcrun_toolchain_path)
|
|
||||||
cmake_path(GET CMAKE_${lang}_COMPILER PARENT_PATH _compiler_parent_path)
|
|
||||||
if ("${_xcrun_toolchain_path}" STREQUAL "${_compiler_parent_path}")
|
|
||||||
set(${output_variable} "")
|
|
||||||
endif()
|
|
||||||
unset(_xcrun_out)
|
|
||||||
unset(_xcrun_toolchain_path)
|
|
||||||
unset(_compiler_parent_path)
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
|
|
||||||
macro(append_compiler_executables_configuration)
|
|
||||||
set(_conan_c_compiler "")
|
|
||||||
set(_conan_cpp_compiler "")
|
|
||||||
set(_conan_rc_compiler "")
|
|
||||||
set(_conan_compilers_list "")
|
|
||||||
if(CMAKE_C_COMPILER)
|
|
||||||
set(_conan_c_compiler "\"c\":\"${CMAKE_C_COMPILER}\"")
|
|
||||||
set_conan_compiler_if_appleclang(C cc _conan_c_compiler)
|
|
||||||
list(APPEND _conan_compilers_list ${_conan_c_compiler})
|
|
||||||
else()
|
|
||||||
message(WARNING "CMake-Conan: The C compiler is not defined. "
|
|
||||||
"Please define CMAKE_C_COMPILER or enable the C language.")
|
|
||||||
endif()
|
|
||||||
if(CMAKE_CXX_COMPILER)
|
|
||||||
set(_conan_cpp_compiler "\"cpp\":\"${CMAKE_CXX_COMPILER}\"")
|
|
||||||
set_conan_compiler_if_appleclang(CXX c++ _conan_cpp_compiler)
|
|
||||||
list(APPEND _conan_compilers_list ${_conan_cpp_compiler})
|
|
||||||
else()
|
|
||||||
message(WARNING "CMake-Conan: The C++ compiler is not defined. "
|
|
||||||
"Please define CMAKE_CXX_COMPILER or enable the C++ language.")
|
|
||||||
endif()
|
|
||||||
if(CMAKE_RC_COMPILER)
|
|
||||||
set(_conan_rc_compiler "\"rc\":\"${CMAKE_RC_COMPILER}\"")
|
|
||||||
list(APPEND _conan_compilers_list ${_conan_rc_compiler})
|
|
||||||
# Not necessary to warn if RC not defined
|
|
||||||
endif()
|
|
||||||
if(NOT "x${_conan_compilers_list}" STREQUAL "x")
|
|
||||||
string(REPLACE ";" "," _conan_compilers_list "${_conan_compilers_list}")
|
|
||||||
string(APPEND profile "tools.build:compiler_executables={${_conan_compilers_list}}\n")
|
|
||||||
endif()
|
|
||||||
unset(_conan_c_compiler)
|
|
||||||
unset(_conan_cpp_compiler)
|
|
||||||
unset(_conan_rc_compiler)
|
|
||||||
unset(_conan_compilers_list)
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
|
|
||||||
function(detect_host_profile output_file)
|
|
||||||
detect_os(os os_api_level os_sdk os_subsystem os_version)
|
|
||||||
detect_arch(arch)
|
|
||||||
detect_compiler(compiler compiler_version compiler_runtime compiler_runtime_type)
|
|
||||||
detect_cxx_standard(compiler_cppstd)
|
|
||||||
detect_lib_cxx(compiler_libcxx)
|
|
||||||
detect_build_type(build_type)
|
|
||||||
|
|
||||||
set(profile "")
|
|
||||||
string(APPEND profile "[settings]\n")
|
|
||||||
if(arch)
|
|
||||||
string(APPEND profile arch=${arch} "\n")
|
|
||||||
endif()
|
|
||||||
if(os)
|
|
||||||
string(APPEND profile os=${os} "\n")
|
|
||||||
endif()
|
|
||||||
if(os_api_level)
|
|
||||||
string(APPEND profile os.api_level=${os_api_level} "\n")
|
|
||||||
endif()
|
|
||||||
if(os_version)
|
|
||||||
string(APPEND profile os.version=${os_version} "\n")
|
|
||||||
endif()
|
|
||||||
if(os_sdk)
|
|
||||||
string(APPEND profile os.sdk=${os_sdk} "\n")
|
|
||||||
endif()
|
|
||||||
if(os_subsystem)
|
|
||||||
string(APPEND profile os.subsystem=${os_subsystem} "\n")
|
|
||||||
endif()
|
|
||||||
if(compiler)
|
|
||||||
string(APPEND profile compiler=${compiler} "\n")
|
|
||||||
endif()
|
|
||||||
if(compiler_version)
|
|
||||||
string(APPEND profile compiler.version=${compiler_version} "\n")
|
|
||||||
endif()
|
|
||||||
if(compiler_runtime)
|
|
||||||
string(APPEND profile compiler.runtime=${compiler_runtime} "\n")
|
|
||||||
endif()
|
|
||||||
if(compiler_runtime_type)
|
|
||||||
string(APPEND profile compiler.runtime_type=${compiler_runtime_type} "\n")
|
|
||||||
endif()
|
|
||||||
if(compiler_cppstd)
|
|
||||||
string(APPEND profile compiler.cppstd=${compiler_cppstd} "\n")
|
|
||||||
endif()
|
|
||||||
if(compiler_libcxx)
|
|
||||||
string(APPEND profile compiler.libcxx=${compiler_libcxx} "\n")
|
|
||||||
endif()
|
|
||||||
if(build_type)
|
|
||||||
string(APPEND profile "build_type=${build_type}\n")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT DEFINED output_file)
|
|
||||||
set(file_name "${CMAKE_BINARY_DIR}/profile")
|
|
||||||
else()
|
|
||||||
set(file_name ${output_file})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
string(APPEND profile "[conf]\n")
|
|
||||||
string(APPEND profile "tools.cmake.cmaketoolchain:generator=${CMAKE_GENERATOR}\n")
|
|
||||||
|
|
||||||
# propagate compilers via profile
|
|
||||||
append_compiler_executables_configuration()
|
|
||||||
|
|
||||||
if(os STREQUAL "Android")
|
|
||||||
string(APPEND profile "tools.android:ndk_path=${CMAKE_ANDROID_NDK}\n")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
message(STATUS "CMake-Conan: Creating profile ${file_name}")
|
|
||||||
file(WRITE ${file_name} ${profile})
|
|
||||||
message(STATUS "CMake-Conan: Profile: \n${profile}")
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
|
|
||||||
function(conan_profile_detect_default)
|
|
||||||
message(STATUS "CMake-Conan: Checking if a default profile exists")
|
|
||||||
execute_process(COMMAND ${CONAN_COMMAND} profile path default
|
|
||||||
RESULT_VARIABLE return_code
|
|
||||||
OUTPUT_VARIABLE conan_stdout
|
|
||||||
ERROR_VARIABLE conan_stderr
|
|
||||||
ECHO_ERROR_VARIABLE # show the text output regardless
|
|
||||||
ECHO_OUTPUT_VARIABLE
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
if(NOT ${return_code} EQUAL "0")
|
|
||||||
message(STATUS "CMake-Conan: The default profile doesn't exist, detecting it.")
|
|
||||||
execute_process(COMMAND ${CONAN_COMMAND} profile detect
|
|
||||||
RESULT_VARIABLE return_code
|
|
||||||
OUTPUT_VARIABLE conan_stdout
|
|
||||||
ERROR_VARIABLE conan_stderr
|
|
||||||
ECHO_ERROR_VARIABLE # show the text output regardless
|
|
||||||
ECHO_OUTPUT_VARIABLE
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
|
|
||||||
function(conan_install)
|
|
||||||
cmake_parse_arguments(ARGS conan_args ${ARGN})
|
|
||||||
set(conan_output_folder ${CMAKE_BINARY_DIR}/conan)
|
|
||||||
# Invoke "conan install" with the provided arguments
|
|
||||||
set(conan_args ${conan_args} -of=${conan_output_folder})
|
|
||||||
message(STATUS "CMake-Conan: conan install ${CMAKE_SOURCE_DIR} ${conan_args} ${ARGN}")
|
|
||||||
|
|
||||||
|
|
||||||
# In case there was not a valid cmake executable in the PATH, we inject the
|
|
||||||
# same we used to invoke the provider to the PATH
|
|
||||||
if(DEFINED PATH_TO_CMAKE_BIN)
|
|
||||||
set(old_path $ENV{PATH})
|
|
||||||
set(ENV{PATH} "$ENV{PATH}:${PATH_TO_CMAKE_BIN}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
execute_process(COMMAND ${CONAN_COMMAND} install ${CMAKE_SOURCE_DIR} ${conan_args} ${ARGN} --format=json
|
|
||||||
RESULT_VARIABLE return_code
|
|
||||||
OUTPUT_VARIABLE conan_stdout
|
|
||||||
ERROR_VARIABLE conan_stderr
|
|
||||||
ECHO_ERROR_VARIABLE # show the text output regardless
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
|
|
||||||
if(DEFINED PATH_TO_CMAKE_BIN)
|
|
||||||
set(ENV{PATH} "${old_path}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT "${return_code}" STREQUAL "0")
|
|
||||||
message(FATAL_ERROR "Conan install failed='${return_code}'")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# the files are generated in a folder that depends on the layout used, if
|
|
||||||
# one is specified, but we don't know a priori where this is.
|
|
||||||
# TODO: this can be made more robust if Conan can provide this in the json output
|
|
||||||
string(JSON conan_generators_folder GET "${conan_stdout}" graph nodes 0 generators_folder)
|
|
||||||
cmake_path(CONVERT ${conan_generators_folder} TO_CMAKE_PATH_LIST conan_generators_folder)
|
|
||||||
|
|
||||||
message(STATUS "CMake-Conan: CONAN_GENERATORS_FOLDER=${conan_generators_folder}")
|
|
||||||
set_property(GLOBAL PROPERTY CONAN_GENERATORS_FOLDER "${conan_generators_folder}")
|
|
||||||
# reconfigure on conanfile changes
|
|
||||||
string(JSON conanfile GET "${conan_stdout}" graph nodes 0 label)
|
|
||||||
message(STATUS "CMake-Conan: CONANFILE=${CMAKE_SOURCE_DIR}/${conanfile}")
|
|
||||||
set_property(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/${conanfile}")
|
|
||||||
# success
|
|
||||||
set_property(GLOBAL PROPERTY CONAN_INSTALL_SUCCESS TRUE)
|
|
||||||
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
|
|
||||||
function(conan_get_version conan_command conan_current_version)
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${conan_command} --version
|
|
||||||
OUTPUT_VARIABLE conan_output
|
|
||||||
RESULT_VARIABLE conan_result
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
||||||
)
|
|
||||||
if(conan_result)
|
|
||||||
message(FATAL_ERROR "CMake-Conan: Error when trying to run Conan")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" conan_version ${conan_output})
|
|
||||||
set(${conan_current_version} ${conan_version} PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
|
|
||||||
function(conan_version_check)
|
|
||||||
set(options )
|
|
||||||
set(one_value_args MINIMUM CURRENT)
|
|
||||||
set(multi_value_args )
|
|
||||||
cmake_parse_arguments(conan_version_check
|
|
||||||
"${options}" "${one_value_args}" "${multi_value_args}" ${ARGN})
|
|
||||||
|
|
||||||
if(NOT conan_version_check_MINIMUM)
|
|
||||||
message(FATAL_ERROR "CMake-Conan: Required parameter MINIMUM not set!")
|
|
||||||
endif()
|
|
||||||
if(NOT conan_version_check_CURRENT)
|
|
||||||
message(FATAL_ERROR "CMake-Conan: Required parameter CURRENT not set!")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(conan_version_check_CURRENT VERSION_LESS conan_version_check_MINIMUM)
|
|
||||||
message(FATAL_ERROR "CMake-Conan: Conan version must be ${conan_version_check_MINIMUM} or later")
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
|
|
||||||
macro(construct_profile_argument argument_variable profile_list)
|
|
||||||
set(${argument_variable} "")
|
|
||||||
if("${profile_list}" STREQUAL "CONAN_HOST_PROFILE")
|
|
||||||
set(_arg_flag "--profile:host=")
|
|
||||||
elseif("${profile_list}" STREQUAL "CONAN_BUILD_PROFILE")
|
|
||||||
set(_arg_flag "--profile:build=")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(_profile_list "${${profile_list}}")
|
|
||||||
list(TRANSFORM _profile_list REPLACE "auto-cmake" "${CMAKE_BINARY_DIR}/conan_host_profile")
|
|
||||||
list(TRANSFORM _profile_list PREPEND ${_arg_flag})
|
|
||||||
set(${argument_variable} ${_profile_list})
|
|
||||||
|
|
||||||
unset(_arg_flag)
|
|
||||||
unset(_profile_list)
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
|
|
||||||
macro(conan_provide_dependency method package_name)
|
|
||||||
set_property(GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED TRUE)
|
|
||||||
get_property(_conan_install_success GLOBAL PROPERTY CONAN_INSTALL_SUCCESS)
|
|
||||||
if(NOT _conan_install_success)
|
|
||||||
find_program(CONAN_COMMAND "conan" REQUIRED)
|
|
||||||
conan_get_version(${CONAN_COMMAND} CONAN_CURRENT_VERSION)
|
|
||||||
conan_version_check(MINIMUM ${CONAN_MINIMUM_VERSION} CURRENT ${CONAN_CURRENT_VERSION})
|
|
||||||
message(STATUS "CMake-Conan: first find_package() found. Installing dependencies with Conan")
|
|
||||||
if("default" IN_LIST CONAN_HOST_PROFILE OR "default" IN_LIST CONAN_BUILD_PROFILE)
|
|
||||||
conan_profile_detect_default()
|
|
||||||
endif()
|
|
||||||
if("auto-cmake" IN_LIST CONAN_HOST_PROFILE)
|
|
||||||
detect_host_profile(${CMAKE_BINARY_DIR}/conan_host_profile)
|
|
||||||
endif()
|
|
||||||
construct_profile_argument(_host_profile_flags CONAN_HOST_PROFILE)
|
|
||||||
construct_profile_argument(_build_profile_flags CONAN_BUILD_PROFILE)
|
|
||||||
if(EXISTS "${CMAKE_SOURCE_DIR}/conanfile.py")
|
|
||||||
file(READ "${CMAKE_SOURCE_DIR}/conanfile.py" outfile)
|
|
||||||
if(NOT "${outfile}" MATCHES ".*CMakeDeps.*")
|
|
||||||
message(WARNING "Cmake-conan: CMakeDeps generator was not defined in the conanfile")
|
|
||||||
endif()
|
|
||||||
set(generator "")
|
|
||||||
elseif (EXISTS "${CMAKE_SOURCE_DIR}/conanfile.txt")
|
|
||||||
file(READ "${CMAKE_SOURCE_DIR}/conanfile.txt" outfile)
|
|
||||||
if(NOT "${outfile}" MATCHES ".*CMakeDeps.*")
|
|
||||||
message(WARNING "Cmake-conan: CMakeDeps generator was not defined in the conanfile. "
|
|
||||||
"Please define the generator as it will be mandatory in the future")
|
|
||||||
endif()
|
|
||||||
set(generator "-g;CMakeDeps")
|
|
||||||
endif()
|
|
||||||
get_property(_multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
|
||||||
if(NOT _multiconfig_generator)
|
|
||||||
message(STATUS "CMake-Conan: Installing single configuration ${CMAKE_BUILD_TYPE}")
|
|
||||||
conan_install(${_host_profile_flags} ${_build_profile_flags} ${CONAN_INSTALL_ARGS} ${generator})
|
|
||||||
else()
|
|
||||||
message(STATUS "CMake-Conan: Installing both Debug and Release")
|
|
||||||
conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Release ${CONAN_INSTALL_ARGS} ${generator})
|
|
||||||
conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Debug ${CONAN_INSTALL_ARGS} ${generator})
|
|
||||||
endif()
|
|
||||||
unset(_host_profile_flags)
|
|
||||||
unset(_build_profile_flags)
|
|
||||||
unset(_multiconfig_generator)
|
|
||||||
unset(_conan_install_success)
|
|
||||||
else()
|
|
||||||
message(STATUS "CMake-Conan: find_package(${ARGV1}) found, 'conan install' already ran")
|
|
||||||
unset(_conan_install_success)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
get_property(_conan_generators_folder GLOBAL PROPERTY CONAN_GENERATORS_FOLDER)
|
|
||||||
|
|
||||||
# Ensure that we consider Conan-provided packages ahead of any other,
|
|
||||||
# irrespective of other settings that modify the search order or search paths
|
|
||||||
# This follows the guidelines from the find_package documentation
|
|
||||||
# (https://cmake.org/cmake/help/latest/command/find_package.html):
|
|
||||||
# find_package (<PackageName> PATHS paths... NO_DEFAULT_PATH)
|
|
||||||
# find_package (<PackageName>)
|
|
||||||
|
|
||||||
# Filter out `REQUIRED` from the argument list, as the first call may fail
|
|
||||||
set(_find_args_${package_name} "${ARGN}")
|
|
||||||
list(REMOVE_ITEM _find_args_${package_name} "REQUIRED")
|
|
||||||
if(NOT "MODULE" IN_LIST _find_args_${package_name})
|
|
||||||
find_package(${package_name} ${_find_args_${package_name}} BYPASS_PROVIDER PATHS "${_conan_generators_folder}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
|
|
||||||
unset(_find_args_${package_name})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Invoke find_package a second time - if the first call succeeded,
|
|
||||||
# this will simply reuse the result. If not, fall back to CMake default search
|
|
||||||
# behaviour, also allowing modules to be searched.
|
|
||||||
if(NOT ${package_name}_FOUND)
|
|
||||||
list(FIND CMAKE_MODULE_PATH "${_conan_generators_folder}" _index)
|
|
||||||
if(_index EQUAL -1)
|
|
||||||
list(PREPEND CMAKE_MODULE_PATH "${_conan_generators_folder}")
|
|
||||||
endif()
|
|
||||||
unset(_index)
|
|
||||||
find_package(${package_name} ${ARGN} BYPASS_PROVIDER)
|
|
||||||
list(REMOVE_ITEM CMAKE_MODULE_PATH "${_conan_generators_folder}")
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
|
|
||||||
cmake_language(
|
|
||||||
SET_DEPENDENCY_PROVIDER conan_provide_dependency
|
|
||||||
SUPPORTED_METHODS FIND_PACKAGE
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
macro(conan_provide_dependency_check)
|
|
||||||
set(_conan_provide_dependency_invoked FALSE)
|
|
||||||
get_property(_conan_provide_dependency_invoked GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED)
|
|
||||||
if(NOT _conan_provide_dependency_invoked)
|
|
||||||
message(WARNING "Conan is correctly configured as dependency provider, "
|
|
||||||
"but Conan has not been invoked. Please add at least one "
|
|
||||||
"call to `find_package()`.")
|
|
||||||
if(DEFINED CONAN_COMMAND)
|
|
||||||
# supress warning in case `CONAN_COMMAND` was specified but unused.
|
|
||||||
set(_conan_command ${CONAN_COMMAND})
|
|
||||||
unset(_conan_command)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
unset(_conan_provide_dependency_invoked)
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
|
|
||||||
# Add a deferred call at the end of processing the top-level directory
|
|
||||||
# to check if the dependency provider was invoked at all.
|
|
||||||
cmake_language(DEFER DIRECTORY "${CMAKE_SOURCE_DIR}" CALL conan_provide_dependency_check)
|
|
||||||
|
|
||||||
# Configurable variables for Conan profiles
|
|
||||||
set(CONAN_HOST_PROFILE "default;auto-cmake" CACHE STRING "Conan host profile")
|
|
||||||
set(CONAN_BUILD_PROFILE "default" CACHE STRING "Conan build profile")
|
|
||||||
set(CONAN_INSTALL_ARGS "--build=missing" CACHE STRING "Command line arguments for conan install")
|
|
||||||
|
|
||||||
find_program(_cmake_program NAMES cmake NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_FIND_ROOT_PATH)
|
|
||||||
if(NOT _cmake_program)
|
|
||||||
get_filename_component(PATH_TO_CMAKE_BIN "${CMAKE_COMMAND}" DIRECTORY)
|
|
||||||
set(PATH_TO_CMAKE_BIN "${PATH_TO_CMAKE_BIN}" CACHE INTERNAL "Path where the CMake executable is")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
cmake_policy(POP)
|
|
||||||
@ -13,5 +13,9 @@
|
|||||||
#endif
|
#endif
|
||||||
#define VALUE_COUNT ((size_t)(4 * 24 * 365))
|
#define VALUE_COUNT ((size_t)(4 * 24 * 365))
|
||||||
#define MAX_CONDITIONS 2560
|
#define MAX_CONDITIONS 2560
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
typedef std::unique_ptr<std::vector<std::pair<std::string, std::vector<std::string>>>> usageProfile;
|
||||||
|
|
||||||
#endif //CONFIG_H
|
#endif //CONFIG_H
|
||||||
|
|||||||
95
src/helper/CalculateProfile.cpp
Normal file
95
src/helper/CalculateProfile.cpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
//
|
||||||
|
// Created by stani on 3/14/2025.
|
||||||
|
|
||||||
|
#include "CalculateProfile.h"
|
||||||
|
|
||||||
|
#include <charconv>
|
||||||
|
#include <iostream>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
|
#include "../singelton/UsageProfile.h"
|
||||||
|
#include <ranges>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param profileNameCon Name of the Consumption Profile e.g. G1
|
||||||
|
* @param profileNameGen Name of the Generation Profile e.g. Solar
|
||||||
|
* @param annualConsumption Annual Consumption value
|
||||||
|
* @param annualGeneration Annual Consumption value
|
||||||
|
* @return Tuple first element consumption vector, second generation Vector
|
||||||
|
* @throws runtime_error if profileNameCon or profileNameGen is not loaded
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
std::tuple<std::vector<float>, std::vector<float>> CalculateProfile::calculateProfile(
|
||||||
|
const std::string& profileNameCon, const std::string& profileNameGen, const float annualConsumption,
|
||||||
|
const float annualGeneration)
|
||||||
|
{
|
||||||
|
const UsageProfile* profiles = UsageProfile::getInstance();
|
||||||
|
std::vector<float> calculatedConProfile;
|
||||||
|
std::vector<float> calculatedGenProfile;
|
||||||
|
const auto itCon = std::ranges::find_if(*profiles->ConsumptionProfile,
|
||||||
|
[&profileNameCon](
|
||||||
|
const std::pair<std::string, std::vector<std::string>>& pair)
|
||||||
|
{
|
||||||
|
return pair.first == profileNameCon;
|
||||||
|
});
|
||||||
|
const auto itGen = std::ranges::find_if(*profiles->GenerationProfile,
|
||||||
|
[&profileNameGen](
|
||||||
|
const std::pair<std::string, std::vector<std::string>>& pair)
|
||||||
|
{
|
||||||
|
return pair.first == profileNameGen;
|
||||||
|
});
|
||||||
|
if (itCon == profiles->ConsumptionProfile->end()) {
|
||||||
|
throw std::runtime_error("Consumption profile not found: " + profileNameCon);
|
||||||
|
}
|
||||||
|
if (itGen == profiles->GenerationProfile->end()) {
|
||||||
|
throw std::runtime_error("Consumption profile not found: " + profileNameGen);
|
||||||
|
}
|
||||||
|
const float sumCon = std::accumulate(itCon->second.begin(), itCon->second.end(), 0.0f,
|
||||||
|
[](const float acc, const std::string& str)
|
||||||
|
{
|
||||||
|
float value;
|
||||||
|
const auto result = std::from_chars(str.data(), str.data() + str.size(), value);
|
||||||
|
if (result.ec != std::errc())
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("Invalid number format: " + str);
|
||||||
|
}
|
||||||
|
return acc + value;
|
||||||
|
});
|
||||||
|
|
||||||
|
const float sumGen = std::accumulate(itGen->second.begin(), itGen->second.end(), 0.0f,
|
||||||
|
[](const float acc, const std::string& str)
|
||||||
|
{
|
||||||
|
float value = 0.0f;
|
||||||
|
auto result = std::from_chars(str.data(), str.data() + str.size(), value);
|
||||||
|
if (result.ec != std::errc())
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("Invalid number format: " + str);
|
||||||
|
}
|
||||||
|
return acc + value;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (auto&& [consumption, generation] : std::views::zip(
|
||||||
|
itCon->second,
|
||||||
|
itGen->second
|
||||||
|
))
|
||||||
|
{
|
||||||
|
float floatCon = 0.f;
|
||||||
|
float floatGen = 0.f;
|
||||||
|
const auto res1 = std::from_chars(consumption.data(), consumption.data() + consumption.size(), floatCon);
|
||||||
|
const auto res2 = std::from_chars(generation.data(), generation.data() + generation.size(), floatGen);
|
||||||
|
if (res1.ec == std::errc::invalid_argument || res2.ec == std::errc::invalid_argument)
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("Not a float");
|
||||||
|
}
|
||||||
|
if (res1.ec == std::errc::result_out_of_range || res2.ec == std::errc::result_out_of_range)
|
||||||
|
{
|
||||||
|
throw std::out_of_range("Out fo range");
|
||||||
|
}
|
||||||
|
calculatedConProfile.push_back(floatCon * annualConsumption / sumCon);
|
||||||
|
calculatedGenProfile.push_back(floatGen * annualGeneration / sumGen);
|
||||||
|
}
|
||||||
|
return make_tuple(std::move(calculatedConProfile),
|
||||||
|
std::move(calculatedGenProfile));
|
||||||
|
}
|
||||||
20
src/helper/CalculateProfile.h
Normal file
20
src/helper/CalculateProfile.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// Created by stani on 3/14/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CALCULATEPROFILE_H
|
||||||
|
#define CALCULATEPROFILE_H
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
class CalculateProfile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::tuple<std::vector<float>, std::vector<float>> calculateProfile(
|
||||||
|
const std::string& profileNameCon, const std::string& profileNameGen, float annualConsumption,
|
||||||
|
float annualGeneration);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //CALCULATEPROFILE_H
|
||||||
@ -11,21 +11,25 @@
|
|||||||
|
|
||||||
#include "../Config.h"
|
#include "../Config.h"
|
||||||
|
|
||||||
std::vector<std::string> CsvBinary::splitLine(const std::string &line, const char delimiter) {
|
std::vector<std::string> CsvBinary::splitLine(const std::string& line, const char delimiter)
|
||||||
|
{
|
||||||
std::vector<std::string> tokens;
|
std::vector<std::string> tokens;
|
||||||
std::stringstream ss(line);
|
std::stringstream ss(line);
|
||||||
std::string token;
|
std::string token;
|
||||||
while (std::getline(ss, token, delimiter)) {
|
while (std::getline(ss, token, delimiter))
|
||||||
|
{
|
||||||
tokens.push_back(token);
|
tokens.push_back(token);
|
||||||
}
|
}
|
||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvBinary::csvToBinary(const std::string &csvFile, const std::string &binFile) {
|
void CsvBinary::csvToBinary(const std::string& csvFile, const std::string& binFile)
|
||||||
|
{
|
||||||
std::ifstream inFile(csvFile);
|
std::ifstream inFile(csvFile);
|
||||||
std::ofstream outFile(binFile, std::ios::binary);
|
std::ofstream outFile(binFile, std::ios::binary);
|
||||||
|
|
||||||
if (!inFile.is_open() || !outFile.is_open()) {
|
if (!inFile.is_open() || !outFile.is_open())
|
||||||
|
{
|
||||||
LOG_DEBUG_ERROR("Failed opening file");
|
LOG_DEBUG_ERROR("Failed opening file");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -37,14 +41,17 @@ void CsvBinary::csvToBinary(const std::string &csvFile, const std::string &binFi
|
|||||||
std::stringstream jsonHeader;
|
std::stringstream jsonHeader;
|
||||||
jsonHeader << "{\"headers\":[";
|
jsonHeader << "{\"headers\":[";
|
||||||
|
|
||||||
while (std::getline(inFile, line)) {
|
while (std::getline(inFile, line))
|
||||||
|
{
|
||||||
std::vector<std::string> row = splitLine(line, ';');
|
std::vector<std::string> row = splitLine(line, ';');
|
||||||
|
|
||||||
if (isHeader) {
|
if (isHeader)
|
||||||
|
{
|
||||||
header = row;
|
header = row;
|
||||||
|
|
||||||
// Store header as JSON
|
// Store header as JSON
|
||||||
for (size_t i = 0; i < header.size(); ++i) {
|
for (size_t i = 0; i < header.size(); ++i)
|
||||||
|
{
|
||||||
jsonHeader << "\"" << header[i] << "\"";
|
jsonHeader << "\"" << header[i] << "\"";
|
||||||
if (i < header.size() - 1) jsonHeader << ",";
|
if (i < header.size() - 1) jsonHeader << ",";
|
||||||
}
|
}
|
||||||
@ -61,7 +68,8 @@ void CsvBinary::csvToBinary(const std::string &csvFile, const std::string &binFi
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &field : row) {
|
for (const auto& field : row)
|
||||||
|
{
|
||||||
size_t length = field.size();
|
size_t length = field.size();
|
||||||
outFile.write(reinterpret_cast<const char*>(&length), sizeof(size_t));
|
outFile.write(reinterpret_cast<const char*>(&length), sizeof(size_t));
|
||||||
outFile.write(field.c_str(), length);
|
outFile.write(field.c_str(), length);
|
||||||
@ -74,11 +82,13 @@ void CsvBinary::csvToBinary(const std::string &csvFile, const std::string &binFi
|
|||||||
LOG_DEBUG_INFO("CSV converted to binary successfully.");
|
LOG_DEBUG_INFO("CSV converted to binary successfully.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvBinary::binaryToCsv(const std::string &binFile, const std::string &csvFile) {
|
void CsvBinary::binaryToCsv(const std::string& binFile, const std::string& csvFile)
|
||||||
|
{
|
||||||
std::ifstream inFile(binFile, std::ios::binary);
|
std::ifstream inFile(binFile, std::ios::binary);
|
||||||
std::ofstream outFile(csvFile);
|
std::ofstream outFile(csvFile);
|
||||||
|
|
||||||
if (!inFile.is_open() || !outFile.is_open()) {
|
if (!inFile.is_open() || !outFile.is_open())
|
||||||
|
{
|
||||||
LOG_DEBUG_ERROR("Failed opening file");
|
LOG_DEBUG_ERROR("Failed opening file");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -98,21 +108,25 @@ void CsvBinary::binaryToCsv(const std::string &binFile, const std::string &csvFi
|
|||||||
|
|
||||||
std::stringstream ss(headersStr);
|
std::stringstream ss(headersStr);
|
||||||
std::string field;
|
std::string field;
|
||||||
while (std::getline(ss, field, ',')) {
|
while (std::getline(ss, field, ','))
|
||||||
|
{
|
||||||
field.erase(std::remove(field.begin(), field.end(), '\"'), field.end()); // Remove quotes
|
field.erase(std::remove(field.begin(), field.end(), '\"'), field.end()); // Remove quotes
|
||||||
header.push_back(field);
|
header.push_back(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write header to CSV
|
// Write header to CSV
|
||||||
for (size_t i = 0; i < header.size(); ++i) {
|
for (size_t i = 0; i < header.size(); ++i)
|
||||||
|
{
|
||||||
outFile << header[i];
|
outFile << header[i];
|
||||||
if (i < header.size() - 1) outFile << ";";
|
if (i < header.size() - 1) outFile << ";";
|
||||||
}
|
}
|
||||||
outFile << "\n";
|
outFile << "\n";
|
||||||
|
|
||||||
while (!inFile.eof()) {
|
while (!inFile.eof())
|
||||||
|
{
|
||||||
std::vector<std::string> row;
|
std::vector<std::string> row;
|
||||||
for (size_t i = 0; i < header.size(); ++i) {
|
for (size_t i = 0; i < header.size(); ++i)
|
||||||
|
{
|
||||||
size_t length;
|
size_t length;
|
||||||
if (!inFile.read(reinterpret_cast<char*>(&length), sizeof(size_t))) break;
|
if (!inFile.read(reinterpret_cast<char*>(&length), sizeof(size_t))) break;
|
||||||
|
|
||||||
@ -120,8 +134,10 @@ void CsvBinary::binaryToCsv(const std::string &binFile, const std::string &csvFi
|
|||||||
inFile.read(&field[0], length);
|
inFile.read(&field[0], length);
|
||||||
row.push_back(field);
|
row.push_back(field);
|
||||||
}
|
}
|
||||||
if (!row.empty()) {
|
if (!row.empty())
|
||||||
for (size_t i = 0; i < row.size(); ++i) {
|
{
|
||||||
|
for (size_t i = 0; i < row.size(); ++i)
|
||||||
|
{
|
||||||
outFile << row[i];
|
outFile << row[i];
|
||||||
if (i < row.size() - 1) outFile << ";";
|
if (i < row.size() - 1) outFile << ";";
|
||||||
}
|
}
|
||||||
@ -136,12 +152,13 @@ void CsvBinary::binaryToCsv(const std::string &binFile, const std::string &csvFi
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<std::vector<std::pair<std::string, std::vector<std::string>>>> CsvBinary::binaryToVector(
|
std::unique_ptr<std::vector<std::pair<std::string, std::vector<std::string>>>> CsvBinary::binaryToVector(
|
||||||
const std::string &binFile) {
|
const std::string& binFile)
|
||||||
|
{
|
||||||
std::ifstream inFile(binFile, std::ios::binary);
|
std::ifstream inFile(binFile, std::ios::binary);
|
||||||
auto data = std::make_unique<std::vector<std::pair<std::string, std::vector<std::string>>>>();
|
auto data = std::make_unique<std::vector<std::pair<std::string, std::vector<std::string>>>>();
|
||||||
|
|
||||||
if (!inFile.is_open()) {
|
if (!inFile.is_open())
|
||||||
|
{
|
||||||
LOG_DEBUG_ERROR("Failed to open binary file");
|
LOG_DEBUG_ERROR("Failed to open binary file");
|
||||||
return data; // Return empty structure
|
return data; // Return empty structure
|
||||||
}
|
}
|
||||||
@ -162,19 +179,23 @@ std::unique_ptr<std::vector<std::pair<std::string, std::vector<std::string>>>> C
|
|||||||
|
|
||||||
std::stringstream ss(headersStr);
|
std::stringstream ss(headersStr);
|
||||||
std::string field;
|
std::string field;
|
||||||
while (std::getline(ss, field, ',')) {
|
while (std::getline(ss, field, ','))
|
||||||
|
{
|
||||||
field.erase(std::remove(field.begin(), field.end(), '\"'), field.end()); // Remove quotes
|
field.erase(std::remove(field.begin(), field.end(), '\"'), field.end()); // Remove quotes
|
||||||
headers.push_back(field);
|
headers.push_back(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize data structure for columns
|
// Initialize data structure for columns
|
||||||
for (const auto &header : headers) {
|
for (const auto& header : headers)
|
||||||
|
{
|
||||||
data->emplace_back(header, std::vector<std::string>());
|
data->emplace_back(header, std::vector<std::string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read row data and distribute into columns
|
// Read row data and distribute into columns
|
||||||
while (!inFile.eof()) {
|
while (!inFile.eof())
|
||||||
for (size_t i = 0; i < headers.size(); ++i) {
|
{
|
||||||
|
for (size_t i = 0; i < headers.size(); ++i)
|
||||||
|
{
|
||||||
size_t length;
|
size_t length;
|
||||||
if (!inFile.read(reinterpret_cast<char*>(&length), sizeof(size_t))) break;
|
if (!inFile.read(reinterpret_cast<char*>(&length), sizeof(size_t))) break;
|
||||||
|
|
||||||
|
|||||||
@ -4,23 +4,17 @@
|
|||||||
|
|
||||||
#ifndef CSVTOBINARY_H
|
#ifndef CSVTOBINARY_H
|
||||||
#define CSVTOBINARY_H
|
#define CSVTOBINARY_H
|
||||||
#include <iosfwd>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class CsvBinary {
|
class CsvBinary
|
||||||
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static std::vector<std::string> splitLine(const std::string& line, char delimiter);
|
static std::vector<std::string> splitLine(const std::string& line, char delimiter);
|
||||||
|
|
||||||
static void saveHeaderToFile(const std::string &string, const std::string &line);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static void csvToBinary(const std::string& csvFile, const std::string& binFile);
|
static void csvToBinary(const std::string& csvFile, const std::string& binFile);
|
||||||
|
|
||||||
static void binaryToCsv(const std::string& binFile, const std::string& csvFile);
|
static void binaryToCsv(const std::string& binFile, const std::string& csvFile);
|
||||||
|
|||||||
@ -5,11 +5,15 @@
|
|||||||
#include "StringOperations.h"
|
#include "StringOperations.h"
|
||||||
|
|
||||||
void StringOperations::splitString(const std::string& input, const std::string& delimiter, std::string& before,
|
void StringOperations::splitString(const std::string& input, const std::string& delimiter, std::string& before,
|
||||||
std::string &after) {
|
std::string& after)
|
||||||
if (const size_t pos = input.find(delimiter); pos != std::string::npos) {
|
{
|
||||||
|
if (const size_t pos = input.find(delimiter); pos != std::string::npos)
|
||||||
|
{
|
||||||
before = input.substr(0, pos);
|
before = input.substr(0, pos);
|
||||||
after = input.substr(pos + delimiter.length());
|
after = input.substr(pos + delimiter.length());
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
before = input;
|
before = input;
|
||||||
after = "";
|
after = "";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,19 +6,25 @@
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
float Building::Metadata::special_rate_consumption() const {
|
#include "../helper/CalculateProfile.h"
|
||||||
|
|
||||||
|
float Building::Metadata::special_rate_consumption() const
|
||||||
|
{
|
||||||
return SpecialRateConsumption;
|
return SpecialRateConsumption;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Metadata::set_special_rate_consumption(const float special_rate_consumption) {
|
void Building::Metadata::set_special_rate_consumption(const float special_rate_consumption)
|
||||||
|
{
|
||||||
SpecialRateConsumption = special_rate_consumption;
|
SpecialRateConsumption = special_rate_consumption;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Building::Metadata::special_rate_generation() const {
|
float Building::Metadata::special_rate_generation() const
|
||||||
|
{
|
||||||
return SpecialRateGeneration;
|
return SpecialRateGeneration;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Metadata::set_special_rate_generation(const float special_rate_generation) {
|
void Building::Metadata::set_special_rate_generation(const float special_rate_generation)
|
||||||
|
{
|
||||||
SpecialRateGeneration = special_rate_generation;
|
SpecialRateGeneration = special_rate_generation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,260 +108,332 @@ void Building::Metadata::set_total_by_category_without(std::unordered_map<std::s
|
|||||||
TotalByCategoryWithout = std::move(value);
|
TotalByCategoryWithout = std::move(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> &Building::Simulation_Values::generation_after_community() {
|
std::vector<float>& Building::Simulation_Values::generation_after_community()
|
||||||
|
{
|
||||||
return GenerationAfterCommunity;
|
return GenerationAfterCommunity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::generation_after_community(const std::vector<float> &generation_after_community) {
|
void Building::Simulation_Values::generation_after_community(const std::vector<float>& generation_after_community)
|
||||||
|
{
|
||||||
GenerationAfterCommunity = generation_after_community;
|
GenerationAfterCommunity = generation_after_community;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> &Building::Simulation_Values::consumption_after_community() {
|
std::vector<float>& Building::Simulation_Values::consumption_after_community()
|
||||||
|
{
|
||||||
return ConsumptionAfterCommunity;
|
return ConsumptionAfterCommunity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::consumption_after_community(const std::vector<float> &consumption_after_community) {
|
void Building::Simulation_Values::consumption_after_community(const std::vector<float>& consumption_after_community)
|
||||||
|
{
|
||||||
ConsumptionAfterCommunity = consumption_after_community;
|
ConsumptionAfterCommunity = consumption_after_community;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> &Building::Simulation_Values::generation_to_community() {
|
std::vector<float>& Building::Simulation_Values::generation_to_community()
|
||||||
|
{
|
||||||
return GenerationToCommunity;
|
return GenerationToCommunity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::generation_to_community(const std::vector<float> &generation_to_community) {
|
void Building::Simulation_Values::generation_to_community(const std::vector<float>& generation_to_community)
|
||||||
|
{
|
||||||
GenerationToCommunity = generation_to_community;
|
GenerationToCommunity = generation_to_community;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> &Building::Simulation_Values::consumption_from_community() {
|
std::vector<float>& Building::Simulation_Values::consumption_from_community()
|
||||||
|
{
|
||||||
return ConsumptionFromCommunity;
|
return ConsumptionFromCommunity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::consumption_from_community(const std::vector<float> &consumption_from_community) {
|
void Building::Simulation_Values::consumption_from_community(const std::vector<float>& consumption_from_community)
|
||||||
|
{
|
||||||
ConsumptionFromCommunity = consumption_from_community;
|
ConsumptionFromCommunity = consumption_from_community;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Building::Simulation_Values::con_from_community_relative() const {
|
float Building::Simulation_Values::con_from_community_relative() const
|
||||||
|
{
|
||||||
return this->ConsumptionFromCommunityRelative;
|
return this->ConsumptionFromCommunityRelative;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::set_con_from_community_relative(const float x) {
|
void Building::Simulation_Values::set_con_from_community_relative(const float x)
|
||||||
|
{
|
||||||
this->ConsumptionFromCommunityRelative = x;
|
this->ConsumptionFromCommunityRelative = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Building::Simulation_Values::gen_to_community_relative() const {
|
float Building::Simulation_Values::gen_to_community_relative() const
|
||||||
|
{
|
||||||
return this->GenerationToCommunityRelative;
|
return this->GenerationToCommunityRelative;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::set_gen_to_community_relative(float x) {
|
void Building::Simulation_Values::set_gen_to_community_relative(float x)
|
||||||
|
{
|
||||||
this->GenerationToCommunityRelative = x;
|
this->GenerationToCommunityRelative = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Building::Simulation_Values::consumption_after_own_coverage_sum() const {
|
float Building::Simulation_Values::consumption_after_own_coverage_sum() const
|
||||||
|
{
|
||||||
return ConsumptionAfterCommunitySum;
|
return ConsumptionAfterCommunitySum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::set_consumption_after_own_coverage_sum(const float value) {
|
void Building::Simulation_Values::set_consumption_after_own_coverage_sum(const float value)
|
||||||
|
{
|
||||||
ConsumptionFromCommunityRelative = value;
|
ConsumptionFromCommunityRelative = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Building::Simulation_Values::own_usage_sum() const {
|
float Building::Simulation_Values::own_usage_sum() const
|
||||||
|
{
|
||||||
return OwnUsageSum;
|
return OwnUsageSum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::set_own_usage_sum(const float value) {
|
void Building::Simulation_Values::set_own_usage_sum(const float value)
|
||||||
|
{
|
||||||
OwnUsageSum = value;
|
OwnUsageSum = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Building::Simulation_Values::needed_con_sum() const {
|
float Building::Simulation_Values::needed_con_sum() const
|
||||||
|
{
|
||||||
return NeededConSum;
|
return NeededConSum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::set_needed_con_sum(const float value) {
|
void Building::Simulation_Values::set_needed_con_sum(const float value)
|
||||||
|
{
|
||||||
NeededConSum = value;
|
NeededConSum = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Building::Simulation_Values::needed_gen_sum() const {
|
float Building::Simulation_Values::needed_gen_sum() const
|
||||||
|
{
|
||||||
return NeededGenSum;
|
return NeededGenSum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::set_needed_gen_sum(const float value) {
|
void Building::Simulation_Values::set_needed_gen_sum(const float value)
|
||||||
|
{
|
||||||
NeededGenSum = value;
|
NeededGenSum = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Building::Simulation_Values::consumption_after_community_sum() const {
|
float Building::Simulation_Values::consumption_after_community_sum() const
|
||||||
|
{
|
||||||
return ConsumptionAfterCommunitySum;
|
return ConsumptionAfterCommunitySum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::set_consumption_after_community_sum(const float value) {
|
void Building::Simulation_Values::set_consumption_after_community_sum(const float value)
|
||||||
|
{
|
||||||
ConsumptionAfterCommunitySum = value;
|
ConsumptionAfterCommunitySum = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Building::Simulation_Values::generation_after_community_sum() const {
|
float Building::Simulation_Values::generation_after_community_sum() const
|
||||||
|
{
|
||||||
return GenerationAfterCommunitySum;
|
return GenerationAfterCommunitySum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::set_generation_after_community_sum(const float value) {
|
void Building::Simulation_Values::set_generation_after_community_sum(const float value)
|
||||||
|
{
|
||||||
GenerationAfterCommunitySum = value;
|
GenerationAfterCommunitySum = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Building::Simulation_Values::consumption_from_community_sum() const {
|
float Building::Simulation_Values::consumption_from_community_sum() const
|
||||||
|
{
|
||||||
return ConsumptionFromCommunitySum;
|
return ConsumptionFromCommunitySum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::set_consumption_from_community_sum(const float value) {
|
void Building::Simulation_Values::set_consumption_from_community_sum(const float value)
|
||||||
|
{
|
||||||
ConsumptionFromCommunitySum = value;
|
ConsumptionFromCommunitySum = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Building::Simulation_Values::generation_to_community_sum() const {
|
float Building::Simulation_Values::generation_to_community_sum() const
|
||||||
|
{
|
||||||
return GenerationToCommunitySum;
|
return GenerationToCommunitySum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::set_generation_to_community_sum(const float values) {
|
void Building::Simulation_Values::set_generation_to_community_sum(const float values)
|
||||||
|
{
|
||||||
GenerationToCommunitySum = values;
|
GenerationToCommunitySum = values;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> &Building::Simulation_Values::consumption_after_own_coverage() {
|
std::vector<float>& Building::Simulation_Values::consumption_after_own_coverage()
|
||||||
|
{
|
||||||
return ConsumptionAfterOwnCoverage;
|
return ConsumptionAfterOwnCoverage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::
|
void Building::Simulation_Values::
|
||||||
set_community_coverage(std::vector<float> community_coverage) {
|
set_community_coverage(std::vector<float> community_coverage)
|
||||||
|
{
|
||||||
ConsumptionAfterOwnCoverage = std::move(community_coverage);
|
ConsumptionAfterOwnCoverage = std::move(community_coverage);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> &Building::Simulation_Values::own_usage() {
|
std::vector<float>& Building::Simulation_Values::own_usage()
|
||||||
|
{
|
||||||
return OwnUsage;
|
return OwnUsage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::set_own_usage(std::vector<float> own_usage) {
|
void Building::Simulation_Values::set_own_usage(std::vector<float> own_usage)
|
||||||
|
{
|
||||||
OwnUsage = std::move(own_usage);
|
OwnUsage = std::move(own_usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> &Building::Simulation_Values::needed_con() {
|
std::vector<float>& Building::Simulation_Values::needed_con()
|
||||||
|
{
|
||||||
return NeededCon;
|
return NeededCon;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::set_needed_con(std::vector<float> needed_con) {
|
void Building::Simulation_Values::set_needed_con(std::vector<float> needed_con)
|
||||||
|
{
|
||||||
NeededCon = std::move(needed_con);
|
NeededCon = std::move(needed_con);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> &Building::Simulation_Values::needed_gen() {
|
std::vector<float>& Building::Simulation_Values::needed_gen()
|
||||||
|
{
|
||||||
return NeededGen;
|
return NeededGen;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::set_needed_gen(std::vector<float> needed_gen) {
|
void Building::Simulation_Values::set_needed_gen(std::vector<float> needed_gen)
|
||||||
|
{
|
||||||
NeededGen = std::move(needed_gen);
|
NeededGen = std::move(needed_gen);
|
||||||
}
|
}
|
||||||
|
|
||||||
float Building::Simulation_Values::relativeSelfConsumption() const {
|
float Building::Simulation_Values::relativeSelfConsumption() const
|
||||||
|
{
|
||||||
return RelativeSelfConsumption;
|
return RelativeSelfConsumption;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::set_relativeSelfConsumption(float const relativeSelfConsumption) {
|
void Building::Simulation_Values::set_relativeSelfConsumption(float const relativeSelfConsumption)
|
||||||
|
{
|
||||||
this->RelativeSelfConsumption = relativeSelfConsumption;
|
this->RelativeSelfConsumption = relativeSelfConsumption;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Building::Simulation_Values::relativeSelfGeneration() const {
|
float Building::Simulation_Values::relativeSelfGeneration() const
|
||||||
|
{
|
||||||
return RelativeGeneration;
|
return RelativeGeneration;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Simulation_Values::set_relativeSelfGeneration(float const relativeSelfGeneration) {
|
void Building::Simulation_Values::set_relativeSelfGeneration(float const relativeSelfGeneration)
|
||||||
|
{
|
||||||
this->RelativeGeneration = relativeSelfGeneration;
|
this->RelativeGeneration = relativeSelfGeneration;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Building::Metadata::name() const {
|
Building::Metadata::Metadata()
|
||||||
|
{
|
||||||
|
auto [con, gen] = CalculateProfile::calculateProfile(ConsumptionProfileName, GenerationProfileName,
|
||||||
|
AnnualConsumption, AnnualConsumption);
|
||||||
|
ConsumptionProfile = std::move(con);
|
||||||
|
GenerationProfile = std::move(gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Building::Metadata::name() const
|
||||||
|
{
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Metadata::set_name(const std::string &name) {
|
void Building::Metadata::set_name(const std::string& name)
|
||||||
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Building::Metadata::annual_consumption() const {
|
float Building::Metadata::annual_consumption() const
|
||||||
|
{
|
||||||
return AnnualConsumption;
|
return AnnualConsumption;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Metadata::set_annual_consumption(float annual_consumption) {
|
void Building::Metadata::set_annual_consumption(float annual_consumption)
|
||||||
|
{
|
||||||
AnnualConsumption = annual_consumption;
|
AnnualConsumption = annual_consumption;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Building::Metadata::annual_generation() const {
|
float Building::Metadata::annual_generation() const
|
||||||
|
{
|
||||||
return AnnualGeneration;
|
return AnnualGeneration;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Metadata::set_annual_generation(float annual_generation) {
|
void Building::Metadata::set_annual_generation(float annual_generation)
|
||||||
|
{
|
||||||
AnnualGeneration = annual_generation;
|
AnnualGeneration = annual_generation;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> &Building::Metadata::consumption_profile() {
|
std::vector<float>& Building::Metadata::consumption_profile()
|
||||||
|
{
|
||||||
return ConsumptionProfile;
|
return ConsumptionProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Metadata::set_consumption_profile(std::vector<float> consumption_profile) {
|
void Building::Metadata::set_consumption_profile(std::vector<float> consumption_profile)
|
||||||
|
{
|
||||||
ConsumptionProfile = std::move(consumption_profile);
|
ConsumptionProfile = std::move(consumption_profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> &Building::Metadata::generation_profile() {
|
std::vector<float>& Building::Metadata::generation_profile()
|
||||||
|
{
|
||||||
return GenerationProfile;
|
return GenerationProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Metadata::set_generation_profile(std::vector<float> generation_profile) {
|
void Building::Metadata::set_generation_profile(std::vector<float> generation_profile)
|
||||||
|
{
|
||||||
GenerationProfile = std::move(generation_profile);
|
GenerationProfile = std::move(generation_profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Building::Metadata::consumption_profile_name() const {
|
std::string Building::Metadata::consumption_profile_name() const
|
||||||
|
{
|
||||||
return ConsumptionProfileName;
|
return ConsumptionProfileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Metadata::set_consumption_profile_name(const std::string &consumption_profile_name) {
|
void Building::Metadata::set_consumption_profile_name(const std::string& consumption_profile_name)
|
||||||
|
{
|
||||||
ConsumptionProfileName = consumption_profile_name;
|
ConsumptionProfileName = consumption_profile_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Building::Metadata::generation_profile_name() const {
|
std::string Building::Metadata::generation_profile_name() const
|
||||||
|
{
|
||||||
return GenerationProfileName;
|
return GenerationProfileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Metadata::set_generation_profile_name(const std::string &generation_profile_name) {
|
void Building::Metadata::set_generation_profile_name(const std::string& generation_profile_name)
|
||||||
|
{
|
||||||
GenerationProfileName = generation_profile_name;
|
GenerationProfileName = generation_profile_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
short Building::Metadata::connection_power() const {
|
short Building::Metadata::connection_power() const
|
||||||
|
{
|
||||||
return ConnectionPower;
|
return ConnectionPower;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Metadata::set_connection_power(short connection_power) {
|
void Building::Metadata::set_connection_power(short connection_power)
|
||||||
|
{
|
||||||
ConnectionPower = connection_power;
|
ConnectionPower = connection_power;
|
||||||
}
|
}
|
||||||
|
|
||||||
short Building::Metadata::grid_power() const {
|
short Building::Metadata::grid_power() const
|
||||||
|
{
|
||||||
return GridPower;
|
return GridPower;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Metadata::set_grid_power(short grid_power) {
|
void Building::Metadata::set_grid_power(short grid_power)
|
||||||
|
{
|
||||||
GridPower = grid_power;
|
GridPower = grid_power;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Building::Cost> &Building::Base::cost() {
|
std::unique_ptr<Building::Cost>& Building::Base::cost()
|
||||||
|
{
|
||||||
return CostHistory;
|
return CostHistory;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Base::set_cost(std::unique_ptr<Building::Cost> cost) {
|
void Building::Base::set_cost(std::unique_ptr<Building::Cost> cost)
|
||||||
|
{
|
||||||
CostHistory = std::move(cost);
|
CostHistory = std::move(cost);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Building::Simulation_Values>& Building::Base::values() {
|
std::shared_ptr<Building::Simulation_Values>& Building::Base::values()
|
||||||
|
{
|
||||||
return Values;
|
return Values;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Base::set_values(std::shared_ptr<Simulation_Values> values) {
|
void Building::Base::set_values(std::shared_ptr<Simulation_Values> values)
|
||||||
|
{
|
||||||
Values = std::move(values);
|
Values = std::move(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Building::Metadata> &Building::Base::metadata() {
|
std::shared_ptr<Building::Metadata>& Building::Base::metadata()
|
||||||
|
{
|
||||||
return Data;
|
return Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Building::Base::set_metadata(const std::shared_ptr<Building::Metadata>& metadata) {
|
void Building::Base::set_metadata(const std::shared_ptr<Building::Metadata>& metadata)
|
||||||
|
{
|
||||||
Data = metadata;
|
Data = metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
namespace Building
|
namespace Building
|
||||||
{
|
{
|
||||||
|
|
||||||
class Cost
|
class Cost
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -126,8 +125,8 @@ namespace Building
|
|||||||
std::string Name{};
|
std::string Name{};
|
||||||
float AnnualConsumption{0.0f};
|
float AnnualConsumption{0.0f};
|
||||||
float AnnualGeneration{0.0f};
|
float AnnualGeneration{0.0f};
|
||||||
std::vector<float> ConsumptionProfile = std::vector(VALUE_COUNT, 0.0f);
|
std::vector<float> ConsumptionProfile;
|
||||||
std::vector<float> GenerationProfile = std::vector(VALUE_COUNT, 0.0f);
|
std::vector<float> GenerationProfile;
|
||||||
std::string ConsumptionProfileName{};
|
std::string ConsumptionProfileName{};
|
||||||
std::string GenerationProfileName{};
|
std::string GenerationProfileName{};
|
||||||
short ConnectionPower{0};
|
short ConnectionPower{0};
|
||||||
@ -144,7 +143,7 @@ namespace Building
|
|||||||
std::unordered_map<std::string, float> TotalByCategoryWithout{};
|
std::unordered_map<std::string, float> TotalByCategoryWithout{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Metadata() = default;
|
Metadata();
|
||||||
|
|
||||||
[[nodiscard]] std::string name() const;
|
[[nodiscard]] std::string name() const;
|
||||||
void set_name(const std::string& name);
|
void set_name(const std::string& name);
|
||||||
|
|||||||
@ -1,64 +1,81 @@
|
|||||||
#include "Community.h"
|
#include "Community.h"
|
||||||
|
|
||||||
|
|
||||||
std::string Community::name() const {
|
std::string Community::name() const
|
||||||
|
{
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Community::set_name(const std::string &name) {
|
void Community::set_name(const std::string& name)
|
||||||
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Building::Base> > &Community::buildings() {
|
std::vector<std::unique_ptr<Building::Base>>& Community::buildings()
|
||||||
|
{
|
||||||
return Buildings;
|
return Buildings;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use move semantics for efficiency
|
// Use move semantics for efficiency
|
||||||
void Community::set_buildings(std::vector<std::unique_ptr<Building::Base> > buildings) {
|
void Community::set_buildings(std::vector<std::unique_ptr<Building::Base>> buildings)
|
||||||
|
{
|
||||||
Buildings = std::move(buildings);
|
Buildings = std::move(buildings);
|
||||||
}
|
}
|
||||||
|
|
||||||
Energy_Tariff Community::energy_tariff() const {
|
Energy_Tariff Community::energy_tariff() const
|
||||||
|
{
|
||||||
return energy_Tariff;
|
return energy_Tariff;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Community::set_energy_tariff(const Energy_Tariff &energy_tariff) {
|
void Community::set_energy_tariff(const Energy_Tariff& energy_tariff)
|
||||||
|
{
|
||||||
energy_Tariff = energy_tariff;
|
energy_Tariff = energy_tariff;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> &Community::generation_available() {
|
std::vector<float>& Community::generation_available()
|
||||||
|
{
|
||||||
return GenerationAvailable;
|
return GenerationAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Community::set_generation_available(std::vector<float> &generationAvailable) {
|
void Community::set_generation_available(std::vector<float>& generationAvailable)
|
||||||
|
{
|
||||||
this->GenerationAvailable = generationAvailable;
|
this->GenerationAvailable = generationAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> &Community::consumption_available() {
|
std::vector<float>& Community::consumption_available()
|
||||||
|
{
|
||||||
return ConsumptionAvailable;
|
return ConsumptionAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Community::set_consumption_available(std::vector<float> &consumptionAvailable) {
|
void Community::set_consumption_available(std::vector<float>& consumptionAvailable)
|
||||||
|
{
|
||||||
this->ConsumptionAvailable = consumptionAvailable;
|
this->ConsumptionAvailable = consumptionAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<bool> &Community::is_gen_bigger_than_con() {
|
std::vector<bool>& Community::is_gen_bigger_than_con()
|
||||||
|
{
|
||||||
return IsGenBiggerThanCon;
|
return IsGenBiggerThanCon;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Community::set_is_gen_bigger_than_con(std::vector<bool> &isGenBiggerThanCon) {
|
void Community::set_is_gen_bigger_than_con(std::vector<bool>& isGenBiggerThanCon)
|
||||||
|
{
|
||||||
this->IsGenBiggerThanCon = isGenBiggerThanCon;
|
this->IsGenBiggerThanCon = isGenBiggerThanCon;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Community::iterateBuildings(
|
auto Community::iterateBuildings(
|
||||||
std::vector<std::unique_ptr<Community>>& Communities)
|
std::vector<std::unique_ptr<Community>>& Communities)
|
||||||
-> std::function<std::function<void(const std::function<void(Community&, Building::Base&)>&)>(
|
-> std::function<std::function<void(const std::function<void(Community&, Building::Base&)>&)>(
|
||||||
const std::function<void(Community &)> &)> {
|
const std::function<void(Community&)>&)>
|
||||||
return [&](const std::function<void(Community &)> &func1) {
|
{
|
||||||
return [&, func1](const std::function<void(Community &, Building::Base &)> &func2) {
|
return [&](const std::function<void(Community&)>& func1)
|
||||||
for (auto &community: Communities) {
|
{
|
||||||
|
return [&, func1](const std::function<void(Community&, Building::Base&)>& func2)
|
||||||
|
{
|
||||||
|
for (auto& community : Communities)
|
||||||
|
{
|
||||||
func1(*community);
|
func1(*community);
|
||||||
for (auto &building: community->buildings()) {
|
for (auto& building : community->buildings())
|
||||||
|
{
|
||||||
func2(*community, *building);
|
func2(*community, *building);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,8 @@
|
|||||||
#include "Energy_Tariff.h"
|
#include "Energy_Tariff.h"
|
||||||
|
|
||||||
|
|
||||||
class Community : public Model<Community> {
|
class Community : public Model<Community>
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
float total{0.f};
|
float total{0.f};
|
||||||
|
|
||||||
|
|||||||
@ -7,11 +7,11 @@
|
|||||||
#include "../../interfaces/ICostComponent.h"
|
#include "../../interfaces/ICostComponent.h"
|
||||||
|
|
||||||
|
|
||||||
class BillCharge : public ICostComponent {
|
class BillCharge : public ICostComponent
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
void apply(std::unique_ptr<Building::Base>& building, std::unique_ptr<Community>& community) override;
|
void apply(std::unique_ptr<Building::Base>& building, std::unique_ptr<Community>& community) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif //BILLCHARGE_H
|
#endif //BILLCHARGE_H
|
||||||
|
|||||||
@ -7,11 +7,11 @@
|
|||||||
#include "../../interfaces/ICostComponent.h"
|
#include "../../interfaces/ICostComponent.h"
|
||||||
|
|
||||||
|
|
||||||
class CalculateFinalSums : public ICostComponent{
|
class CalculateFinalSums : public ICostComponent
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
void apply(std::unique_ptr<Building::Base>& building, std::unique_ptr<Community>& community) override;
|
void apply(std::unique_ptr<Building::Base>& building, std::unique_ptr<Community>& community) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif //CALCULATEFINALSUMS_H
|
#endif //CALCULATEFINALSUMS_H
|
||||||
|
|||||||
@ -5,12 +5,15 @@
|
|||||||
#include "CostPipeline.h"
|
#include "CostPipeline.h"
|
||||||
|
|
||||||
|
|
||||||
void CostPipeline::addCostComponent(const std::shared_ptr<ICostComponent> &components) {
|
void CostPipeline::addCostComponent(const std::shared_ptr<ICostComponent>& components)
|
||||||
|
{
|
||||||
this->components.push_back(components);
|
this->components.push_back(components);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CostPipeline::calculateFinalCost() {
|
void CostPipeline::calculateFinalCost()
|
||||||
for (size_t i = 0; i < this->components.size() - 1; i++) {
|
{
|
||||||
|
for (size_t i = 0; i < this->components.size() - 1; i++)
|
||||||
|
{
|
||||||
iterateCommunity(this->components[i]);
|
iterateCommunity(this->components[i]);
|
||||||
}
|
}
|
||||||
// Ensure CalculateFinalSums is last
|
// Ensure CalculateFinalSums is last
|
||||||
@ -18,14 +21,18 @@ void CostPipeline::calculateFinalCost() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CostPipeline::iterateCommunity(std::shared_ptr<ICostComponent> &component) const {
|
void CostPipeline::iterateCommunity(std::shared_ptr<ICostComponent>& component) const
|
||||||
for (auto &community: this->communities) {
|
{
|
||||||
|
for (auto& community : this->communities)
|
||||||
|
{
|
||||||
iterateBuilding(community, component);
|
iterateBuilding(community, component);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CostPipeline::iterateBuilding(std::unique_ptr<Community> &community, std::shared_ptr<ICostComponent> &component) {
|
void CostPipeline::iterateBuilding(std::unique_ptr<Community>& community, std::shared_ptr<ICostComponent>& component)
|
||||||
for (auto &building: community->buildings()) {
|
{
|
||||||
|
for (auto& building : community->buildings())
|
||||||
|
{
|
||||||
component->apply(building, community);
|
component->apply(building, community);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,11 +7,13 @@
|
|||||||
#include "../../interfaces/ICostComponent.h"
|
#include "../../interfaces/ICostComponent.h"
|
||||||
|
|
||||||
|
|
||||||
class TaxComponent : public ICostComponent {
|
class TaxComponent : public ICostComponent
|
||||||
|
{
|
||||||
double taxRate;
|
double taxRate;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TaxComponent(const double rate) : ICostComponent(), taxRate(rate) {
|
explicit TaxComponent(const double rate) : ICostComponent(), taxRate(rate)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void apply(std::unique_ptr<Building::Base>& building, std::unique_ptr<Community>& community) override;
|
void apply(std::unique_ptr<Building::Base>& building, std::unique_ptr<Community>& community) override;
|
||||||
|
|||||||
@ -9,42 +9,56 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
class CostHistory {
|
class CostHistory
|
||||||
|
{
|
||||||
private:
|
private:
|
||||||
struct CostPoint {
|
struct CostPoint
|
||||||
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
float value{0.0f};
|
float value{0.0f};
|
||||||
float amount{0.f};
|
float amount{0.f};
|
||||||
|
|
||||||
CostPoint(std::string name, const float value, const float amount)
|
CostPoint(std::string name, const float value, const float amount)
|
||||||
: name(std::move(name)), value(value), amount(amount) {}
|
: name(std::move(name)), value(value), amount(amount)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] float total() const {
|
[[nodiscard]] float total() const
|
||||||
|
{
|
||||||
return value * amount;
|
return value * amount;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<CostPoint> costPoints{};
|
std::vector<CostPoint> costPoints{};
|
||||||
std::unordered_map<std::string, float> TotalByCategory{};
|
std::unordered_map<std::string, float> TotalByCategory{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void add_cost_point(const std::string &name, float value, float amount) {
|
void add_cost_point(const std::string& name, float value, float amount)
|
||||||
|
{
|
||||||
if (amount == 0.0) return;
|
if (amount == 0.0) return;
|
||||||
costPoints.emplace_back(name, value, amount);
|
costPoints.emplace_back(name, value, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
float total_cost() const {
|
float total_cost() const
|
||||||
|
{
|
||||||
return std::accumulate(costPoints.begin(), costPoints.end(), 0.0f,
|
return std::accumulate(costPoints.begin(), costPoints.end(), 0.0f,
|
||||||
[](const float sum, const CostPoint &point) {
|
[](const float sum, const CostPoint& point)
|
||||||
|
{
|
||||||
return sum + point.total();
|
return sum + point.total();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<CostPoint> &get_cost_points() const {
|
const std::vector<CostPoint>& get_cost_points() const
|
||||||
|
{
|
||||||
return costPoints;
|
return costPoints;
|
||||||
}
|
}
|
||||||
std::unordered_map<std::string, float> calculateCategories() {
|
|
||||||
|
std::unordered_map<std::string, float> calculateCategories()
|
||||||
|
{
|
||||||
TotalByCategory.clear();
|
TotalByCategory.clear();
|
||||||
if (costPoints.empty()) return {};
|
if (costPoints.empty()) return {};
|
||||||
for (const CostPoint& point : costPoints) {
|
for (const CostPoint& point : costPoints)
|
||||||
|
{
|
||||||
const size_t pos = point.name.find(' ');
|
const size_t pos = point.name.find(' ');
|
||||||
std::string result = (pos != std::string::npos) ? point.name.substr(0, pos) : point.name;
|
std::string result = (pos != std::string::npos) ? point.name.substr(0, pos) : point.name;
|
||||||
TotalByCategory[result] += point.total();
|
TotalByCategory[result] += point.total();
|
||||||
@ -54,5 +68,4 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif //COSTHISTORY_H
|
#endif //COSTHISTORY_H
|
||||||
|
|||||||
@ -8,10 +8,12 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
void Surplus::CalculateSurplus() {
|
void Surplus::CalculateSurplus()
|
||||||
|
{
|
||||||
auto iterateFunc = Community::iterateBuildings(communities);
|
auto iterateFunc = Community::iterateBuildings(communities);
|
||||||
|
|
||||||
auto modifyCommunity = [this](const Community &c) {
|
auto modifyCommunity = [this](const Community& c)
|
||||||
|
{
|
||||||
this->consumptionAvailable = std::vector<float>(VALUE_COUNT, 0.f);
|
this->consumptionAvailable = std::vector<float>(VALUE_COUNT, 0.f);
|
||||||
this->generationAvailable = std::vector<float>(VALUE_COUNT, 0.f);
|
this->generationAvailable = std::vector<float>(VALUE_COUNT, 0.f);
|
||||||
|
|
||||||
@ -19,8 +21,8 @@ void Surplus::CalculateSurplus() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
auto modifyBuildingSurplus = [this](Community &community, Building::Base &building) {
|
auto modifyBuildingSurplus = [this](Community& community, Building::Base& building)
|
||||||
|
{
|
||||||
CalculateBuildingSurplus(community, building);
|
CalculateBuildingSurplus(community, building);
|
||||||
|
|
||||||
community.set_consumption_available(this->consumptionAvailable);
|
community.set_consumption_available(this->consumptionAvailable);
|
||||||
@ -29,7 +31,8 @@ void Surplus::CalculateSurplus() {
|
|||||||
|
|
||||||
iterateFunc(modifyCommunity)(modifyBuildingSurplus);
|
iterateFunc(modifyCommunity)(modifyBuildingSurplus);
|
||||||
|
|
||||||
auto calculateCommunitySurplus = [this](Community &community) {
|
auto calculateCommunitySurplus = [this](Community& community)
|
||||||
|
{
|
||||||
std::vector<bool> isGenBiggerThanCon;
|
std::vector<bool> isGenBiggerThanCon;
|
||||||
std::ranges::transform(
|
std::ranges::transform(
|
||||||
consumptionAvailable, generationAvailable,
|
consumptionAvailable, generationAvailable,
|
||||||
@ -39,14 +42,16 @@ void Surplus::CalculateSurplus() {
|
|||||||
community.set_is_gen_bigger_than_con(isGenBiggerThanCon);
|
community.set_is_gen_bigger_than_con(isGenBiggerThanCon);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto calculateDistribution = [this](Community &community, Building::Base &building) {
|
auto calculateDistribution = [this](Community& community, Building::Base& building)
|
||||||
|
{
|
||||||
CalculateSurplusCommunity(community, building);
|
CalculateSurplusCommunity(community, building);
|
||||||
};
|
};
|
||||||
|
|
||||||
iterateFunc(calculateCommunitySurplus)(calculateDistribution);
|
iterateFunc(calculateCommunitySurplus)(calculateDistribution);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Surplus::CalculateBuildingSurplus(Community &community, Building::Base &building) {
|
void Surplus::CalculateBuildingSurplus(Community& community, Building::Base& building)
|
||||||
|
{
|
||||||
auto ownCoverage = std::vector(VALUE_COUNT, 0.0f);
|
auto ownCoverage = std::vector(VALUE_COUNT, 0.0f);
|
||||||
auto neededConsumption = std::vector(VALUE_COUNT, 0.0f);
|
auto neededConsumption = std::vector(VALUE_COUNT, 0.0f);
|
||||||
auto neededGeneration = std::vector(VALUE_COUNT, 0.0f);
|
auto neededGeneration = std::vector(VALUE_COUNT, 0.0f);
|
||||||
@ -58,7 +63,8 @@ void Surplus::CalculateBuildingSurplus(Community &community, Building::Base &bui
|
|||||||
const auto& generation = building.metadata()->generation_profile();
|
const auto& generation = building.metadata()->generation_profile();
|
||||||
|
|
||||||
size_t i = 0; // Fixed static variable issue
|
size_t i = 0; // Fixed static variable issue
|
||||||
std::ranges::for_each(consumption, [&](auto c_ptr) {
|
std::ranges::for_each(consumption, [&](auto c_ptr)
|
||||||
|
{
|
||||||
const float c = c_ptr ? c_ptr : 0.0f;
|
const float c = c_ptr ? c_ptr : 0.0f;
|
||||||
const float g = i < generation.size() ? generation[i] : 0.0f;
|
const float g = i < generation.size() ? generation[i] : 0.0f;
|
||||||
const float c_community = (i < consumptionAvailable.size()) ? consumptionAvailable[i] : 0.0f;
|
const float c_community = (i < consumptionAvailable.size()) ? consumptionAvailable[i] : 0.0f;
|
||||||
@ -91,24 +97,31 @@ void Surplus::CalculateBuildingSurplus(Community &community, Building::Base &bui
|
|||||||
const float totalGeneration = std::accumulate(building.metadata()->generation_profile().begin(),
|
const float totalGeneration = std::accumulate(building.metadata()->generation_profile().begin(),
|
||||||
building.metadata()->generation_profile().end(), 0.0f);
|
building.metadata()->generation_profile().end(), 0.0f);
|
||||||
|
|
||||||
if (totalConsumption > 0.0f) {
|
if (totalConsumption > 0.0f)
|
||||||
|
{
|
||||||
building.values()->set_relativeSelfConsumption(
|
building.values()->set_relativeSelfConsumption(
|
||||||
std::accumulate(building.values()->own_usage().begin(), building.values()->own_usage().end(), 0.0f) /
|
std::accumulate(building.values()->own_usage().begin(), building.values()->own_usage().end(), 0.0f) /
|
||||||
totalConsumption);
|
totalConsumption);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
building.values()->set_relativeSelfConsumption(0.0f);
|
building.values()->set_relativeSelfConsumption(0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalGeneration > 0.0f) {
|
if (totalGeneration > 0.0f)
|
||||||
|
{
|
||||||
building.values()->set_relativeSelfGeneration(
|
building.values()->set_relativeSelfGeneration(
|
||||||
std::accumulate(building.values()->own_usage().begin(), building.values()->own_usage().end(), 0.0f) /
|
std::accumulate(building.values()->own_usage().begin(), building.values()->own_usage().end(), 0.0f) /
|
||||||
totalGeneration);
|
totalGeneration);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
building.values()->set_relativeSelfGeneration(0.0f);
|
building.values()->set_relativeSelfGeneration(0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Surplus::CalculateSurplusCommunity(Community &community, Building::Base &base) {
|
void Surplus::CalculateSurplusCommunity(Community& community, Building::Base& base)
|
||||||
|
{
|
||||||
const size_t neededGenSize = base.values()->needed_gen().size();
|
const size_t neededGenSize = base.values()->needed_gen().size();
|
||||||
const size_t neededConSize = base.values()->needed_con().size();
|
const size_t neededConSize = base.values()->needed_con().size();
|
||||||
const size_t consumptionAfterCommunitySize = base.values()->consumption_after_community().size();
|
const size_t consumptionAfterCommunitySize = base.values()->consumption_after_community().size();
|
||||||
@ -124,7 +137,8 @@ void Surplus::CalculateSurplusCommunity(Community &community, Building::Base &ba
|
|||||||
neededGenSize != generationToCommunitySize ||
|
neededGenSize != generationToCommunitySize ||
|
||||||
neededGenSize != consumptionFromCommunitySize ||
|
neededGenSize != consumptionFromCommunitySize ||
|
||||||
neededGenSize != communityConsumptionSize ||
|
neededGenSize != communityConsumptionSize ||
|
||||||
neededGenSize != communityGenerationSize) {
|
neededGenSize != communityGenerationSize)
|
||||||
|
{
|
||||||
std::cerr << "Size mismatch detected in CalculateSurplusCommunity():\n";
|
std::cerr << "Size mismatch detected in CalculateSurplusCommunity():\n";
|
||||||
std::cerr << "neededGenSize: " << neededGenSize << "\n";
|
std::cerr << "neededGenSize: " << neededGenSize << "\n";
|
||||||
std::cerr << "neededConSize: " << neededConSize << "\n";
|
std::cerr << "neededConSize: " << neededConSize << "\n";
|
||||||
@ -150,11 +164,15 @@ void Surplus::CalculateSurplusCommunity(Community &community, Building::Base &ba
|
|||||||
community.consumption_available(),
|
community.consumption_available(),
|
||||||
community.generation_available(),
|
community.generation_available(),
|
||||||
community.is_gen_bigger_than_con()
|
community.is_gen_bigger_than_con()
|
||||||
)) {
|
))
|
||||||
if (isGenBigger) {
|
{
|
||||||
|
if (isGenBigger)
|
||||||
|
{
|
||||||
con_from = needed_g;
|
con_from = needed_g;
|
||||||
gen_to = needed_g / gen_available * con_available;
|
gen_to = needed_g / gen_available * con_available;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
con_from = needed_c / con_available * gen_available;
|
con_from = needed_c / con_available * gen_available;
|
||||||
gen_to = needed_c;
|
gen_to = needed_c;
|
||||||
}
|
}
|
||||||
@ -162,13 +180,15 @@ void Surplus::CalculateSurplusCommunity(Community &community, Building::Base &ba
|
|||||||
gen_after = needed_g - gen_to;
|
gen_after = needed_g - gen_to;
|
||||||
}
|
}
|
||||||
CalculateSums(base);
|
CalculateSums(base);
|
||||||
if (base.metadata()->annual_consumption() != 0) {
|
if (base.metadata()->annual_consumption() != 0)
|
||||||
|
{
|
||||||
base.values()->set_con_from_community_relative(
|
base.values()->set_con_from_community_relative(
|
||||||
std::accumulate(base.values()->consumption_from_community().begin(),
|
std::accumulate(base.values()->consumption_from_community().begin(),
|
||||||
base.values()->consumption_from_community().end(),
|
base.values()->consumption_from_community().end(),
|
||||||
0.0f) / base.metadata()->annual_consumption());
|
0.0f) / base.metadata()->annual_consumption());
|
||||||
}
|
}
|
||||||
if (base.metadata()->annual_generation() != 0) {
|
if (base.metadata()->annual_generation() != 0)
|
||||||
|
{
|
||||||
base.values()->set_gen_to_community_relative(
|
base.values()->set_gen_to_community_relative(
|
||||||
std::accumulate(base.values()->generation_to_community().begin(),
|
std::accumulate(base.values()->generation_to_community().begin(),
|
||||||
base.values()->generation_to_community().end(),
|
base.values()->generation_to_community().end(),
|
||||||
@ -176,14 +196,21 @@ void Surplus::CalculateSurplusCommunity(Community &community, Building::Base &ba
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Surplus::CalculateSums(Building::Base &base) {
|
void Surplus::CalculateSums(Building::Base& base)
|
||||||
|
{
|
||||||
const auto& values = base.values();
|
const auto& values = base.values();
|
||||||
values->set_consumption_after_own_coverage_sum(std::accumulate(values->consumption_after_own_coverage().begin(),values->consumption_after_own_coverage().end(),0.f));
|
values->set_consumption_after_own_coverage_sum(std::accumulate(values->consumption_after_own_coverage().begin(),
|
||||||
|
values->consumption_after_own_coverage().end(),
|
||||||
|
0.f));
|
||||||
values->set_own_usage_sum(std::accumulate(values->own_usage().begin(), values->own_usage().end(), 0.f));
|
values->set_own_usage_sum(std::accumulate(values->own_usage().begin(), values->own_usage().end(), 0.f));
|
||||||
values->set_needed_con_sum(std::accumulate(values->needed_con().begin(), values->needed_con().end(), 0.f));
|
values->set_needed_con_sum(std::accumulate(values->needed_con().begin(), values->needed_con().end(), 0.f));
|
||||||
values->set_needed_gen_sum(std::accumulate(values->needed_gen().begin(), values->needed_gen().end(), 0.f));
|
values->set_needed_gen_sum(std::accumulate(values->needed_gen().begin(), values->needed_gen().end(), 0.f));
|
||||||
values->set_consumption_after_community_sum(std::accumulate(values->consumption_after_community().begin(),values->consumption_after_community().end(),0.f));
|
values->set_consumption_after_community_sum(std::accumulate(values->consumption_after_community().begin(),
|
||||||
values->set_generation_after_community_sum(std::accumulate(values->generation_after_community().begin(),values->generation_after_community().end(),0.f));
|
values->consumption_after_community().end(), 0.f));
|
||||||
values->set_consumption_from_community_sum(std::accumulate(values->consumption_from_community().begin(),values->consumption_from_community().end(),0.f));
|
values->set_generation_after_community_sum(std::accumulate(values->generation_after_community().begin(),
|
||||||
values->set_generation_to_community_sum(std::accumulate(values->generation_to_community().begin(),values->generation_to_community().end(),0.f));
|
values->generation_after_community().end(), 0.f));
|
||||||
|
values->set_consumption_from_community_sum(std::accumulate(values->consumption_from_community().begin(),
|
||||||
|
values->consumption_from_community().end(), 0.f));
|
||||||
|
values->set_generation_to_community_sum(std::accumulate(values->generation_to_community().begin(),
|
||||||
|
values->generation_to_community().end(), 0.f));
|
||||||
}
|
}
|
||||||
@ -11,7 +11,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
class Surplus {
|
class Surplus
|
||||||
|
{
|
||||||
private:
|
private:
|
||||||
std::vector<std::unique_ptr<Community>>& communities;
|
std::vector<std::unique_ptr<Community>>& communities;
|
||||||
std::vector<float> consumptionAvailable;
|
std::vector<float> consumptionAvailable;
|
||||||
@ -20,7 +21,8 @@ private:
|
|||||||
public:
|
public:
|
||||||
explicit Surplus(std::vector<std::unique_ptr<Community>>& communities) : communities(communities),
|
explicit Surplus(std::vector<std::unique_ptr<Community>>& communities) : communities(communities),
|
||||||
consumptionAvailable(VALUE_COUNT, 0.0f),
|
consumptionAvailable(VALUE_COUNT, 0.0f),
|
||||||
generationAvailable(VALUE_COUNT, 0.0f) {
|
generationAvailable(VALUE_COUNT, 0.0f)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalculateSurplus();
|
void CalculateSurplus();
|
||||||
|
|||||||
9
src/singelton/UsageProfile.cpp
Normal file
9
src/singelton/UsageProfile.cpp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
//
|
||||||
|
// Created by stani on 3/14/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "UsageProfile.h"
|
||||||
|
|
||||||
|
|
||||||
|
std::mutex UsageProfile::mtx;
|
||||||
|
UsageProfile* UsageProfile::instance = nullptr;
|
||||||
49
src/singelton/UsageProfile.h
Normal file
49
src/singelton/UsageProfile.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// Created by stani on 3/14/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef USAGEPROFILE_H
|
||||||
|
#define USAGEPROFILE_H
|
||||||
|
#include <mutex>
|
||||||
|
#include "../Config.h"
|
||||||
|
#include "../helper/CsvBinary.h"
|
||||||
|
|
||||||
|
class UsageProfile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static UsageProfile* getInstance()
|
||||||
|
{
|
||||||
|
std::lock_guard lock(mtx);
|
||||||
|
if (!instance)
|
||||||
|
{
|
||||||
|
instance = new UsageProfile();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroyInstance()
|
||||||
|
{
|
||||||
|
delete instance;
|
||||||
|
instance = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
UsageProfile(const UsageProfile&) = delete;
|
||||||
|
UsageProfile& operator=(const UsageProfile&) = delete;
|
||||||
|
|
||||||
|
usageProfile ConsumptionProfile;
|
||||||
|
usageProfile GenerationProfile;
|
||||||
|
|
||||||
|
private:
|
||||||
|
UsageProfile(): ConsumptionProfile(CsvBinary::binaryToVector("Verbrauchsprofile.bin")),
|
||||||
|
GenerationProfile(CsvBinary::binaryToVector("ErzeugerProfile.bin"))
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
~UsageProfile() = default;
|
||||||
|
|
||||||
|
static UsageProfile* instance;
|
||||||
|
static std::mutex mtx;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //USAGEPROFILE_H
|
||||||
@ -12,12 +12,11 @@
|
|||||||
|
|
||||||
TEST_CASE("Test Csv to binary and back") {
|
TEST_CASE("Test Csv to binary and back") {
|
||||||
CsvBinary::csvToBinary("Verbrauchsprofile.csv","Verbrauchsprofil.bin");
|
CsvBinary::csvToBinary("Verbrauchsprofile.csv","Verbrauchsprofil.bin");
|
||||||
CsvBinary::binaryToCsv("Verbrauchsprofil.bin","Restored.csv");
|
|
||||||
auto verbrauchsProfil = CsvBinary::binaryToVector("Verbrauchsprofil.bin");
|
auto verbrauchsProfil = CsvBinary::binaryToVector("Verbrauchsprofil.bin");
|
||||||
for (auto &row: *verbrauchsProfil) {
|
for (const auto & [fst, snd]: *verbrauchsProfil) {
|
||||||
LOG_DEBUG_INFO("Sum from {}: {}",row.first ,std::accumulate(
|
LOG_DEBUG_INFO("Sum from {}: {}",fst ,std::accumulate(
|
||||||
row.second.begin(), row.second.end(), 0.f,
|
snd.begin(), snd.end(), 0.f,
|
||||||
[](float sum, const std::string& val) {
|
[](const float sum, const std::string& val) {
|
||||||
return sum + std::stof(val); // Convert string to float before addition
|
return sum + std::stof(val); // Convert string to float before addition
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|||||||
Reference in New Issue
Block a user