TalTech_cpp/CT3/booking.cpp

152 lines
5.3 KiB
C++

#pragma once
#include <cstdint>
#include <ostream>
#include <algorithm>
#include <functional>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <memory>
#include "menugen.cpp"
namespace Booking {
using seat_num = uint64_t;
using seat_range = std::pair<seat_num, seat_num>;
using uiBool = bool;
constexpr size_t SEAT_CAPACITY = 20;
class BookingException : public std::exception {
public: const char* what() const noexcept override { return "Internal exception!"; }
};
#define EXCEPTION(INTERNAL, EXTARNAL) \
class INTERNAL : public BookingException { \
const char* what() const noexcept override { return EXTARNAL; } \
};
EXCEPTION(AlreadyReserved, "Already reserved!")
EXCEPTION(NotReserved, "Not reserved!")
EXCEPTION(InvalidSeat, "Invalid seat number!");
EXCEPTION(InvalidArgument, "Invalid argument!")
class Seat : public std::enable_shared_from_this<Seat> {
struct Private{ explicit Private() = default; };
public:
enum class Type {
VIP, REGULAR, CHEAP
};
enum class Status {
AVALIBLE, RESERVED, BROKEN
};
Status s = Status::AVALIBLE;
Type c;
Seat(Private, Type t) : c(t) {}
static std::shared_ptr<Seat> create(Type t) {
return std::make_shared<Seat>(Private(), t);
}
std::shared_ptr<Seat> getptr() {
return shared_from_this();
}
};
class Booker {
private:
std::map< seat_num, std::shared_ptr< Seat > > seatmap;
std::map< Seat::Type, std::queue< std::string > > queues =
{{Seat::Type::VIP, {}}, {Seat::Type::REGULAR, {}}, {Seat::Type::CHEAP, {}}};
std::map< Seat::Type, std::queue< std::shared_ptr< Seat > > > avaliables =
{{Seat::Type::VIP, {}}, {Seat::Type::REGULAR, {}}, {Seat::Type::CHEAP, {}}};
public:
Booker(seat_num vip = 5, seat_num regular = 10, seat_num cheap = 10) {
for (seat_num i = 0; i < vip; ++i) {
auto s = Seat::create(Seat::Type::VIP);
seatmap.emplace(seatmap.size(), s->getptr() );
avaliables[Seat::Type::VIP].emplace(s->getptr());
}
for (seat_num i = 0; i < regular; ++i) {
auto s = Seat::create(Seat::Type::REGULAR);
seatmap.emplace(seatmap.size(), s->getptr() );
avaliables[Seat::Type::REGULAR].emplace(s->getptr());
}
for (seat_num i = 0; i < cheap; ++i) {
auto s = Seat::create(Seat::Type::CHEAP);
seatmap.emplace(seatmap.size(), s->getptr() );
avaliables[Seat::Type::CHEAP].emplace(s->getptr());
}
}
Seat::Status getSeatState(seat_num seat) {
return seatmap.at(seat)->s;
}
void reserveSeat(Seat::Type t, seat_num n = 1) {
for (seat_num i = 0; i < n; ++i) {
if (avaliables[t].size()) {
auto s = avaliables[t].front();
avaliables[t].pop();
seatmap[s]
}
}
}
void reserveSeat(seat_range r) {
// bool status = false;
// for (auto i = r.first - 1; i < r.second; ++i)
// status |= seats[i].s != Seat::Status::AVALIBLE;
// if (status) throw AlreadyReserved();
// for (auto i = r.first - 1; i < r.second; ++i)
// seats[i].s = Seat::Status::RESERVED;
}
void cancelSeat(seat_range r) {
// bool status = false;
// for (auto i = r.first - 1; i < r.second; ++i)
// status |= seats[i].s != Seat::Status::RESERVED;
// if (status) throw NotReserved();
// for (auto i = r.first - 1; i < r.second; ++i)
// seats[i].s = Seat::Status::AVALIBLE;
}
void breakSeat(seat_range r, std::ostream&os, const char* prefix) {
// for (auto i = r.first - 1; i < r.second; ++i) {
// if (seats[i].s == Seat::Status::RESERVED)
// os << prefix << "Reservation on seat " << i + 1 << " is canceled, seat is now broken\n";
// seats[i].s = Seat::Status::BROKEN;
// }
}
void filter(const std::function<bool(const Seat&)>& f, std::ostream& os) {
// for (seat_num i = 0; i <= SEAT_CAPACITY; ++i) {
// if (f(seats[i]))
// os << i + 1 << ' ';
// }
// os << '\n';
}
void print(seat_range r, std::ostream& os) const {
// for (seat_num i = r.first - 1; i < r.second; ++i) {
// switch (seats[i].s) {
// case Seat::Status::AVALIBLE: os << Menu::GREEN << "Seat " << i + 1 << " is avaliable\n" << Menu::RESET; break;
// case Seat::Status::RESERVED: os << Menu::YELLOW << "Seat " << i + 1 << " is reserved\n" << Menu::RESET; break;
// case Seat::Status::BROKEN: os << Menu::RED << "Seat " << i + 1 << " is broken\n" << Menu::RESET; break;
// default: break;
// }
// }
}
};
}
std::ostream& operator<<(std::ostream& os, const Booking::Booker& b) {
b.print({1, Booking::SEAT_CAPACITY}, os);
return os;
}