Curring magic

This commit is contained in:
2025-03-10 21:04:58 +01:00
parent a3c34ab6bc
commit b0056c9004
16 changed files with 296 additions and 44 deletions

View File

@ -14,6 +14,14 @@ add_executable(Sim_C__
src/services/Surplus.cpp src/services/Surplus.cpp
src/services/Surplus.h src/services/Surplus.h
tests/services/test_Surplus.cpp tests/services/test_Surplus.cpp
src/model/Model.h
tests/model/Factory.h
src/services/Cost/CostPipeline.cpp
src/services/Cost/CostPipeline.h
src/interfaces/ICostComponent.h
src/services/Cost/TaxComponent.cpp
src/services/Cost/TaxComponent.h
src/helper/Curry.h
) )
find_package(doctest CONFIG REQUIRED) find_package(doctest CONFIG REQUIRED)
target_link_libraries(Sim_C__ PRIVATE doctest::doctest) target_link_libraries(Sim_C__ PRIVATE doctest::doctest)

14
src/helper/Curry.h Normal file
View File

@ -0,0 +1,14 @@
//
// Created by stani on 3/10/2025.
//
#ifndef CURRY_H
#define CURRY_H
template <typename Func1, typename Func2>
auto curry(Func1 f1, Func2 f2) {
return [=](auto... args) {
auto result1 = f1(args...);
return f2(result1);
};
}
#endif //CURRY_H

View File

@ -0,0 +1,15 @@
//
// Created by stani on 3/10/2025.
//
#ifndef ICOSTCOMPONENT_H
#define ICOSTCOMPONENT_H
#include "../model/Community.h"
class ICostComponent
{
public:
virtual ~ICostComponent() = default;
virtual double apply(std::vector<std::unique_ptr<Community>>& communities) const = 0;
};
#endif //ICOSTCOMPONENT_H

View File

@ -129,7 +129,7 @@ std::unique_ptr<Building::Cost>& Building::Base::cost() {
return Cost; return Cost;
} }
void Building::Base::set_cost(std::unique_ptr<Building::Cost> &cost) { void Building::Base::set_cost(std::unique_ptr<Building::Cost> cost) {
Cost = std::move(cost); Cost = std::move(cost);
} }
@ -137,7 +137,7 @@ std::unique_ptr<Building::Simulation_Values>& Building::Base::values() {
return Values; return Values;
} }
void Building::Base::set_values(std::unique_ptr<Simulation_Values> &values) { void Building::Base::set_values(std::unique_ptr<Simulation_Values> values) {
Values = std::move(values); Values = std::move(values);
} }
@ -145,15 +145,8 @@ std::unique_ptr<Building::Metadata>& Building::Base::metadata() {
return Metadata; return Metadata;
} }
void Building::Base::set_metadata(std::unique_ptr<Building::Metadata> &metadata) { void Building::Base::set_metadata(std::unique_ptr<Building::Metadata> metadata) {
Metadata = std::move(metadata); Metadata = std::move(metadata);
} }
void Building::Base::iterateBuildings(std::vector<std::unique_ptr<Building::Base>> &buildings,
const std::function<void(Building::Base &)>& function) {
for (auto &building : buildings) {
function(*building);
}
}

View File

