115 lines
3.8 KiB
C++
115 lines
3.8 KiB
C++
// #include "booking.cpp"
|
|
#include <algorithm>
|
|
#include <numeric>
|
|
|
|
namespace Booking {
|
|
// 1. Calculate total free/booked seats - std::accumulate
|
|
std::pair<size_t, size_t> Booker::calculateSeatStatistics() const {
|
|
m.lock_shared();
|
|
auto ret = std::accumulate(seats.begin(), seats.end(), std::make_pair<size_t, size_t>(0, 0),
|
|
[](std::pair<size_t, size_t> acc, const std::pair<seat_num, Seat>& p) {
|
|
if (p.second.s == Seat::Status::AVALIBLE) ++acc.first;
|
|
if (p.second.s == Seat::Status::RESERVED) ++acc.second;
|
|
return acc;
|
|
}
|
|
);
|
|
m.unlock_shared();
|
|
|
|
return ret;
|
|
}
|
|
|
|
// 2. Sort clients by name using std::sort
|
|
std::vector<std::string> Booker::getSortedClients() const {
|
|
m.lock_shared();
|
|
std::vector<std::string> clients;
|
|
for (const auto& kv : seats) {
|
|
if (kv.second.s == Seat::Status::RESERVED)
|
|
clients.push_back(kv.second.reservation_name);
|
|
}
|
|
m.unlock_shared();
|
|
|
|
std::sort(clients.begin(), clients.end());
|
|
return clients;
|
|
}
|
|
|
|
// 3. Find the client with the highest seat number using std::max_element
|
|
std::pair<seat_num, std::string> Booker::getHighestSeatReservation() const {
|
|
m.lock_shared();
|
|
auto it = std::max_element(seats.begin(), seats.end(),
|
|
[](auto& a, auto& b) {
|
|
bool ra = (a.second.s == Seat::Status::RESERVED);
|
|
bool rb = (b.second.s == Seat::Status::RESERVED);
|
|
if (ra != rb) return !ra;
|
|
return a.first < b.first;
|
|
}
|
|
);
|
|
auto end = seats.end();
|
|
m.unlock_shared();
|
|
|
|
if (it == end || it->second.s != Seat::Status::RESERVED)
|
|
throw NotReserved();
|
|
return { it->first, it->second.reservation_name };
|
|
}
|
|
|
|
// 4. Reverse display of seats using std::reverse and iteration
|
|
void Booker::displaySeatsReversed(std::ostream& os) const {
|
|
m.lock_shared();
|
|
std::vector<std::pair<seat_num, Seat>> vec(seats.begin(), seats.end());
|
|
m.unlock_shared();
|
|
|
|
std::reverse(vec.begin(), vec.end());
|
|
for (const auto& kv : vec) {
|
|
os << "Seat " << kv.first << ": ";
|
|
switch (kv.second.s) {
|
|
case Seat::Status::AVALIBLE: os << Menu::GREEN << "Available"; break;
|
|
case Seat::Status::RESERVED: os << Menu::YELLOW << "Reserved by " << kv.second.reservation_name; break;
|
|
case Seat::Status::BROKEN: os << "Broken"; break;
|
|
}
|
|
os << Menu::RESET << std::endl;
|
|
}
|
|
}
|
|
|
|
// 5. Count bookings by a specific client using std::count_if
|
|
size_t Booker::countBookingsByClient(const std::string& name) const {
|
|
m.lock_shared();
|
|
auto ret = std::count_if(seats.begin(), seats.end(),
|
|
[&](auto& kv){ return kv.second.s == Seat::Status::RESERVED && kv.second.reservation_name == name; }
|
|
);
|
|
m.unlock_shared();
|
|
|
|
return ret;
|
|
}
|
|
|
|
// 6. Replace a client name across all bookings using std::replace_if
|
|
size_t Booker::replaceClientName(const std::string& oldName, const std::string& newName) {
|
|
m.lock();
|
|
size_t cnt = 0;
|
|
std::for_each(seats.begin(), seats.end(),
|
|
[&](auto& kv) {
|
|
if (kv.second.s == Seat::Status::RESERVED && kv.second.reservation_name == oldName) {
|
|
kv.second.reservation_name = newName;
|
|
++cnt;
|
|
}
|
|
}
|
|
);
|
|
m.unlock();
|
|
return cnt;
|
|
}
|
|
|
|
// 7. Copy all VIP clients to a separate list using std::copy_if
|
|
std::vector<std::string> Booker::getVipClients() const {
|
|
m.lock_shared();
|
|
std::vector<std::pair<const seat_num, Booking::Seat>> vip;
|
|
std::vector<std::string> ret;
|
|
std::copy_if(seats.begin(), seats.end(), std::back_inserter(vip),
|
|
[](const auto& kv){ return kv.second.s == Seat::Status::RESERVED && kv.second.t == Seat::Type::VIP; }
|
|
);
|
|
m.unlock_shared();
|
|
|
|
// extract names
|
|
for (const auto& i : vip)
|
|
ret.push_back(i.second.reservation_name);
|
|
return ret;
|
|
}
|
|
}
|