shushus

Спринт 12. Путешествия с RAII. Задание 2.

Apr 6th, 2023
597
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.37 KB | None | 0 0
  1. -----------------------------------------------------------------------
  2. main.cpp
  3. -----------------------------------------------------------------------
  4. #include "new_trip_manager.h"
  5.  
  6. #include <cassert>
  7. #include <iostream>
  8. #include <stdexcept>
  9.  
  10. using namespace std;
  11.  
  12. int FlightProvider::capacity = 0;
  13. int FlightProvider::counter = 0;
  14.  
  15. int HotelProvider::capacity = 0;
  16. int HotelProvider::counter = 0;
  17.  
  18. void TestNoOverbooking() {
  19.     FlightProvider::capacity = 100;
  20.     HotelProvider::capacity = 100;
  21.     FlightProvider::counter = 0;
  22.     HotelProvider::counter = 0;
  23.     {
  24.         TripManager tm;
  25.         auto trip = tm.Book({});
  26.     }
  27.     assert(FlightProvider::counter == 0);
  28.     assert(HotelProvider::counter == 0);
  29. }
  30.  
  31. void TestFlightOverbooking() {
  32.     FlightProvider::capacity = 1;
  33.     HotelProvider::capacity = 100;
  34.     FlightProvider::counter = 0;
  35.     HotelProvider::counter = 0;
  36.     try {
  37.         TripManager tm;
  38.         auto trip = tm.Book({});
  39.     } catch (const runtime_error&) {
  40.         assert(FlightProvider::counter == 0);
  41.         assert(HotelProvider::counter == 0);
  42.         return;
  43.     }
  44.     cout << "Flight overbooking was expected"s << endl;
  45. }
  46.  
  47. void TestHotelOverbooking() {
  48.     FlightProvider::capacity = 100;
  49.     HotelProvider::capacity = 0;
  50.     FlightProvider::counter = 0;
  51.     HotelProvider::counter = 0;
  52.     try {
  53.         TripManager tm;
  54.         auto trip = tm.Book({});
  55.     } catch (const runtime_error& ex) {
  56.         assert(FlightProvider::counter == 0);
  57.         assert(HotelProvider::counter == 0);
  58.         return;
  59.     }
  60.     cout << "Hotel overbooking was expected"s << endl;
  61. }
  62.  
  63. int main() {
  64.     TestNoOverbooking();
  65.     TestFlightOverbooking();
  66.     TestHotelOverbooking();
  67. }
  68. -----------------------------------------------------------------------
  69. new_flight_provider.h
  70. -----------------------------------------------------------------------
  71. #pragma once
  72.  
  73. #include "booking.h"
  74. #include <iostream>
  75.  
  76. #include <stdexcept>
  77. #include <string>
  78.  
  79. class FlightProvider {
  80. public:
  81.     using BookingId = int;
  82.     using Booking = raii::Booking<FlightProvider>;
  83.     friend Booking;
  84.  
  85.     struct BookingData {
  86.         std::string city_from;
  87.         std::string city_to;
  88.         std::string date;
  89.     };
  90.  
  91.     Booking Book(const BookingData&) {
  92.         using namespace std;
  93.        
  94.         if (counter >= capacity) {
  95.             throw runtime_error("Flight overbooking"s);
  96.         }
  97.         counter++;
  98.         return {this, counter};
  99.     }
  100.  
  101. private:
  102.  
  103.     void CancelOrComplete(const Booking&) {
  104.         counter--;
  105.         if (0 > counter) {
  106.             counter = 0;
  107.         }
  108.     }
  109.  
  110. public:
  111.     static int capacity;
  112.     static int counter;
  113. };
  114. -----------------------------------------------------------------------
  115. new_hotel_provider.h
  116. -----------------------------------------------------------------------
  117. #pragma once
  118. #include <stdexcept>
  119. #include <string>
  120.  
  121. class HotelProvider {
  122. public:
  123.     using BookingId = int;
  124.     using Booking = raii::Booking<HotelProvider>;
  125.     friend Booking;
  126.  
  127.     struct BookingData {
  128.         std::string city;
  129.         std::string date_from;
  130.         std::string date_to;
  131.     };
  132.  
  133.     Booking Book(const BookingData&) {
  134.         using namespace std;
  135.         if (counter >= capacity) {
  136.             throw runtime_error("Hotel overbooking"s);
  137.         }
  138.         counter++;
  139.         return {this, counter};
  140.     }
  141.  
  142. private:
  143.     void CancelOrComplete(const Booking&) {
  144.         counter--;
  145.         if (0 > counter) {
  146.             counter = 0;
  147.         }
  148.     }
  149.  
  150. public:
  151.     static int capacity;
  152.     static int counter;
  153. };
  154. -----------------------------------------------------------------------
  155. new_trip_manager.h
  156. -----------------------------------------------------------------------
  157. #pragma once
  158. #include "new_flight_provider.h"
  159. #include "new_hotel_provider.h"
  160.  
  161. #include <vector>
  162.  
  163. class Trip {
  164. public:
  165.     std::vector<HotelProvider::Booking> hotels;
  166.     std::vector<FlightProvider::Booking> flights;
  167.  
  168.     Trip() = default;
  169.     Trip(const Trip&) = delete;
  170.     Trip(Trip&&) = default;
  171.     ~Trip() = default;
  172.  
  173.     Trip& operator=(const Trip&) = delete;
  174.     Trip& operator=(Trip&&) = default;
  175.  
  176.     void Cancel() {
  177.         hotels.clear();
  178.         flights.clear();
  179.     }
  180. };
  181.  
  182. class TripManager {
  183. public:
  184.     struct BookingData {
  185.         std::string city_from;
  186.         std::string city_to;
  187.         std::string date_from;
  188.         std::string date_to;
  189.     };
  190.  
  191.     Trip Book(const BookingData&) {
  192.         Trip trip;
  193.         {
  194.             FlightProvider::BookingData flight_booking_data;
  195.             trip.flights.push_back(flight_provider_.Book(flight_booking_data));
  196.         }
  197.         {
  198.             HotelProvider::BookingData hotel_booking_data;
  199.             trip.hotels.push_back(hotel_provider_.Book(hotel_booking_data));
  200.         }
  201.         {
  202.             FlightProvider::BookingData flight_booking_data;
  203.             trip.flights.push_back(flight_provider_.Book(flight_booking_data));
  204.         }
  205.         return trip;
  206.     }
  207.  
  208.     void Cancel(Trip& trip) {
  209.         trip.Cancel();
  210.     }
  211.  
  212. private:
  213.     HotelProvider hotel_provider_;
  214.     FlightProvider flight_provider_;
  215. };
  216. -----------------------------------------------------------------------
  217. booking.h
  218. -----------------------------------------------------------------------
  219. #pragma once
  220.  
  221. #include <utility>
  222. #include <cassert>
  223.  
  224. namespace raii {
  225.  
  226. template <typename Provider>
  227. class Booking {
  228. public:
  229.     using BookingId = typename Provider::BookingId;
  230.        
  231.     Booking(Provider* p, BookingId id) : provider_(p), id_(id) {}
  232.    
  233.     Booking(const Booking&) = delete;        
  234.     Booking& operator=(const Booking&) = delete;
  235.    
  236.     Booking(Booking&& other) {
  237.    
  238.         assert(provider_ == nullptr);
  239.         provider_ = std::exchange(other.provider_, nullptr);
  240.         id_ = std::move(other.id_);
  241.        
  242.     }
  243.    
  244.     Booking& operator=(Booking&& other) {
  245.    
  246.         if (provider_ != other.provider_) {
  247.             provider_ = std::exchange(other.provider_, nullptr);
  248.             id_ = std::move(other.id_);
  249.         }
  250.        
  251.         return *this;
  252.     }
  253.    
  254.     ~Booking() {
  255.    
  256.         provider_->CancelOrComplete(*this);
  257.     }
  258.  
  259.     BookingId GetId() const {
  260.    
  261.         return id_;
  262.     }
  263.  
  264. private:
  265.     Provider* provider_ = nullptr;
  266.     BookingId id_;
  267.    
  268. };
  269.    
  270. }//end namespace booking
Advertisement
Add Comment
Please, Sign In to add comment