@ -8,6 +8,8 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "Model.h"
namespace Building { namespace Building {
class Cost { class Cost {
@ -15,6 +17,7 @@
float SpecialRateConsumption; float SpecialRateConsumption;
float SpecialRateGeneration; float SpecialRateGeneration;
public: public:
float special_rate_consumption() const; float special_rate_consumption() const;
void set_special_rate_consumption(float special_rate_consumption); void set_special_rate_consumption(float special_rate_consumption);
float special_rate_generation() const; float special_rate_generation() const;
@ -68,21 +71,19 @@
void set_grid_power(short grid_power); void set_grid_power(short grid_power);
}; };
class Base { class Base : public Model<Base>
{
private: private:
std::unique_ptr<Cost> Cost; std::unique_ptr<Cost> Cost;
std::unique_ptr<Simulation_Values> Values; std::unique_ptr<Simulation_Values> Values;
std::unique_ptr<Metadata> Metadata; std::unique_ptr<Metadata> Metadata;
public: public:
std::unique_ptr<Building::Cost>& cost(); std::unique_ptr<Building::Cost>& cost();
void set_cost(std::unique_ptr<Building::Cost> &cost); void set_cost(std::unique_ptr<Building::Cost> cost);
std::unique_ptr<Simulation_Values> & values(); std::unique_ptr<Simulation_Values> & values();
void set_values(std::unique_ptr<Simulation_Values> &values); void set_values(std::unique_ptr<Simulation_Values> values);
std::unique_ptr<Building::Metadata> & metadata(); std::unique_ptr<Building::Metadata> & metadata();
void set_metadata(std::unique_ptr<Building::Metadata> &metadata); void set_metadata(std::unique_ptr<Building::Metadata> metadata);
static void iterateBuildings(std::vector<std::unique_ptr<Building::Base> > &buildings,
const std::function<void(Building::Base &)>& function);
}; };
} }

View File

@ -1,5 +1,7 @@
#include "Community.h" #include "Community.h"
#include "../helper/Curry.h"
std::string Community::name() const { std::string Community::name() const {
return Name; return Name;
} }
@ -25,9 +27,19 @@ void Community::set_energy_tariff(const Energy_Tariff& energy_tariff) {
energy_Tariff = energy_tariff; energy_Tariff = energy_tariff;
} }
void Community::iterateCommunities(std::vector<std::shared_ptr<Community>> &communities, auto Community::iterateBuildings(std::vector<std::unique_ptr<Community>>& Communities) -> std::function<std::function<void(const std::function<void(Building::Base&)>&)>(const std::function<void(Community&)>&)>
const std::function<void(std::shared_ptr<Community>&)> &function) { {
for (auto &community : communities) { return [&](const std::function<void(Community&)>& func1) {
function(community); return [&, func1](const std::function<void(Building::Base&)>& func2) {
} // First apply func1 to each Community
} iterateVector(Communities, func1);
// Second apply func2 to each building inside each Community
iterateVector(Communities, [&](Community& community) {
for (auto& building : community.buildings()) {
func2(*building); // Apply func2 to each Building::Base
}
});
};
};
}

View File

@ -11,11 +11,12 @@
#include "Energy_Tariff.h" #include "Energy_Tariff.h"
class Community { class Community : public Model<Community>
{
public: public:
std::string name() const; std::string name() const;
void set_name(const std::string &name); void set_name(const std::string& name);
std::vector<std::unique_ptr<Building::Base>>& buildings(); std::vector<std::unique_ptr<Building::Base>>& buildings();
@ -23,17 +24,17 @@ public:
Energy_Tariff energy_tariff() const; Energy_Tariff energy_tariff() const;
void set_energy_tariff(const Energy_Tariff &energy_tariff); void set_energy_tariff(const Energy_Tariff& energy_tariff);
static void iterateCommunities(std::vector<std::shared_ptr<Community>> &communities, static std::function<std::function<void(const std::function<void(Building::Base&)>&)>
const std::function<void(std::shared_ptr<Community> &)> &function); (const std::function<void(Community&)>&)>
iterateBuildings(std::vector<std::unique_ptr<Community>>& Communities);
private: private:
std::string Name; std::string Name;
std::vector<std::unique_ptr<Building::Base>> Buildings; std::vector<std::unique_ptr<Building::Base>> Buildings;
Energy_Tariff energy_Tariff; Energy_Tariff energy_Tariff;
}; };
#endif //COMMUNITY_H #endif //COMMUNITY_H

20
src/model/Model.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef MODEL_H
#define MODEL_H
#include <functional>
#include <memory>
#include <vector>
template <class T>
class Model {
public:
static void iterateVector(std::vector<std::unique_ptr<T>>& vector,
const std::function<void(T&)>& function)
{
for (auto& item : vector) {
function(*item);
}
}
};
#endif // MODEL_H

