#include <algorithm>
#include <atomic>
#include <cassert>
#include <iostream>
#include <map>
#include <mutex>
#include <vector>
class Container {
public:
Container() {
std::lock_guard<std::mutex> lock(mut);
auto it = uuid.load();
uuid.store(++it);
serial_number_ = it;
container_map.insert({ serial_number_, this });
}
virtual int get_fluid_capacity() = 0;
friend int totalFluidCapacity() {
std::lock_guard<std::mutex> lock(mut);
int result = 0;
for (auto& it : container_map) {
result += it.second->get_fluid_capacity();
}
return result;
}
friend Container* find_container(size_t serial_number) {
std::lock_guard<std::mutex> lock(mut);
if(container_map.find(serial_number) != container_map.end()) {
return container_map[serial_number];
} else {
return nullptr;
}
}
inline static std::mutex mut;
inline static std::atomic<size_t> uuid;
inline static std::map<size_t, Container*> container_map;
protected:
size_t serial_number_;
};
int totalFluidCapacity();
Container* find_container(size_t serial_number);
class Buckets : public Container {
static constexpr double pi = 3.1415926;
public:
Buckets(int height, int radius) : height_(height), radius_(radius) {}
virtual int get_fluid_capacity() override final {
return static_cast<int>(radius_ * radius_ * height_ * pi);
}
private:
int height_;
int radius_;
};
class Boxes : public Container {
public:
enum class material_type : int {
m = 0, /// for metal
c = 1, /// for cardboard
};
Boxes(const int length, const int width, const int height, material_type type)
: length_(length), width_(width), height_(height), type_(type) {}
virtual int get_fluid_capacity() override final {
if (type_ == material_type::c) {
return length_ * width_ * height_;
} else {
return 0;
}
}
private:
int length_;
int width_;
int height_;
material_type type_;
};
int main() {
Boxes box_c(1, 1, 1, Boxes::material_type::c);
Boxes box_m(1, 1, 1, Boxes::material_type::m);
Buckets bucket(1, 1);
auto capa = totalFluidCapacity();
assert(capa == 4);
auto p_container = find_container(2);
assert(p_container == & box_m);
return 0;
}