#include #include #include #include #include #include #include #include namespace { namespace length { template using m = units::si::length; template using mm = units::si::length; } // namespace length namespace acceleration { template using mps2 = units::si::acceleration; template constexpr mps2<> g{static_cast(9.80665)}; } // namespace acceleration namespace force { template using N = units::si::force; } namespace mass { template using kg = units::si::mass; } namespace density { template using kgpm3 = units::si::density; } namespace volume { template using m3 = units::si::volume; } } // namespace struct Box { static constexpr density::kgpm3<> air_density{1.225}; length::m<> length; length::m<> width; length::m<> height; struct contents { density::kgpm3<> density = air_density; } contents; Box(const length::m<>& l, const length::m<>& w, const length::m<>& h) : length{l}, width{w}, height{h} {} force::N<> filled_weight() const { const volume::m3<> volume = length * width * height; const mass::kg<> mass = contents.density * volume; return mass * acceleration::g<>; } length::m<> fill_level(const mass::kg<>& measured_mass) const { return height * (measured_mass * acceleration::g<>) / filled_weight(); } volume::m3<> spare_capacity(const mass::kg<>& measured_mass) const { return (height - fill_level(measured_mass)) * width * length; } void set_contents_density(const density::kgpm3<>& density_in) { assert(density_in > air_density); contents.density = density_in; } }; #include using namespace units::si::literals; int main() { auto box = Box{1000.0mm, 500.0mm, 200.0mm}; box.set_contents_density(1000.0kgpm3); auto fill_time = 200.0s; // time since starting fill auto measured_mass = 20.0kg; // measured mass at fill_time std::cout << "mpusz/units box example...\n"; std::cout << "fill height at " << fill_time << " = " << box.fill_level(measured_mass) << " (" << (box.fill_level(measured_mass) / box.height) * 100 << "% full)\n"; std::cout << "spare_capacity at " << fill_time << " = " << box.spare_capacity(measured_mass) << '\n'; std::cout << "input flow rate after " << fill_time << " = " << measured_mass / fill_time << '\n'; std::cout << "float rise rate = " << box.fill_level(measured_mass) / fill_time << '\n'; auto fill_time_left = (box.height / box.fill_level(measured_mass) - 1) * fill_time; std::cout << "box full E.T.A. at current flow rate = " << fill_time_left << '\n'; }