View File

@ -0,0 +1,18 @@
//
// Created by stani on 3/10/2025.
//
#include "CostPipeline.h"
void CostPipeline::addCostComponent(const std::shared_ptr<ICostComponent>& components)
{
this->components.push_back(components);
}
void CostPipeline::calculateFinalCost()
{
for (auto& component: this->components)
{
component->apply(this->communities);
}
}

View File

@ -0,0 +1,23 @@
//
// Created by stani on 3/10/2025.
//
#ifndef COSTPIPELINE_H
#define COSTPIPELINE_H
#include <memory>
#include <vector>
#include "../../interfaces/ICostComponent.h"
#include "../../model/Community.h"
class CostPipeline {
std::vector<std::unique_ptr<Community>>& communities;
std::vector<std::shared_ptr<ICostComponent>> components;
public:
CostPipeline(std::vector<std::unique_ptr<Community>>& communities) : communities(communities){}
void addCostComponent(const std::shared_ptr<ICostComponent>& components);
void calculateFinalCost();
};
#endif //COSTPIPELINE_H

View File

@ -0,0 +1,16 @@
//
// Created by stani on 3/10/2025.
//
#include "TaxComponent.h"
void TaxComponent::applyCost(std::vector<std::unique_ptr<Community>>& communities)
{
Community::iterateVector(communities, [&](Community& community)
{
Building::Base::iterateVector(community.buildings(), [&](Building::Base& building)
{
});
});
}

View File

@ -0,0 +1,19 @@
//
// Created by stani on 3/10/2025.
//
#ifndef TAXCOMPONENT_H
#define TAXCOMPONENT_H
#include "../../interfaces/ICostComponent.h"
class TaxComponent : public ICostComponent{
double taxRate;
public:
TaxComponent(double rate) : taxRate(rate){}
void applyCost(std::vector<std::unique_ptr<Community>>& communities);
};
#endif //TAXCOMPONENT_H

View File

