DiffEq - Modern C++ ODE Integration Library 1.0.0
High-performance C++ library for solving ODEs with async signal processing
Loading...
Searching...
No Matches
integrator_builder.hpp
1#pragma once
2
3#include "integrator_decorator.hpp"
4#include "timeout_decorator.hpp"
5#include "parallel_decorator.hpp"
6#include "output_decorator.hpp"
7#include "signal_decorator.hpp"
8#include "interpolation_decorator.hpp" // Fixed template parameter issues
9#include "interprocess_decorator.hpp" // Fixed template parameter issues
10// #include "event_decorator.hpp" // TODO: Fix remaining T template parameter references
11#include <memory>
12
13namespace diffeq::core::composable {
14
38template<system_state S>
40private:
41 std::unique_ptr<AbstractIntegrator<S>> integrator_;
42
43public:
48 explicit IntegratorBuilder(std::unique_ptr<AbstractIntegrator<S>> integrator)
49 : integrator_(std::move(integrator)) {
50
51 if (!integrator_) {
52 throw std::invalid_argument("Base integrator cannot be null");
53 }
54 }
55
63 integrator_ = std::make_unique<TimeoutDecorator<S>>(
64 std::move(integrator_), std::move(config));
65 return *this;
66 }
67
75 integrator_ = std::make_unique<ParallelDecorator<S>>(
76 std::move(integrator_), std::move(config));
77 return *this;
78 }
79
88 std::function<void(const S&, typename AbstractIntegrator<S>::time_type, size_t)> handler = nullptr) {
89 integrator_ = std::make_unique<OutputDecorator<S>>(
90 std::move(integrator_), std::move(config), std::move(handler));
91 return *this;
92 }
93
101 integrator_ = std::make_unique<SignalDecorator<S>>(
102 std::move(integrator_), std::move(config));
103 return *this;
104 }
105
113 integrator_ = std::make_unique<InterpolationDecorator<S>>(
114 std::move(integrator_), std::move(config));
115 return *this;
116 }
117
125 integrator_ = std::make_unique<InterprocessDecorator<S>>(
126 std::move(integrator_), std::move(config));
127 return *this;
128 }
129
130 // TODO: Uncomment when event decorator is fixed
131 /*
132 IntegratorBuilder& with_events(EventConfig config = {}) {
133 integrator_ = std::make_unique<EventDecorator<S, T>>(
134 std::move(integrator_), std::move(config));
135 return *this;
136 }
137 */
138
146 std::unique_ptr<AbstractIntegrator<S>> build() {
147 if (!integrator_) {
148 throw std::runtime_error("Builder has already been used or is in invalid state");
149 }
150 return std::move(integrator_);
151 }
152
170 template<typename DecoratorType>
171 DecoratorType* get_as() {
172 return dynamic_cast<DecoratorType*>(integrator_.get());
173 }
174
179 bool is_valid() const {
180 return integrator_ != nullptr;
181 }
182
187 std::string get_composition_info() const {
188 if (!integrator_) {
189 return "Builder is empty or has been built";
190 }
191
192 std::string info = "Composition: ";
193
194 // Try to identify decorators in the chain
195 // This is a simplified version - a real implementation might maintain
196 // a list of applied decorators for better introspection
197
198 if (dynamic_cast<TimeoutDecorator<S>*>(integrator_.get())) {
199 info += "Timeout -> ";
200 }
201 if (dynamic_cast<ParallelDecorator<S>*>(integrator_.get())) {
202 info += "Parallel -> ";
203 }
204 if (dynamic_cast<OutputDecorator<S>*>(integrator_.get())) {
205 info += "Output -> ";
206 }
207 if (dynamic_cast<SignalDecorator<S>*>(integrator_.get())) {
208 info += "Signal -> ";
209 }
210 if (dynamic_cast<InterpolationDecorator<S>*>(integrator_.get())) {
211 info += "Interpolation -> ";
212 }
213 if (dynamic_cast<InterprocessDecorator<S>*>(integrator_.get())) {
214 info += "Interprocess -> ";
215 }
216 // TODO: Uncomment when event decorator is fixed
217 /*
218 if (dynamic_cast<EventDecorator<S>*>(integrator_.get())) {
219 info += "Events -> ";
220 }
221 */
222
223 info += "Base";
224 return info;
225 }
226};
227
228// ============================================================================
229// FACTORY FUNCTIONS (Easy creation)
230// ============================================================================
231
239template<system_state S>
240auto make_builder(std::unique_ptr<AbstractIntegrator<S>> integrator) {
241 return IntegratorBuilder<S>(std::move(integrator));
242}
243
250template<typename Integrator>
251auto make_builder_copy(const Integrator& integrator) {
253 std::make_unique<Integrator>(integrator));
254}
255
256// ============================================================================
257// CONVENIENCE FUNCTIONS (Common single-decorator use cases)
258// ============================================================================
259
267template<system_state S>
268auto with_timeout_only(std::unique_ptr<AbstractIntegrator<S>> integrator,
269 TimeoutConfig config = {}) {
270 return make_builder(std::move(integrator)).with_timeout(std::move(config)).build();
271}
272
280template<system_state S>
281auto with_parallel_only(std::unique_ptr<AbstractIntegrator<S>> integrator,
282 ParallelConfig config = {}) {
283 return make_builder(std::move(integrator)).with_parallel(std::move(config)).build();
284}
285
293template<system_state S>
294auto with_interpolation_only(std::unique_ptr<AbstractIntegrator<S>> integrator,
295 InterpolationConfig config = {}) {
296 return make_builder(std::move(integrator)).with_interpolation(std::move(config)).build();
297}
298
306template<system_state S>
307auto with_interprocess_only(std::unique_ptr<AbstractIntegrator<S>> integrator,
308 InterprocessConfig config = {}) {
309 return make_builder(std::move(integrator)).with_interprocess(std::move(config)).build();
310}
311
312// TODO: Uncomment when event decorator is fixed
313/*
314template<system_state S>
315auto with_events_only(std::unique_ptr<AbstractIntegrator<S>> integrator,
316 EventConfig config = {}) {
317 return make_builder(std::move(integrator)).with_events(std::move(config)).build();
318}
319*/
320
329template<system_state S>
330auto with_output_only(std::unique_ptr<AbstractIntegrator<S>> integrator,
331 OutputConfig config = {},
332 std::function<void(const S&, typename AbstractIntegrator<S>::time_type, size_t)> handler = nullptr) {
333 return make_builder(std::move(integrator))
334 .with_output(std::move(config), std::move(handler)).build();
335}
336
344template<system_state S>
345auto with_signals_only(std::unique_ptr<AbstractIntegrator<S>> integrator,
346 SignalConfig config = {}) {
347 return make_builder(std::move(integrator)).with_signals(std::move(config)).build();
348}
349
350// ============================================================================
351// COMMON COMPOSITIONS (Frequently used combinations)
352// ============================================================================
353
361template<system_state S>
362auto for_realtime(std::unique_ptr<AbstractIntegrator<S>> integrator,
363 std::chrono::milliseconds timeout_ms = std::chrono::milliseconds{100}) {
364 return make_builder(std::move(integrator))
365 .with_timeout(TimeoutConfig{.timeout_duration = timeout_ms})
366 .with_signals()
367 .build();
368}
369
377template<system_state S>
378auto for_research(std::unique_ptr<AbstractIntegrator<S>> integrator,
379 size_t max_threads = 0) {
380 return make_builder(std::move(integrator))
381 .with_timeout(TimeoutConfig{.timeout_duration = std::chrono::hours{24}})
382 .with_parallel(ParallelConfig{.max_threads = max_threads})
383 .with_output(OutputConfig{.mode = OutputMode::OFFLINE})
384 .build();
385}
386
393template<system_state S>
394auto for_production(std::unique_ptr<AbstractIntegrator<S>> integrator) {
395 return make_builder(std::move(integrator))
396 .with_timeout(TimeoutConfig{
397 .timeout_duration = std::chrono::seconds{30},
398 .throw_on_timeout = false // Don't crash server
399 })
400 .with_output(OutputConfig{.mode = OutputMode::HYBRID})
401 .build();
402}
403
404} // namespace diffeq::core::composable
Builder for composing multiple facilities.
IntegratorBuilder(std::unique_ptr< AbstractIntegrator< S > > integrator)
Construct builder with base integrator.
bool is_valid() const
Check if the builder has a valid integrator.
IntegratorBuilder & with_parallel(ParallelConfig config={})
Add parallel execution facility.
IntegratorBuilder & with_output(OutputConfig config={}, std::function< void(const S &, typename AbstractIntegrator< S >::time_type, size_t)> handler=nullptr)
Add output handling facility.
IntegratorBuilder & with_timeout(TimeoutConfig config={})
Add timeout protection facility.
IntegratorBuilder & with_interprocess(InterprocessConfig config={})
Add interprocess facility.
std::string get_composition_info() const
Get information about the current composition.
DecoratorType * get_as()
Get specific decorator type from the composition chain.
IntegratorBuilder & with_interpolation(InterpolationConfig config={})
Add interpolation facility.
std::unique_ptr< AbstractIntegrator< S > > build()
Build the final composed integrator.
IntegratorBuilder & with_signals(SignalConfig config={})
Add signal processing facility.
Interpolation decorator - adds dense output capabilities to any integrator.
Output decorator - adds configurable output to any integrator.
Parallel execution decorator - adds batch processing to any integrator.
Signal decorator - adds signal processing to any integrator.
Timeout decorator - adds timeout protection to any integrator.
Configuration for interpolation and dense output.
Configuration for interprocess communication.
Configuration for output handling.
Configuration for parallel execution.
Configuration for signal processing.
Timeout configuration for integration protection.