#include #include #include #include // ============================================================================= // EXEMPLE D'UTILISATION DES DÉFENSES WARFACTORY // ============================================================================= namespace warfactory::examples { // ============================================================================= // ECONOMIC ENGINE EXAMPLE // ============================================================================= class Market { private: std::vector prices_; double total_volume_ = 0.0; public: // Constructor avec contracts explicit Market(size_t initial_capacity) { WARFACTORY_REQUIRE(initial_capacity > 0); prices_.reserve(initial_capacity); WARFACTORY_ENSURE(prices_.capacity() >= initial_capacity); WARFACTORY_INVARIANT(total_volume_ == 0.0); } // Ajouter un prix au marché (peut être négatif !) void add_price(double price, double volume) { WARFACTORY_REQUIRE_NOT_NULL(&prices_); WARFACTORY_REQUIRE(std::isfinite(price)); WARFACTORY_REQUIRE(std::isfinite(volume)); WARFACTORY_REQUIRE(volume > 0.0); // Volume doit être positif par contre double old_total = total_volume_; prices_.push_back(price); total_volume_ += volume; WARFACTORY_ENSURE(prices_.size() > 0); WARFACTORY_ENSURE(std::isfinite(total_volume_)); WARFACTORY_ENSURE(total_volume_ == old_total + volume); WARFACTORY_INVARIANT(check_invariants()); } // Calculer prix moyen pondéré double weighted_average_price() const { WARFACTORY_REQUIRE(!prices_.empty()); WARFACTORY_REQUIRE(total_volume_ > 0.0); double weighted_sum = 0.0; double volume_per_price = total_volume_ / prices_.size(); for (double price : prices_) { WARFACTORY_PROPERTY_FINITE_VALUES(price); weighted_sum += price * volume_per_price; } double result = weighted_sum / total_volume_; WARFACTORY_ENSURE_NOT_NULL(&result); WARFACTORY_ENSURE(std::isfinite(result)); return result; } // Exemple de fail-fast sur condition impossible void process_transaction(double amount) { WARFACTORY_REQUIRE(std::isfinite(amount)); if (amount == 0.0) { // Transaction vide, juste ignorer return; } // Condition qui ne devrait jamais arriver if (std::isnan(amount) || std::isinf(amount)) { WARFACTORY_FAIL_FAST_IF(true); // Crash immédiat } // Traitement normal... total_volume_ += std::abs(amount); WARFACTORY_INVARIANT(check_invariants()); } private: bool check_invariants() const { return std::isfinite(total_volume_) && total_volume_ >= 0.0 && prices_.size() < 1000000; // Limite raisonnable } }; // ============================================================================= // FACTORY ENGINE EXAMPLE // ============================================================================= class Production { private: std::vector inputs_; std::vector outputs_; public: void add_production_step(const std::vector& inputs, const std::vector& outputs) { WARFACTORY_REQUIRE(!inputs.empty()); WARFACTORY_REQUIRE(!outputs.empty()); WARFACTORY_REQUIRE(inputs.size() == outputs.size()); double total_input = 0.0; double total_output = 0.0; for (size_t i = 0; i < inputs.size(); ++i) { WARFACTORY_REQUIRE(std::isfinite(inputs[i])); WARFACTORY_REQUIRE(std::isfinite(outputs[i])); WARFACTORY_REQUIRE(inputs[i] >= 0.0); // Les inputs sont non-négatifs WARFACTORY_REQUIRE(outputs[i] >= 0.0); // Les outputs aussi total_input += inputs[i]; total_output += outputs[i]; inputs_.push_back(inputs[i]); outputs_.push_back(outputs[i]); } // Conservation de masse (avec tolérance) WARFACTORY_PROPERTY_CONSERVATION_OF_MASS(total_input, total_output); WARFACTORY_ENSURE(inputs_.size() == outputs_.size()); WARFACTORY_INVARIANT(!inputs_.empty() && !outputs_.empty()); } }; // ============================================================================= // PROPERTY-BASED TESTING EXAMPLE // ============================================================================= // Test que toutes les valeurs restent finies WARFACTORY_PROPERTY(market_values_always_finite, Market& market, double price, double volume) { if (volume <= 0.0) return; // Skip invalid volumes if (!std::isfinite(price) || !std::isfinite(volume)) return; // Skip invalid inputs market.add_price(price, volume); // Property: Le prix moyen doit toujours être fini if (!market.weighted_average_price()) { WARFACTORY_UNREACHABLE(); // Ne devrait jamais arriver } double avg = market.weighted_average_price(); WARFACTORY_PROPERTY_FINITE_VALUES(avg); } // Test de conservation de masse WARFACTORY_PROPERTY(production_conserves_mass, Production& prod) { std::vector inputs = {10.0, 5.0, 2.0}; std::vector outputs = {8.0, 6.0, 3.0}; // Total égal // Cette propriété devrait passer prod.add_production_step(inputs, outputs); } } // namespace warfactory::examples // ============================================================================= // MAIN EXAMPLE // ============================================================================= int main() { try { using namespace warfactory::examples; // Test du marché avec prix négatifs (subventions) Market market(100); market.add_price(150.0, 10.0); // Prix normal market.add_price(-50.0, 5.0); // Subvention ! market.add_price(200.0, 15.0); // Prix élevé double avg = market.weighted_average_price(); printf("Prix moyen pondéré: %.2f (avec subventions)\n", avg); // Test de production Production prod; std::vector inputs = {100.0, 50.0}; std::vector outputs = {75.0, 75.0}; // Conservation parfaite prod.add_production_step(inputs, outputs); printf("Production ajoutée avec conservation de masse\n"); return 0; } catch (const warfactory::contracts::ContractViolation& e) { fprintf(stderr, "CONTRACT VIOLATION: %s\n", e.what()); return 1; } catch (const std::exception& e) { fprintf(stderr, "ERROR: %s\n", e.what()); return 1; } }