@ -7,20 +7,23 @@
#include "../model/Building.h" #include "../model/Building.h"
#include <algorithm> #include <algorithm>
#include <execution> #include <execution>
#include <iostream>
#include <vector> #include <vector>
void Surplus::CalculateSurplus(std::vector<std::shared_ptr<Community>> &communities) { void Surplus::CalculateSurplus(std::vector<std::unique_ptr<Community>>& communities) {
std::vector<float> consumptionAvailable(VALUE_COUNT, 0.0); std::vector<float> consumptionAvailable(VALUE_COUNT, 0.0);
std::vector<float> generationAvailable(VALUE_COUNT, 0.0); std::vector<float> generationAvailable(VALUE_COUNT, 0.0);
auto iterateFunc = Community::iterateBuildings(communities);
Community::iterateCommunities(communities, [&](const std::shared_ptr<Community>& community) { auto modifyCommunity = [](Community& c) {
auto &buildings = community->buildings(); std::cout << "Processing Community\n";
};
Building::Base::iterateBuildings(buildings, [&](Building::Base &building) { auto modifyBuilding = [](Building::Base& building) {
CalculateBuildingSurplus(building); std::cout << "Processing Building\n";
}); CalculateBuildingSurplus(building);
}); };
auto nestedFunc = iterateFunc(modifyCommunity);
nestedFunc(modifyBuilding);
} }
void Surplus::CalculateBuildingSurplus(Building::Base& building) { void Surplus::CalculateBuildingSurplus(Building::Base& building) {

View File

@ -14,13 +14,13 @@ class Community;
class Surplus { class Surplus {
private: private:
std::vector<std::shared_ptr<Community>> &communities; std::vector<std::unique_ptr<Community>>& communities;
public: public:
Surplus(std::vector<std::shared_ptr<Community>> &communities):communities(communities){}; Surplus(std::vector<std::unique_ptr<Community>>& communities) : communities(communities) {}
void CalculateSurplus(std::vector<std::shared_ptr<Community>> &communities); void static CalculateSurplus(std::vector<std::unique_ptr<Community>>& communities);
void CalculateBuildingSurplus(Building::Base&); void static CalculateBuildingSurplus(Building::Base&);
}; };

104
tests/model/Factory.h Normal file
View File

@ -0,0 +1,104 @@
//
// Created by stani on 3/10/2025.
//
#ifndef FACTORY_H
#define FACTORY_H
#include <memory>
#include "../../src/model/Building.h"
#include "../../src/model/Community.h"
#include "../../src/model/Energy_Tariff.h"
namespace Building
{
class Cost;
}
class Factory {
public:
std::unique_ptr<Building::Cost> static create_test_cost() {
auto cost = std::make_unique<Building::Cost>();
cost->set_special_rate_consumption(0.15f);
cost->set_special_rate_generation(0.10f);
return cost;
}
std::unique_ptr<Building::Simulation_Values> static create_test_simulation_values() {
auto values = std::make_unique<Building::Simulation_Values>();
auto communityCoverage = std::vector<std::unique_ptr<float>>();
auto ownUsage = std::vector<std::unique_ptr<float>>();
auto neededCon = std::vector<std::unique_ptr<float>>();
auto neededGen = std::vector<std::unique_ptr<float>>();
for (int i = 0; i < 5; i++) { // Populate with test values
communityCoverage.push_back(std::make_unique<float>(i * 10.0f));
ownUsage.push_back(std::make_unique<float>(i * 5.0f));
neededCon.push_back(std::make_unique<float>(i * 3.0f));
neededGen.push_back(std::make_unique<float>(i * 2.0f));
}
values->set_community_coverage(std::move(communityCoverage));
values->set_own_usage(std::move(ownUsage));
values->set_needed_con(std::move(neededCon));
values->set_needed_gen(std::move(neededGen));
return values;
}
std::unique_ptr<Building::Metadata> static create_test_metadata() {
auto metadata = std::make_unique<Building::Metadata>();
metadata->set_name("Test Building");
metadata->set_annual_consumption(12000.0f);
metadata->set_annual_generation(5000.0f);
metadata->set_consumption_profile_name("Profile_1");
metadata->set_generation_profile_name("Profile_2");
metadata->set_connection_power(100);
metadata->set_grid_power(50);
auto consumptionProfile = std::vector<std::unique_ptr<float>>();
auto generationProfile = std::vector<std::unique_ptr<float>>();
for (int i = 0; i < 5; i++) { // Populate with test values
consumptionProfile.push_back(std::make_unique<float>(i * 100.0f));
generationProfile.push_back(std::make_unique<float>(i * 50.0f));
}
metadata->set_consumption_profile(std::move(consumptionProfile));
metadata->set_generation_profile(std::move(generationProfile));
return metadata;
}
std::unique_ptr<Building::Base> static create_test_building() {
auto building = std::make_unique<Building::Base>();
building->set_cost( create_test_cost());
building->set_values(create_test_simulation_values());
building->set_metadata(create_test_metadata());
return building;
}
Energy_Tariff static create_test_energy_tariff() {
return {};
}
std::unique_ptr<Community> static create_test_community() {
auto community = std::make_unique<Community>();
community->set_name("Test Community");
std::vector<std::unique_ptr<Building::Base>> buildings;
for (int i = 0; i < 3; i++) {
buildings.push_back(create_test_building());
}
community->set_buildings(std::move(buildings));
community->set_energy_tariff(create_test_energy_tariff());
return community;
}
};
#endif //FACTORY_H

View File

@ -2,8 +2,13 @@
// Created by StanislausCichocki on 10.03.2025. // Created by StanislausCichocki on 10.03.2025.
// //
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "../../src/services/Surplus.h"
#include "doctest/doctest.h" #include "doctest/doctest.h"
#include "../model/Factory.h"
TEST_CASE("Testing add function") { TEST_CASE("Testing add function") {
std::vector<std::unique_ptr<Community>> communities;
communities.push_back(Factory::create_test_community());
Surplus::CalculateSurplus(communities);
CHECK(true); CHECK(true);
} }