mirror of
https://github.com/mpusz/mp-units.git
synced 2025-07-29 18:07:16 +02:00
refactor: first examples refactored for V2
This commit is contained in:
@ -1,63 +0,0 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2018 Mateusz Pusz
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
|
||||
#
|
||||
# add_example(target <depependencies>...)
|
||||
#
|
||||
function(add_example target)
|
||||
add_executable(${target}-aliases ${target}.cpp)
|
||||
target_link_libraries(${target}-aliases PRIVATE ${ARGN})
|
||||
target_compile_definitions(${target}-aliases PRIVATE ${projectPrefix}NO_LITERALS ${projectPrefix}NO_REFERENCES)
|
||||
endfunction()
|
||||
|
||||
add_example(avg_speed mp-units::core-io mp-units::si mp-units::si-cgs mp-units::si-international)
|
||||
add_example(box_example mp-units::core-fmt mp-units::si)
|
||||
add_example(capacitor_time_curve mp-units::core-io mp-units::si)
|
||||
add_example(
|
||||
clcpp_response
|
||||
mp-units::core-fmt
|
||||
mp-units::core-io
|
||||
mp-units::si
|
||||
mp-units::si-iau
|
||||
mp-units::si-imperial
|
||||
mp-units::si-international
|
||||
mp-units::si-typographic
|
||||
mp-units::si-uscs
|
||||
)
|
||||
add_example(experimental_angle mp-units::core-fmt mp-units::core-io mp-units::si)
|
||||
add_example(foot_pound_second mp-units::core-fmt mp-units::si-fps)
|
||||
add_example(measurement mp-units::core-io mp-units::si)
|
||||
add_example(total_energy mp-units::core-io mp-units::si mp-units::isq-natural)
|
||||
add_example(unknown_dimension mp-units::core-io mp-units::si)
|
||||
|
||||
if(NOT ${projectPrefix}LIBCXX)
|
||||
add_example(glide_computer_example mp-units::core-fmt mp-units::si-international glide_computer)
|
||||
target_compile_definitions(
|
||||
glide_computer_example-aliases PRIVATE ${projectPrefix}NO_LITERALS ${projectPrefix}NO_REFERENCES
|
||||
)
|
||||
|
||||
find_package(wg21_linear_algebra CONFIG REQUIRED)
|
||||
add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si)
|
||||
target_link_libraries(linear_algebra-aliases PRIVATE wg21_linear_algebra::wg21_linear_algebra)
|
||||
endif()
|
@ -1,192 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/isq/si/cgs/length.h>
|
||||
#include <units/isq/si/cgs/speed.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/international/length.h>
|
||||
#include <units/isq/si/international/speed.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/length.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/speed.h>
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace units::isq;
|
||||
|
||||
constexpr si::speed<si::metre_per_second, int> fixed_int_si_avg_speed(si::length<si::metre, int> d,
|
||||
si::time<si::second, int> t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
|
||||
constexpr si::speed<si::metre_per_second> fixed_double_si_avg_speed(si::length<si::metre> d, si::time<si::second> t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
|
||||
template<typename U1, typename R1, typename U2, typename R2>
|
||||
constexpr Speed auto si_avg_speed(si::length<U1, R1> d, si::time<U2, R2> t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
|
||||
constexpr Speed auto avg_speed(Length auto d, Time auto t) { return d / t; }
|
||||
|
||||
template<Length D, Time T, Speed V>
|
||||
void print_result(D distance, T duration, V speed)
|
||||
{
|
||||
const auto result_in_kmph = units::quantity_cast<si::speed<si::kilometre_per_hour>>(speed);
|
||||
std::cout << "Average speed of a car that makes " << distance << " in " << duration << " is " << result_in_kmph
|
||||
<< ".\n";
|
||||
}
|
||||
|
||||
void example()
|
||||
{
|
||||
// SI (int)
|
||||
{
|
||||
using namespace units::aliases::isq::si;
|
||||
constexpr auto distance = km<int>(220);
|
||||
constexpr auto duration = h<int>(2);
|
||||
|
||||
std::cout << "SI units with 'int' as representation\n";
|
||||
|
||||
print_result(distance, duration, fixed_int_si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
|
||||
// SI (double)
|
||||
{
|
||||
using namespace units::aliases::isq::si;
|
||||
constexpr auto distance = km<double>(220.);
|
||||
constexpr auto duration = h<double>(2.);
|
||||
|
||||
std::cout << "\nSI units with 'double' as representation\n";
|
||||
|
||||
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
|
||||
print_result(distance, duration,
|
||||
fixed_int_si_avg_speed(quantity_cast<int>(distance), quantity_cast<int>(duration)));
|
||||
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
|
||||
// Customary Units (int)
|
||||
{
|
||||
using namespace units::aliases::isq::si::international;
|
||||
using namespace units::aliases::isq::si;
|
||||
constexpr auto distance = mi<int>(140);
|
||||
constexpr auto duration = h<int>(2);
|
||||
|
||||
std::cout << "\nUS Customary Units with 'int' as representation\n";
|
||||
|
||||
// it is not possible to make a lossless conversion of miles to meters on an integral type
|
||||
// (explicit cast needed)
|
||||
print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast<si::metre>(distance), duration));
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
|
||||
// Customary Units (double)
|
||||
{
|
||||
using namespace units::aliases::isq::si::international;
|
||||
using namespace units::aliases::isq::si;
|
||||
constexpr auto distance = mi<double>(140.);
|
||||
constexpr auto duration = h<double>(2.);
|
||||
|
||||
std::cout << "\nUS Customary Units with 'double' as representation\n";
|
||||
|
||||
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
|
||||
// also it is not possible to make a lossless conversion of miles to meters on an integral type
|
||||
// (explicit cast needed)
|
||||
print_result(
|
||||
distance, duration,
|
||||
fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
|
||||
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
|
||||
// CGS (int)
|
||||
{
|
||||
using namespace units::aliases::isq::si::cgs;
|
||||
using namespace units::aliases::isq::si::time;
|
||||
constexpr auto distance = cm<int>(22'000'000);
|
||||
constexpr auto duration = h<int>(2);
|
||||
|
||||
std::cout << "\nCGS units with 'int' as representation\n";
|
||||
|
||||
// it is not possible to make a lossless conversion of centimeters to meters on an integral type
|
||||
// (explicit cast needed)
|
||||
print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast<si::metre>(distance), duration));
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
|
||||
// not possible to convert both a dimension and a unit with implicit cast
|
||||
print_result(distance, duration, si_avg_speed(quantity_cast<si::dim_length>(distance), duration));
|
||||
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
|
||||
// CGS (double)
|
||||
{
|
||||
using namespace units::aliases::isq::si::cgs;
|
||||
using namespace units::aliases::isq::si::time;
|
||||
constexpr auto distance = cm<double>(22'000'000.);
|
||||
constexpr auto duration = h<double>(2.);
|
||||
|
||||
std::cout << "\nCGS units with 'double' as representation\n";
|
||||
|
||||
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
|
||||
// it is not possible to make a lossless conversion of centimeters to meters on an integral type
|
||||
// (explicit cast needed)
|
||||
print_result(
|
||||
distance, duration,
|
||||
fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
|
||||
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
|
||||
// not possible to convert both a dimension and a unit with implicit cast
|
||||
print_result(distance, duration, si_avg_speed(quantity_cast<si::dim_length>(distance), duration));
|
||||
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
example();
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
|
||||
} catch (...) {
|
||||
std::cerr << "Unhandled unknown exception caught\n";
|
||||
}
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/format.h>
|
||||
#include <units/generic/dimensionless.h>
|
||||
#include <units/isq/si/amount_of_substance.h>
|
||||
#include <units/isq/si/area.h>
|
||||
#include <units/isq/si/constants.h>
|
||||
#include <units/isq/si/density.h>
|
||||
#include <units/isq/si/force.h>
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/mass.h>
|
||||
#include <units/isq/si/speed.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/isq/si/volume.h>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace units::aliases::isq::si;
|
||||
|
||||
inline constexpr auto g = units::isq::si::si2019::standard_gravity<>; // NOLINT(readability-identifier-length)
|
||||
inline constexpr auto air_density = kg_per_m3<>(1.225);
|
||||
|
||||
class Box {
|
||||
area::m2<> base_;
|
||||
length::m<> height_;
|
||||
density::kg_per_m3<> density_ = air_density;
|
||||
public:
|
||||
constexpr Box(const length::m<>& length, const length::m<>& width, length::m<> height) :
|
||||
base_(length * width), height_(std::move(height))
|
||||
{
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr force::N<> filled_weight() const
|
||||
{
|
||||
const volume::m3<> volume = base_ * height_;
|
||||
const mass::kg<> mass = density_ * volume;
|
||||
return mass * g;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr length::m<> fill_level(const mass::kg<>& measured_mass) const
|
||||
{
|
||||
return height_ * measured_mass * g / filled_weight();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr volume::m3<> spare_capacity(const mass::kg<>& measured_mass) const
|
||||
{
|
||||
return (height_ - fill_level(measured_mass)) * base_;
|
||||
}
|
||||
|
||||
constexpr void set_contents_density(const density::kg_per_m3<>& density_in)
|
||||
{
|
||||
assert(density_in > air_density);
|
||||
density_ = density_in;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace units;
|
||||
using namespace units::isq;
|
||||
|
||||
const length::m<> height(mm<>(200.0));
|
||||
auto box = Box(mm<>(1000.0), mm<>(500.0), height);
|
||||
box.set_contents_density(kg_per_m3<>(1000.0));
|
||||
|
||||
const auto fill_time = s<>(200.0); // time since starting fill
|
||||
const auto measured_mass = kg<>(20.0); // measured mass at fill_time
|
||||
|
||||
const Length auto fill_level = box.fill_level(measured_mass);
|
||||
const Dimensionless auto fill_percent = quantity_cast<percent>(fill_level / height);
|
||||
const Volume auto spare_capacity = box.spare_capacity(measured_mass);
|
||||
const auto input_flow_rate = measured_mass / fill_time; // unknown dimension
|
||||
const Speed auto float_rise_rate = fill_level / fill_time;
|
||||
const Time auto fill_time_left = (height / fill_level - 1) * fill_time;
|
||||
|
||||
std::cout << "mp-units box example...\n";
|
||||
std::cout << STD_FMT::format("fill height at {} = {} ({} full)\n", fill_time, fill_level, fill_percent);
|
||||
std::cout << STD_FMT::format("spare_capacity at {} = {}\n", fill_time, spare_capacity);
|
||||
std::cout << STD_FMT::format("input flow rate after {} = {}\n", fill_time, input_flow_rate);
|
||||
std::cout << STD_FMT::format("float rise rate = {}\n", float_rise_rate);
|
||||
std::cout << STD_FMT::format("box full E.T.A. at current flow rate = {}\n", fill_time_left);
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2003-2020 Andy Little.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses./
|
||||
*/
|
||||
|
||||
/*
|
||||
capacitor discharge curve using compile_time
|
||||
physical_quantities
|
||||
*/
|
||||
|
||||
#include <units/generic/dimensionless.h>
|
||||
#include <units/isq/si/capacitance.h>
|
||||
#include <units/isq/si/resistance.h>
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/isq/si/voltage.h>
|
||||
#include <units/math.h> // IWYU pragma: keep
|
||||
#include <units/quantity_io.h>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace units::isq;
|
||||
using namespace units::aliases::isq::si;
|
||||
|
||||
std::cout << "mp-units capacitor time curve example...\n";
|
||||
std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
|
||||
std::cout.precision(3);
|
||||
|
||||
constexpr auto C = capacitance::uF<>(0.47);
|
||||
constexpr auto V0 = voltage::V<>(5.0);
|
||||
constexpr auto R = resistance::kR<>(4.7);
|
||||
|
||||
for (auto t = ms<int>(0); t <= ms<int>(50); ++t) {
|
||||
const Voltage auto Vt = V0 * units::exp(-t / (R * C));
|
||||
|
||||
std::cout << "at " << t << " voltage is ";
|
||||
|
||||
if (Vt >= V<>(1))
|
||||
std::cout << Vt;
|
||||
else if (Vt >= mV<>(1))
|
||||
std::cout << mV<>(Vt);
|
||||
else if (Vt >= uV<>(1))
|
||||
std::cout << uV<>(Vt);
|
||||
else if (Vt >= nV<>(1))
|
||||
std::cout << nV<>(Vt);
|
||||
else
|
||||
std::cout << pV<>(Vt);
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
@ -1,151 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2003-2019 Andy Little.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses./
|
||||
*/
|
||||
|
||||
#include <units/format.h>
|
||||
#include <units/isq/si/area.h>
|
||||
#include <units/isq/si/iau/length.h>
|
||||
#include <units/isq/si/imperial/length.h>
|
||||
#include <units/isq/si/international/length.h>
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/isq/si/typographic/length.h>
|
||||
#include <units/isq/si/uscs/length.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace units;
|
||||
|
||||
void simple_quantities()
|
||||
{
|
||||
using namespace units::aliases::isq;
|
||||
using namespace units::aliases::isq::si;
|
||||
using namespace units::aliases::isq::si::international;
|
||||
|
||||
using distance = si::length::m<>;
|
||||
using duration = time::s<>;
|
||||
|
||||
constexpr distance km = si::length::km<>(1.0);
|
||||
constexpr distance miles = mi<>(1.0);
|
||||
|
||||
constexpr duration sec = s<>(1);
|
||||
constexpr duration min = time::min<>(1);
|
||||
constexpr duration hr = h<>(1);
|
||||
|
||||
std::cout << "A physical quantities library can choose the simple\n";
|
||||
std::cout << "option to provide output using a single type for each base unit:\n\n";
|
||||
std::cout << km << '\n';
|
||||
std::cout << miles << '\n';
|
||||
std::cout << sec << '\n';
|
||||
std::cout << min << '\n';
|
||||
std::cout << hr << "\n\n";
|
||||
}
|
||||
|
||||
void quantities_with_typed_units()
|
||||
{
|
||||
using namespace units::aliases::isq;
|
||||
using namespace units::aliases::isq::si;
|
||||
using namespace units::aliases::isq::si::international;
|
||||
|
||||
constexpr si::length::km<> km = si::km<>(1.0);
|
||||
constexpr si::international::length::mi<> miles = mi<>(1.0);
|
||||
|
||||
std::cout.precision(6);
|
||||
|
||||
constexpr time::s<> sec = s<>(1);
|
||||
constexpr time::min<> min = si::min<>(1);
|
||||
constexpr time::h<> hr = h<>(1);
|
||||
|
||||
std::cout << "A more flexible option is to provide separate types for each unit,\n\n";
|
||||
std::cout << km << '\n';
|
||||
std::cout << miles << '\n';
|
||||
std::cout << sec << '\n';
|
||||
std::cout << min << '\n';
|
||||
std::cout << hr << "\n\n";
|
||||
|
||||
constexpr si::length::m<> meter = m<>(1);
|
||||
std::cout << "then a wide range of pre-defined units can be defined and converted,\n"
|
||||
" for consistency and repeatability across applications:\n\n";
|
||||
|
||||
std::cout << meter << '\n';
|
||||
|
||||
std::cout << " = " << au<>(meter) << '\n';
|
||||
std::cout << " = " << iau::angstrom<>(meter) << '\n';
|
||||
std::cout << " = " << imperial::ch<>(meter) << '\n';
|
||||
std::cout << " = " << international::fathom<>(meter) << '\n';
|
||||
std::cout << " = " << uscs::fathom<>(meter) << '\n';
|
||||
std::cout << " = " << international::ft<>(meter) << '\n';
|
||||
std::cout << " = " << uscs::ft<>(meter) << '\n';
|
||||
std::cout << " = " << international::in<>(meter) << '\n';
|
||||
std::cout << " = " << iau::ly<>(meter) << '\n';
|
||||
std::cout << " = " << international::mi<>(meter) << '\n';
|
||||
std::cout << " = " << international::mi_naut<>(meter) << '\n';
|
||||
std::cout << " = " << iau::pc<>(meter) << '\n';
|
||||
std::cout << " = " << typographic::pica_comp<>(meter) << '\n';
|
||||
std::cout << " = " << typographic::pica_prn<>(meter) << '\n';
|
||||
std::cout << " = " << typographic::point_comp<>(meter) << '\n';
|
||||
std::cout << " = " << typographic::point_prn<>(meter) << '\n';
|
||||
std::cout << " = " << imperial::rd<>(meter) << '\n';
|
||||
std::cout << " = " << international::yd<>(meter) << '\n';
|
||||
}
|
||||
|
||||
void calcs_comparison()
|
||||
{
|
||||
using namespace units::aliases::isq::si;
|
||||
|
||||
std::cout << "\nA distinct unit for each type is efficient and accurate\n"
|
||||
"when adding two values of the same very big\n"
|
||||
"or very small type:\n\n";
|
||||
|
||||
length::fm<float> L1A = fm<>(2.f);
|
||||
length::fm<float> L2A = fm<>(3.f);
|
||||
length::fm<float> LrA = L1A + L2A;
|
||||
std::cout << STD_FMT::format("{:%.30Q %q}\n + {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, LrA);
|
||||
|
||||
std::cout << "The single unit method must convert large\n"
|
||||
"or small values in other units to the base unit.\n"
|
||||
"This is both inefficient and inaccurate\n\n";
|
||||
|
||||
length::m<float> L1B = L1A;
|
||||
length::m<float> L2B = L2A;
|
||||
length::m<float> LrB = L1B + L2B;
|
||||
std::cout << STD_FMT::format("{:%.30Q %q}\n + {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1B, L2B, LrB);
|
||||
|
||||
std::cout << "In multiplication and division:\n\n";
|
||||
|
||||
area::fm2<float> ArA = L1A * L2A;
|
||||
std::cout << STD_FMT::format("{:%.30Q %q}\n * {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, ArA);
|
||||
|
||||
std::cout << "similar problems arise\n\n";
|
||||
|
||||
area::m2<float> ArB = L1B * L2B;
|
||||
std::cout << STD_FMT::format("{:%.30Q %q}\n * {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1B, L2B, ArB);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "This demo was originally posted on com.lang.c++.moderated in 2006\n";
|
||||
std::cout << "http://compgroups.net/comp.lang.c++.moderated/dimensional-analysis-units/51712\n";
|
||||
std::cout << "Here converted to use mp-units library.\n\n";
|
||||
|
||||
simple_quantities();
|
||||
quantities_with_typed_units();
|
||||
calcs_comparison();
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/generic/angle.h>
|
||||
#include <units/isq/si/energy.h>
|
||||
#include <units/isq/si/torque.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace units;
|
||||
using namespace units::isq;
|
||||
using namespace units::aliases::isq::si;
|
||||
|
||||
const auto torque = N_m_per_rad<>(20.0 / std::numbers::pi);
|
||||
const auto energy = J<>(20.0);
|
||||
|
||||
Angle auto angle = energy / torque;
|
||||
|
||||
std::cout << angle << '\n';
|
||||
std::cout << quantity_cast<revolution>(angle) << '\n';
|
||||
std::cout << quantity_cast<degree>(angle) << '\n';
|
||||
std::cout << quantity_cast<gradian>(angle) << '\n';
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/format.h>
|
||||
#include <units/isq/si/fps/density.h>
|
||||
#include <units/isq/si/fps/length.h>
|
||||
#include <units/isq/si/fps/mass.h>
|
||||
#include <units/isq/si/fps/power.h>
|
||||
#include <units/isq/si/fps/speed.h>
|
||||
#include <units/isq/si/international/speed.h>
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/mass.h>
|
||||
#include <units/isq/si/power.h>
|
||||
#include <units/isq/si/speed.h>
|
||||
#include <units/isq/si/volume.h>
|
||||
#include <iostream>
|
||||
#include <string_view>
|
||||
|
||||
using namespace units::aliases::isq;
|
||||
|
||||
// Some basic specs for the warship
|
||||
struct Ship {
|
||||
si::fps::length::ft<> length;
|
||||
si::fps::length::ft<> draft;
|
||||
si::fps::length::ft<> beam;
|
||||
|
||||
si::fps::speed::ft_per_s<> speed;
|
||||
si::fps::mass::lb<> mass;
|
||||
|
||||
si::fps::length::in<> mainGuns;
|
||||
si::fps::mass::lb<> shellMass;
|
||||
si::fps::speed::ft_per_s<> shellSpeed;
|
||||
si::fps::power::ft_pdl_per_s<> power;
|
||||
};
|
||||
|
||||
// Print 'a' in its current units and print its value cast to the units in each of Args
|
||||
template<class... Args, units::Quantity Q>
|
||||
auto fmt_line(const Q a)
|
||||
{
|
||||
return STD_FMT::format("{:22}", a) + (STD_FMT::format(",{:20}", units::quantity_cast<Args>(a)) + ...);
|
||||
}
|
||||
|
||||
// Print the ship details in the units as defined in the Ship struct, in other si::imperial units, and in SI
|
||||
void print_details(std::string_view description, const Ship& ship)
|
||||
{
|
||||
const auto waterDensity = si::fps::density::lb_per_ft3<>(62.4);
|
||||
std::cout << STD_FMT::format("{}\n", description);
|
||||
std::cout << STD_FMT::format("{:20} : {}\n", "length", fmt_line<si::fps::length::yd<>, si::length::m<>>(ship.length))
|
||||
<< STD_FMT::format("{:20} : {}\n", "draft", fmt_line<si::fps::length::yd<>, si::length::m<>>(ship.draft))
|
||||
<< STD_FMT::format("{:20} : {}\n", "beam", fmt_line<si::fps::length::yd<>, si::length::m<>>(ship.beam))
|
||||
<< STD_FMT::format("{:20} : {}\n", "mass", fmt_line<si::fps::mass::lton<>, si::mass::t<>>(ship.mass))
|
||||
<< STD_FMT::format("{:20} : {}\n", "speed",
|
||||
fmt_line<si::international::speed::kn<>, si::speed::km_per_h<>>(ship.speed))
|
||||
<< STD_FMT::format("{:20} : {}\n", "power", fmt_line<si::fps::power::hp<>, si::power::kW<>>(ship.power))
|
||||
<< STD_FMT::format("{:20} : {}\n", "main guns",
|
||||
fmt_line<si::fps::length::in<>, si::length::mm<>>(ship.mainGuns))
|
||||
<< STD_FMT::format("{:20} : {}\n", "fire shells weighing",
|
||||
fmt_line<si::fps::mass::lton<>, si::mass::kg<>>(ship.shellMass))
|
||||
<< STD_FMT::format("{:20} : {}\n", "fire shells at",
|
||||
fmt_line<si::fps::speed::mph<>, si::speed::km_per_h<>>(ship.shellSpeed))
|
||||
<< STD_FMT::format("{:20} : {}\n", "volume underwater",
|
||||
fmt_line<si::volume::m3<>, si::volume::l<>>(ship.mass / waterDensity));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace units::aliases::isq::si;
|
||||
using namespace units::aliases::isq::si::fps;
|
||||
using units::aliases::isq::si::fps::length::ft; // to disambiguate from si::femptotonne
|
||||
|
||||
// KMS Bismark, using the units the Germans would use, taken from Wiki
|
||||
auto bismark = Ship{.length{m<>(251.)},
|
||||
.draft{m<>(9.3)},
|
||||
.beam{m<>(36)},
|
||||
.speed{km_per_h<>(56)},
|
||||
.mass{t<>(50'300)},
|
||||
.mainGuns{mm<>(380)},
|
||||
.shellMass{kg<>(800)},
|
||||
.shellSpeed{m_per_s<>(820.)},
|
||||
.power{kW<>(110.45)}};
|
||||
|
||||
// USS Iowa, using units from the foot-pound-second system
|
||||
auto iowa = Ship{.length{ft<>(860.)},
|
||||
.draft{ft<>(37.) + in<>(2.)},
|
||||
.beam{ft<>(108.) + in<>(2.)},
|
||||
.speed{international::kn<>(33)},
|
||||
.mass{lton<>(57'540)},
|
||||
.mainGuns{in<>(16)},
|
||||
.shellMass{lb<>(2700)},
|
||||
.shellSpeed{ft_per_s<>(2690.)},
|
||||
.power{hp<>(212'000)}};
|
||||
|
||||
// HMS King George V, using units from the foot-pound-second system
|
||||
auto kgv = Ship{.length{ft<>(745.1)},
|
||||
.draft{ft<>(33.) + in<>(7.5)},
|
||||
.beam{ft<>(103.2) + in<>(2.5)},
|
||||
.speed{international::kn<>(28.3)},
|
||||
.mass{lton<>(42'245)},
|
||||
.mainGuns{in<>(14)},
|
||||
.shellMass{lb<>(1'590)},
|
||||
.shellSpeed{ft_per_s<>(2483)},
|
||||
.power{hp<>(110'000)}};
|
||||
|
||||
print_details("KMS Bismark, defined in appropriate units from the SI system", bismark);
|
||||
std::cout << "\n\n";
|
||||
print_details("USS Iowa, defined in appropriate units foot-pound-second system", iowa);
|
||||
std::cout << "\n\n";
|
||||
print_details("HMS King George V, defined in appropriate units foot-pound-second system", kgv);
|
||||
}
|
@ -1,201 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include "glide_computer.h"
|
||||
#include <units/bits/fmt_hacks.h>
|
||||
#include <units/chrono.h>
|
||||
#include <units/generic/angle.h>
|
||||
#include <units/generic/dimensionless.h>
|
||||
#include <units/isq/si/international/length.h>
|
||||
#include <array>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace glide_computer;
|
||||
|
||||
using namespace units::isq;
|
||||
|
||||
auto get_gliders()
|
||||
{
|
||||
using namespace units::aliases::isq::si;
|
||||
UNITS_DIAGNOSTIC_PUSH
|
||||
UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES
|
||||
static const std::array gliders = {
|
||||
glider{"SZD-30 Pirat", {velocity(km_per_h<>(83)), rate_of_climb(m_per_s<>(-0.7389))}},
|
||||
glider{"SZD-51 Junior", {velocity(km_per_h<>(80)), rate_of_climb(m_per_s<>(-0.6349))}},
|
||||
glider{"SZD-48 Jantar Std 3", {velocity(km_per_h<>(110)), rate_of_climb(m_per_s<>(-0.77355))}},
|
||||
glider{"SZD-56 Diana", {velocity(km_per_h<>(110)), rate_of_climb(m_per_s<>(-0.63657))}}};
|
||||
UNITS_DIAGNOSTIC_POP
|
||||
return gliders;
|
||||
}
|
||||
|
||||
auto get_weather_conditions()
|
||||
{
|
||||
using namespace units::aliases::isq::si;
|
||||
static const std::array weather_conditions = {
|
||||
std::pair("Good", weather{height(m<>(1900)), rate_of_climb(m_per_s<>(4.3))}),
|
||||
std::pair("Medium", weather{height(m<>(1550)), rate_of_climb(m_per_s<>(2.8))}),
|
||||
std::pair("Bad", weather{height(m<>(850)), rate_of_climb(m_per_s<>(1.8))})};
|
||||
return weather_conditions;
|
||||
}
|
||||
|
||||
auto get_waypoints()
|
||||
{
|
||||
using namespace geographic::literals;
|
||||
using namespace units::aliases::isq::si::international;
|
||||
static const std::array waypoints = {
|
||||
waypoint{"EPPR", {54.24772_N, 18.6745_E}, altitude(ft<>(16))}, // N54°14'51.8" E18°40'28.2"
|
||||
waypoint{"EPGI", {53.52442_N, 18.84947_E}, altitude(ft<>(115))} // N53°31'27.9" E18°50'58.1"
|
||||
};
|
||||
return waypoints;
|
||||
}
|
||||
|
||||
template<std::ranges::input_range R>
|
||||
requires(std::same_as<std::ranges::range_value_t<R>, glider>)
|
||||
void print(const R& gliders)
|
||||
{
|
||||
std::cout << "Gliders:\n";
|
||||
std::cout << "========\n";
|
||||
for (const auto& g : gliders) {
|
||||
std::cout << "- Name: " << g.name << "\n";
|
||||
std::cout << "- Polar:\n";
|
||||
for (const auto& p : g.polar) {
|
||||
const auto ratio = units::quantity_cast<units::one>(glide_ratio(g.polar[0]));
|
||||
std::cout << STD_FMT::format(" * {:%.4Q %q} @ {:%.1Q %q} -> {:%.1Q %q} ({:%.1Q %q})\n", p.climb, p.v, ratio,
|
||||
units::quantity_cast<units::degree>(asin(1 / ratio)));
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
template<std::ranges::input_range R>
|
||||
requires(std::same_as<std::ranges::range_value_t<R>, std::pair<const char*, weather>>)
|
||||
void print(const R& conditions)
|
||||
{
|
||||
std::cout << "Weather:\n";
|
||||
std::cout << "========\n";
|
||||
for (const auto& c : conditions) {
|
||||
std::cout << "- " << c.first << "\n";
|
||||
const auto& w = c.second;
|
||||
std::cout << " * Cloud base: " << STD_FMT::format("{:%.0Q %q}", w.cloud_base) << " AGL\n";
|
||||
std::cout << " * Thermals strength: " << STD_FMT::format("{:%.1Q %q}", w.thermal_strength) << "\n";
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
template<std::ranges::input_range R>
|
||||
requires(std::same_as<std::ranges::range_value_t<R>, waypoint>)
|
||||
void print(const R& waypoints)
|
||||
{
|
||||
std::cout << "Waypoints:\n";
|
||||
std::cout << "==========\n";
|
||||
for (const auto& w : waypoints)
|
||||
std::cout << STD_FMT::format("- {}: {} {}, {:%.1Q %q}\n", w.name, w.pos.lat, w.pos.lon, w.alt);
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void print(const task& t)
|
||||
{
|
||||
std::cout << "Task:\n";
|
||||
std::cout << "=====\n";
|
||||
|
||||
std::cout << "- Start: " << t.get_start().name << "\n";
|
||||
std::cout << "- Finish: " << t.get_finish().name << "\n";
|
||||
std::cout << "- Length: " << STD_FMT::format("{:%.1Q %q}", t.get_length()) << "\n";
|
||||
|
||||
std::cout << "- Legs: "
|
||||
<< "\n";
|
||||
for (const auto& l : t.get_legs())
|
||||
std::cout << STD_FMT::format(" * {} -> {} ({:%.1Q %q})\n", l.begin().name, l.end().name, l.get_length());
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void print(const safety& s)
|
||||
{
|
||||
std::cout << "Safety:\n";
|
||||
std::cout << "=======\n";
|
||||
std::cout << "- Min AGL separation: " << STD_FMT::format("{:%.0Q %q}", s.min_agl_height) << "\n";
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void print(const aircraft_tow& tow)
|
||||
{
|
||||
std::cout << "Tow:\n";
|
||||
std::cout << "====\n";
|
||||
std::cout << "- Type: aircraft\n";
|
||||
std::cout << "- Height: " << STD_FMT::format("{:%.0Q %q}", tow.height_agl) << "\n";
|
||||
std::cout << "- Performance: " << STD_FMT::format("{:%.1Q %q}", tow.performance) << "\n";
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void example()
|
||||
{
|
||||
using namespace units::aliases::isq::si;
|
||||
|
||||
const safety sfty = {height(m<>(300))};
|
||||
const auto gliders = get_gliders();
|
||||
const auto waypoints = get_waypoints();
|
||||
const auto weather_conditions = get_weather_conditions();
|
||||
const task t = {waypoints[0], waypoints[1], waypoints[0]};
|
||||
const aircraft_tow tow = {height(m<>(400)), rate_of_climb(m_per_s<>(1.6))};
|
||||
// TODO use C++20 date library when available
|
||||
// set `start_time` to 11:00 am today
|
||||
const timestamp start_time(std::chrono::system_clock::now());
|
||||
|
||||
print(sfty);
|
||||
print(gliders);
|
||||
print(waypoints);
|
||||
print(weather_conditions);
|
||||
print(t);
|
||||
print(tow);
|
||||
|
||||
for (const auto& g : gliders) {
|
||||
for (const auto& c : weather_conditions) {
|
||||
std::string txt = "Scenario: Glider = " + g.name + ", Weather = " + c.first;
|
||||
std::cout << txt << "\n";
|
||||
std::cout << STD_FMT::format("{0:=^{1}}\n\n", "", txt.size());
|
||||
|
||||
estimate(start_time, g, c.second, t, sfty, tow);
|
||||
|
||||
std::cout << "\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
example();
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
|
||||
} catch (...) {
|
||||
std::cerr << "Unhandled unknown exception caught\n";
|
||||
}
|
||||
}
|
@ -1,362 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/format.h>
|
||||
#include <units/isq/si/energy.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/force.h>
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/speed.h> // IWYU pragma: keep
|
||||
#include <units/quantity_io.h>
|
||||
#include <iostream>
|
||||
#include <linear_algebra.hpp>
|
||||
|
||||
namespace STD_LA {
|
||||
|
||||
template<class ET, class OT>
|
||||
std::ostream& operator<<(std::ostream& os, const vector<ET, OT>& v)
|
||||
{
|
||||
os << "|";
|
||||
for (auto i = 0U; i < v.size(); ++i) {
|
||||
os << STD_FMT::format(" {:>9}", v(i));
|
||||
}
|
||||
os << " |";
|
||||
return os;
|
||||
}
|
||||
|
||||
template<class ET, class OT>
|
||||
std::ostream& operator<<(std::ostream& os, const matrix<ET, OT>& v)
|
||||
{
|
||||
for (auto i = 0U; i < v.rows(); ++i) {
|
||||
os << "|";
|
||||
for (auto j = 0U; j < v.columns(); ++j) {
|
||||
os << STD_FMT::format(" {:>9}", v(i, j));
|
||||
}
|
||||
os << (i != v.rows() - 1U ? " |\n" : " |");
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace STD_LA
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace units::aliases::isq::si;
|
||||
|
||||
template<typename Rep = double>
|
||||
using vector = std::math::fs_vector<Rep, 3>;
|
||||
|
||||
template<typename Rep = double>
|
||||
using matrix = std::math::fs_matrix<Rep, 3, 3>;
|
||||
|
||||
|
||||
void vector_of_quantity_add()
|
||||
{
|
||||
std::cout << "\nvector_of_quantity_add:\n";
|
||||
|
||||
vector<length::m<>> v = {m<>(1), m<>(2), m<>(3)};
|
||||
vector<length::m<>> u = {m<>(3), m<>(2), m<>(1)};
|
||||
vector<length::km<>> t = {km<>(3), km<>(2), km<>(1)};
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
std::cout << "u = " << u << "\n";
|
||||
std::cout << "t = " << t << "\n";
|
||||
|
||||
std::cout << "v + u = " << v + u << "\n";
|
||||
std::cout << "v + t = " << v + t << "\n";
|
||||
std::cout << "t[m] = " << vector<length::m<>>(t) << "\n";
|
||||
}
|
||||
|
||||
void vector_of_quantity_multiply_same()
|
||||
{
|
||||
std::cout << "\nvector_of_quantity_multiply_same:\n";
|
||||
|
||||
vector<length::m<>> v = {m<>(1), m<>(2), m<>(3)};
|
||||
vector<length::m<>> u = {m<>(3), m<>(2), m<>(1)};
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
std::cout << "u = " << u << "\n";
|
||||
|
||||
std::cout << "v * u = " << v * u << "\n";
|
||||
std::cout << "m<>(2) * v = " << m<>(2.) * v << "\n";
|
||||
}
|
||||
|
||||
void vector_of_quantity_multiply_different()
|
||||
{
|
||||
std::cout << "\nvector_of_quantity_multiply_different:\n";
|
||||
|
||||
vector<force::N<>> v = {N<>(1), N<>(2), N<>(3)};
|
||||
vector<length::m<>> u = {m<>(3), m<>(2), m<>(1)};
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
std::cout << "u = " << u << "\n";
|
||||
|
||||
std::cout << "v * u = " << v * u << "\n";
|
||||
std::cout << "N<>(2) * u = " << N<>(2.) * u << "\n";
|
||||
std::cout << "2 * u = " << 2 * u << "\n";
|
||||
}
|
||||
|
||||
void vector_of_quantity_divide_by_scalar()
|
||||
{
|
||||
std::cout << "\nvector_of_quantity_divide_by_scalar:\n";
|
||||
|
||||
vector<length::m<>> v = {m<>(4), m<>(8), m<>(12)};
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
|
||||
// TODO Uncomment when bug in the LA is fixed
|
||||
// std::cout << "v / s<>(2) = " << v / s<>(2) << "\n";
|
||||
// std::cout << "v / 2 = " << v / 2 << "\n";
|
||||
}
|
||||
|
||||
void vector_of_quantity_tests()
|
||||
{
|
||||
vector_of_quantity_add();
|
||||
vector_of_quantity_multiply_same();
|
||||
vector_of_quantity_multiply_different();
|
||||
vector_of_quantity_divide_by_scalar();
|
||||
}
|
||||
|
||||
void matrix_of_quantity_add()
|
||||
{
|
||||
std::cout << "\nmatrix_of_quantity_add:\n";
|
||||
|
||||
matrix<length::m<>> v = {{m<>(1), m<>(2), m<>(3)}, {m<>(4), m<>(5), m<>(6)}, {m<>(7), m<>(8), m<>(9)}};
|
||||
matrix<length::m<>> u = {{m<>(3), m<>(2), m<>(1)}, {m<>(3), m<>(2), m<>(1)}, {m<>(3), m<>(2), m<>(1)}};
|
||||
matrix<length::mm<>> t = {{mm<>(3), mm<>(2), mm<>(1)}, {mm<>(3), mm<>(2), mm<>(1)}, {mm<>(3), mm<>(2), mm<>(1)}};
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
std::cout << "u =\n" << u << "\n";
|
||||
std::cout << "t =\n" << t << "\n";
|
||||
|
||||
std::cout << "v + u =\n" << v + u << "\n";
|
||||
std::cout << "v + t =\n" << v + t << "\n";
|
||||
|
||||
// TODO Uncomment when fixed in the LA lib
|
||||
// std::cout << "v[mm] =\n" << matrix<length::mm<>>(v) << "\n";
|
||||
}
|
||||
|
||||
void matrix_of_quantity_multiply_same()
|
||||
{
|
||||
std::cout << "\nmatrix_of_quantity_multiply_same:\n";
|
||||
|
||||
matrix<length::m<>> v = {{m<>(1), m<>(2), m<>(3)}, {m<>(4), m<>(5), m<>(6)}, {m<>(7), m<>(8), m<>(9)}};
|
||||
vector<length::m<>> u = {m<>(3), m<>(2), m<>(1)};
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
std::cout << "u =\n" << u << "\n";
|
||||
|
||||
std::cout << "v * u =\n" << v * u << "\n";
|
||||
std::cout << "m<>(2) * u =\n" << m<>(2.) * u << "\n";
|
||||
}
|
||||
|
||||
void matrix_of_quantity_multiply_different()
|
||||
{
|
||||
std::cout << "\nmatrix_of_quantity_multiply_different:\n";
|
||||
|
||||
vector<force::N<>> v = {N<>(1), N<>(2), N<>(3)};
|
||||
matrix<length::m<>> u = {{m<>(1), m<>(2), m<>(3)}, {m<>(4), m<>(5), m<>(6)}, {m<>(7), m<>(8), m<>(9)}};
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
std::cout << "u =\n" << u << "\n";
|
||||
|
||||
std::cout << "v * u =\n" << v * u << "\n";
|
||||
std::cout << "N<>(2) * u =\n" << N<>(2.) * u << "\n";
|
||||
std::cout << "2 * u =\n" << 2 * u << "\n";
|
||||
}
|
||||
|
||||
void matrix_of_quantity_divide_by_scalar()
|
||||
{
|
||||
std::cout << "\nmatrix_of_quantity_divide_by_scalar:\n";
|
||||
|
||||
matrix<length::m<>> v = {{m<>(2), m<>(4), m<>(6)}, {m<>(4), m<>(6), m<>(8)}, {m<>(8), m<>(4), m<>(2)}};
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
|
||||
// TODO Uncomment when bug in the LA is fixed
|
||||
// std::cout << "v / s<>(2) =\n" << v / s<>(2) << "\n";
|
||||
// std::cout << "v / 2 =\n" << v / 2 << "\n";
|
||||
}
|
||||
|
||||
void matrix_of_quantity_tests()
|
||||
{
|
||||
matrix_of_quantity_add();
|
||||
matrix_of_quantity_multiply_same();
|
||||
matrix_of_quantity_multiply_different();
|
||||
matrix_of_quantity_divide_by_scalar();
|
||||
}
|
||||
|
||||
using namespace units::isq;
|
||||
|
||||
template<units::Unit U = si::metre, units::Representation Rep = double>
|
||||
using length_v = si::length<U, vector<Rep>>;
|
||||
|
||||
template<units::Unit U = si::newton, units::Representation Rep = double>
|
||||
using force_v = si::force<U, vector<Rep>>;
|
||||
|
||||
void quantity_of_vector_add()
|
||||
{
|
||||
std::cout << "\nquantity_of_vector_add:\n";
|
||||
|
||||
length_v<> v(vector<>{1, 2, 3});
|
||||
length_v<> u(vector<>{3, 2, 1});
|
||||
length_v<si::kilometre> t(vector<>{3, 2, 1});
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
std::cout << "u = " << u << "\n";
|
||||
std::cout << "t = " << t << "\n";
|
||||
|
||||
std::cout << "v + u = " << v + u << "\n";
|
||||
std::cout << "v + t = " << v + t << "\n";
|
||||
std::cout << "t[m] = " << quantity_cast<si::metre>(t) << "\n";
|
||||
}
|
||||
|
||||
void quantity_of_vector_multiply_same()
|
||||
{
|
||||
std::cout << "\nquantity_of_vector_multiply_same:\n";
|
||||
|
||||
length_v<> v(vector<>{1, 2, 3});
|
||||
length_v<> u(vector<>{3, 2, 1});
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
std::cout << "u = " << u << "\n";
|
||||
|
||||
std::cout << "v * u = " << v * u << "\n";
|
||||
std::cout << "m<>(2) * v = " << m<>(2.) * v << "\n";
|
||||
}
|
||||
|
||||
void quantity_of_vector_multiply_different()
|
||||
{
|
||||
std::cout << "\nquantity_of_vector_multiply_different:\n";
|
||||
|
||||
force_v<> v(vector<>{1, 2, 3});
|
||||
length_v<> u(vector<>{3, 2, 1});
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
std::cout << "u = " << u << "\n";
|
||||
|
||||
std::cout << "v * u = " << v * u << "\n";
|
||||
std::cout << "N<>(2) * u = " << N<>(2.) * u << "\n";
|
||||
std::cout << "2 * u = " << 2 * u << "\n";
|
||||
}
|
||||
|
||||
void quantity_of_vector_divide_by_scalar()
|
||||
{
|
||||
std::cout << "\nquantity_of_vector_divide_by_scalar:\n";
|
||||
|
||||
length_v<> v(vector<>{4, 8, 12});
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
|
||||
// TODO Uncomment when bug in the LA is fixed
|
||||
// std::cout << "v / s<>(2) = " << v / s<>(2) << "\n";
|
||||
// std::cout << "v / 2 = " << v / 2 << "\n";
|
||||
}
|
||||
|
||||
void quantity_of_vector_tests()
|
||||
{
|
||||
quantity_of_vector_add();
|
||||
quantity_of_vector_multiply_same();
|
||||
quantity_of_vector_multiply_different();
|
||||
quantity_of_vector_divide_by_scalar();
|
||||
}
|
||||
|
||||
template<units::Unit U = si::metre, units::Representation Rep = double>
|
||||
using length_m = si::length<U, matrix<Rep>>;
|
||||
|
||||
void quantity_of_matrix_add()
|
||||
{
|
||||
std::cout << "\nquantity_of_matrix_add:\n";
|
||||
|
||||
length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
|
||||
length_m<> u(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}});
|
||||
length_m<si::kilometre> t(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}});
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
std::cout << "u =\n" << u << "\n";
|
||||
std::cout << "t =\n" << t << "\n";
|
||||
|
||||
std::cout << "v + u =\n" << v + u << "\n";
|
||||
std::cout << "v + t =\n" << v + t << "\n";
|
||||
|
||||
// TODO Uncomment when fixed in the LA lib
|
||||
// std::cout << "v[mm] =\n" << matrix<length::mm<>>(v) << "\n";
|
||||
}
|
||||
|
||||
void quantity_of_matrix_multiply_same()
|
||||
{
|
||||
std::cout << "\nquantity_of_matrix_multiply_same:\n";
|
||||
|
||||
length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
|
||||
length_v<> u(vector<>{3, 2, 1});
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
std::cout << "u =\n" << u << "\n";
|
||||
|
||||
std::cout << "v * u =\n" << v * u << "\n";
|
||||
std::cout << "m<>(2) * u =\n" << m<>(2.) * u << "\n";
|
||||
}
|
||||
|
||||
void quantity_of_matrix_multiply_different()
|
||||
{
|
||||
std::cout << "\nquantity_of_matrix_multiply_different:\n";
|
||||
|
||||
force_v<> v(vector<>{1, 2, 3});
|
||||
length_m<> u(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
std::cout << "u =\n" << u << "\n";
|
||||
|
||||
std::cout << "v * u =\n" << v * u << "\n";
|
||||
std::cout << "N<>(2) * u =\n" << N<>(2.) * u << "\n";
|
||||
std::cout << "2 * u =\n" << 2 * u << "\n";
|
||||
}
|
||||
|
||||
void quantity_of_matrix_divide_by_scalar()
|
||||
{
|
||||
std::cout << "\nquantity_of_matrix_divide_by_scalar:\n";
|
||||
|
||||
length_m<> v(matrix<>{{2, 4, 6}, {4, 6, 8}, {8, 4, 2}});
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
|
||||
// TODO Uncomment when bug in the LA is fixed
|
||||
// std::cout << "v / s<>(2) =\n" << v / s<>(2) << "\n";
|
||||
// std::cout << "v / 2 =\n" << v / 2 << "\n";
|
||||
}
|
||||
|
||||
void quantity_of_matrix_tests()
|
||||
{
|
||||
quantity_of_matrix_add();
|
||||
quantity_of_matrix_multiply_same();
|
||||
quantity_of_matrix_multiply_different();
|
||||
quantity_of_matrix_divide_by_scalar();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
vector_of_quantity_tests();
|
||||
matrix_of_quantity_tests();
|
||||
quantity_of_vector_tests();
|
||||
quantity_of_matrix_tests();
|
||||
}
|
@ -1,156 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/isq/si/acceleration.h>
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/speed.h>
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <cmath>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
template<class T>
|
||||
class measurement {
|
||||
public:
|
||||
using value_type = T;
|
||||
|
||||
measurement() = default;
|
||||
|
||||
constexpr explicit measurement(const value_type& val, const value_type& err = {}) : value_(val)
|
||||
{
|
||||
// it sucks that using declaration cannot be provided for a constructor initializer list
|
||||
using namespace std;
|
||||
uncertainty_ = abs(err);
|
||||
}
|
||||
|
||||
constexpr const value_type& value() const { return value_; }
|
||||
constexpr const value_type& uncertainty() const { return uncertainty_; }
|
||||
|
||||
constexpr value_type relative_uncertainty() const { return uncertainty() / value(); }
|
||||
constexpr value_type lower_bound() const { return value() - uncertainty(); }
|
||||
constexpr value_type upper_bound() const { return value() + uncertainty(); }
|
||||
|
||||
[[nodiscard]] constexpr measurement operator-() const { return measurement(-value(), uncertainty()); }
|
||||
|
||||
[[nodiscard]] friend constexpr measurement operator+(const measurement& lhs, const measurement& rhs)
|
||||
{
|
||||
using namespace std;
|
||||
return measurement(lhs.value() + rhs.value(), hypot(lhs.uncertainty(), rhs.uncertainty()));
|
||||
}
|
||||
|
||||
[[nodiscard]] friend constexpr measurement operator-(const measurement& lhs, const measurement& rhs)
|
||||
{
|
||||
using namespace std;
|
||||
return measurement(lhs.value() - rhs.value(), hypot(lhs.uncertainty(), rhs.uncertainty()));
|
||||
}
|
||||
|
||||
[[nodiscard]] friend constexpr measurement operator*(const measurement& lhs, const measurement& rhs)
|
||||
{
|
||||
const auto val = lhs.value() * rhs.value();
|
||||
using namespace std;
|
||||
return measurement(val, val * hypot(lhs.relative_uncertainty(), rhs.relative_uncertainty()));
|
||||
}
|
||||
|
||||
[[nodiscard]] friend constexpr measurement operator*(const measurement& lhs, const value_type& value)
|
||||
{
|
||||
const auto val = lhs.value() * value;
|
||||
return measurement(val, val * lhs.relative_uncertainty());
|
||||
}
|
||||
|
||||
[[nodiscard]] friend constexpr measurement operator*(const value_type& value, const measurement& rhs)
|
||||
{
|
||||
const auto val = rhs.value() * value;
|
||||
return measurement(val, val * rhs.relative_uncertainty());
|
||||
}
|
||||
|
||||
[[nodiscard]] friend constexpr measurement operator/(const measurement& lhs, const measurement& rhs)
|
||||
{
|
||||
const auto val = lhs.value() / rhs.value();
|
||||
using namespace std;
|
||||
return measurement(val, val * hypot(lhs.relative_uncertainty(), rhs.relative_uncertainty()));
|
||||
}
|
||||
|
||||
[[nodiscard]] friend constexpr measurement operator/(const measurement& lhs, const value_type& value)
|
||||
{
|
||||
const auto val = lhs.value() / value;
|
||||
return measurement(val, val * lhs.relative_uncertainty());
|
||||
}
|
||||
|
||||
[[nodiscard]] friend constexpr measurement operator/(const value_type& value, const measurement& rhs)
|
||||
{
|
||||
const auto val = value / rhs.value();
|
||||
return measurement(val, val * rhs.relative_uncertainty());
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto operator<=>(const measurement&) const = default;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const measurement& v)
|
||||
{
|
||||
return os << v.value() << " ± " << v.uncertainty();
|
||||
}
|
||||
|
||||
private:
|
||||
value_type value_{};
|
||||
value_type uncertainty_{};
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
static_assert(units::Representation<measurement<double>>);
|
||||
|
||||
void example()
|
||||
{
|
||||
using namespace units::isq;
|
||||
using namespace units::aliases::isq::si;
|
||||
|
||||
const auto a = acceleration::m_per_s2<measurement<double>>(measurement(9.8, 0.1));
|
||||
const auto t = time::s<measurement<double>>(measurement(1.2, 0.1));
|
||||
|
||||
const Speed auto v1 = a * t;
|
||||
#if UNITS_DOWNCAST_MODE == 0
|
||||
std::cout << a << " * " << t << " = " << v1 << " = " << km_per_h<measurement<double>>(v1) << '\n';
|
||||
#else
|
||||
std::cout << a << " * " << t << " = " << v1 << " = " << km_per_h<measurement<double>>(v1) << '\n';
|
||||
#endif
|
||||
|
||||
length::m<measurement<double>> length(measurement(123., 1.));
|
||||
std::cout << "10 * " << length << " = " << 10 * length << '\n';
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
example();
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
|
||||
} catch (...) {
|
||||
std::cerr << "Unhandled unknown exception caught\n";
|
||||
}
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/isq/natural/natural.h>
|
||||
#include <units/isq/si/constants.h>
|
||||
#include <units/isq/si/energy.h>
|
||||
#include <units/isq/si/mass.h>
|
||||
#include <units/isq/si/momentum.h>
|
||||
#include <units/isq/si/speed.h> // IWYU pragma: keep
|
||||
#include <units/math.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace units::isq;
|
||||
|
||||
Energy auto total_energy(Momentum auto p, Mass auto m, Speed auto c)
|
||||
{
|
||||
return sqrt(pow<2>(p * c) + pow<2>(m * pow<2>(c)));
|
||||
}
|
||||
|
||||
void si_example()
|
||||
{
|
||||
using namespace units::aliases::isq::si;
|
||||
|
||||
constexpr Speed auto c = units::isq::si::si2019::speed_of_light<>;
|
||||
|
||||
std::cout << "\n*** SI units (c = " << c << ") ***\n";
|
||||
|
||||
const Momentum auto p = GeV<>(4.) / c;
|
||||
const Mass auto m = GeV<>(3.) / pow<2>(c);
|
||||
const Energy auto E = total_energy(p, m, c);
|
||||
|
||||
std::cout << "[in GeV]\n"
|
||||
<< "p = " << p << "\n"
|
||||
<< "m = " << m << "\n"
|
||||
<< "E = " << E << "\n";
|
||||
|
||||
const momentum::kg_m_per_s<> p_si = p;
|
||||
const mass::kg<> m_si = m;
|
||||
const energy::J<> E_si = total_energy(p_si, m_si, c);
|
||||
|
||||
std::cout << "\n[in SI units]\n"
|
||||
<< "p = " << p_si << "\n"
|
||||
<< "m = " << m_si << "\n"
|
||||
<< "E = " << E_si << "\n";
|
||||
|
||||
std::cout << "\n[converted from SI units back to GeV]\n"
|
||||
<< "E = " << GeV<>(E_si) << "\n";
|
||||
}
|
||||
|
||||
void natural_example()
|
||||
{
|
||||
using namespace units::aliases::isq::natural;
|
||||
|
||||
constexpr Speed auto c = units::isq::natural::speed_of_light<>;
|
||||
const momentum::GeV<> p(4);
|
||||
const mass::GeV<> m(3);
|
||||
const Energy auto E = total_energy(p, m, c);
|
||||
|
||||
std::cout << "\n*** Natural units (c = " << c << ") ***\n"
|
||||
<< "p = " << p << "\n"
|
||||
<< "m = " << m << "\n"
|
||||
<< "E = " << E << "\n";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
si_example();
|
||||
natural_example();
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
|
||||
} catch (...) {
|
||||
std::cerr << "Unhandled unknown exception caught\n";
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/speed.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
template<units::isq::Length D, units::isq::Time T>
|
||||
constexpr units::isq::Speed auto avg_speed(D d, T t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
|
||||
void example()
|
||||
{
|
||||
using namespace units::isq;
|
||||
using namespace units::aliases::isq::si;
|
||||
|
||||
Length auto d1 = m<>(123);
|
||||
Time auto t1 = s<>(10);
|
||||
Speed auto v1 = avg_speed(d1, t1);
|
||||
|
||||
auto temp1 =
|
||||
v1 * m<>(50); // produces intermediate unknown dimension with 'unknown_coherent_unit' as its 'coherent_unit'
|
||||
Speed auto v2 = temp1 / m<>(100); // back to known dimensions again
|
||||
Length auto d2 = v2 * s<>(60);
|
||||
|
||||
std::cout << "d1 = " << d1 << '\n';
|
||||
std::cout << "t1 = " << t1 << '\n';
|
||||
std::cout << "v1 = " << v1 << '\n';
|
||||
std::cout << "temp1 = " << temp1 << '\n';
|
||||
std::cout << "v2 = " << v2 << '\n';
|
||||
std::cout << "d2 = " << d2 << '\n';
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
example();
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
|
||||
} catch (...) {
|
||||
std::cerr << "Unhandled unknown exception caught\n";
|
||||
}
|
||||
}
|
108
example/box_example.cpp
Normal file
108
example/box_example.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/format.h>
|
||||
#include <units/generic/dimensionless.h>
|
||||
#include <units/isq/mechanics.h>
|
||||
#include <units/isq/space_and_time.h>
|
||||
#include <units/si/constants.h>
|
||||
#include <units/si/unit_symbols.h>
|
||||
#include <units/si/units.h>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace units;
|
||||
using namespace units::si;
|
||||
using namespace units::si::unit_symbols;
|
||||
|
||||
inline constexpr auto g = 1 * standard_gravity;
|
||||
inline constexpr auto air_density = 1.225 * isq::mass_density[kg / m3];
|
||||
|
||||
class Box {
|
||||
quantity<isq::area[m2]> base_;
|
||||
quantity<isq::length[m]> height_;
|
||||
quantity<isq::mass_density[kg / m3]> density_ = air_density;
|
||||
public:
|
||||
constexpr Box(const quantity<isq::length[m]>& length, const quantity<isq::length[m]>& width,
|
||||
quantity<isq::length[m]> height) :
|
||||
base_(length * width), height_(std::move(height))
|
||||
{
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto filled_weight() const
|
||||
{
|
||||
const weak_quantity_of<isq::volume> auto volume = base_ * height_;
|
||||
const quantity_of<isq::mass> auto mass = density_ * volume;
|
||||
return mass * g;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr quantity<isq::length[m]> fill_level(const quantity<isq::mass[kg]>& measured_mass) const
|
||||
{
|
||||
return height_ * measured_mass * g / filled_weight();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr quantity<isq::volume[m3]> spare_capacity(const quantity<isq::mass[kg]>& measured_mass) const
|
||||
{
|
||||
return (height_ - fill_level(measured_mass)) * base_;
|
||||
}
|
||||
|
||||
constexpr void set_contents_density(const quantity<isq::mass_density[kg / m3]>& density_in)
|
||||
{
|
||||
assert(density_in > air_density);
|
||||
density_ = density_in;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
const auto mm = isq::length[unit_symbols::mm]; // helper reference value
|
||||
|
||||
const auto height = (200.0 * mm)[metre];
|
||||
auto box = Box(1000.0 * mm, 500.0 * mm, height);
|
||||
box.set_contents_density(1000.0 * isq::mass_density[kg / m3]);
|
||||
|
||||
const auto fill_time = 200.0 * isq::time[s]; // time since starting fill
|
||||
const auto measured_mass = 20.0 * isq::mass[kg]; // measured mass at fill_time
|
||||
const auto fill_level = box.fill_level(measured_mass);
|
||||
const auto spare_capacity = box.spare_capacity(measured_mass);
|
||||
const auto filled_weight = box.filled_weight();
|
||||
|
||||
const weak_quantity_of<isq::mass_change_rate> auto input_flow_rate = measured_mass / fill_time;
|
||||
const weak_quantity_of<isq::speed> auto float_rise_rate = fill_level / fill_time;
|
||||
const quantity_of<isq::time> auto fill_time_left = (height / fill_level - 1) * fill_time;
|
||||
|
||||
const auto fill_percent = (fill_level / height)[percent];
|
||||
|
||||
std::cout << "mp-units box example...\n";
|
||||
std::cout << STD_FMT::format("fill height at {} = {} ({} full)\n", fill_time, fill_level, fill_percent);
|
||||
std::cout << STD_FMT::format("fill weight at {} = {} ({})\n", fill_time, filled_weight, filled_weight[N]);
|
||||
std::cout << STD_FMT::format("spare capacity at {} = {}\n", fill_time, spare_capacity);
|
||||
std::cout << STD_FMT::format("input flow rate after {} = {}\n", fill_time, input_flow_rate);
|
||||
std::cout << STD_FMT::format("float rise rate = {}\n", float_rise_rate);
|
||||
std::cout << STD_FMT::format("box full E.T.A. at current flow rate = {}\n", fill_time_left);
|
||||
}
|
@ -16,7 +16,8 @@
|
||||
*/
|
||||
|
||||
#include <units/format.h>
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/space_and_time.h>
|
||||
#include <units/si/units.h>
|
||||
#include <iostream>
|
||||
#include <type_traits>
|
||||
|
||||
@ -28,26 +29,22 @@
|
||||
namespace {
|
||||
|
||||
template<units::Quantity Target, units::Quantity Source>
|
||||
requires units::equivalent<typename Source::dimension, typename Target::dimension>
|
||||
inline constexpr std::common_type_t<typename Target::rep, typename Source::rep> conversion_factor(Target, Source)
|
||||
requires std::constructible_from<Target, Source>
|
||||
inline constexpr double conversion_factor(Target, Source)
|
||||
{
|
||||
// get quantities looking like inputs but with Q::rep that doesn't have narrowing conversion
|
||||
typedef std::common_type_t<typename Target::rep, typename Source::rep> rep;
|
||||
typedef units::quantity<typename Source::dimension, typename Source::unit, rep> source;
|
||||
typedef units::quantity<typename Target::dimension, typename Target::unit, rep> target;
|
||||
return target{source{1}}.number();
|
||||
return quantity_cast<Target::unit>(1. * Source::reference).number();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace units::isq::si;
|
||||
using namespace units;
|
||||
|
||||
std::cout << "conversion factor in mp-units...\n\n";
|
||||
|
||||
constexpr length<metre> lengthA(2.0);
|
||||
constexpr length<millimetre> lengthB = lengthA;
|
||||
constexpr auto lengthA = 2.0 * isq::length[si::metre];
|
||||
constexpr auto lengthB = lengthA[si::milli<si::metre>];
|
||||
|
||||
std::cout << STD_FMT::format("lengthA( {} ) and lengthB( {} )\n", lengthA, lengthB)
|
||||
<< "represent the same length in different units.\n\n";
|
||||
|
@ -20,14 +20,14 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/format.h>
|
||||
#include <units/isq/si/energy.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/force.h>
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/speed.h> // IWYU pragma: keep
|
||||
#include <units/quantity_io.h>
|
||||
#include <iostream>
|
||||
#include <linear_algebra.hpp>
|
||||
// linear_algebra.hpp has to be included first otherwise the header will fail to compile!
|
||||
#include <units/format.h>
|
||||
#include <units/isq/mechanics.h>
|
||||
#include <units/isq/space_and_time.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <units/si/units.h>
|
||||
#include <iostream>
|
||||
|
||||
namespace STD_LA {
|
||||
|
||||
@ -59,9 +59,7 @@ std::ostream& operator<<(std::ostream& os, const matrix<ET, OT>& v)
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace units::isq;
|
||||
using namespace units::isq::si::length_references;
|
||||
using namespace units::isq::si::force_references;
|
||||
using namespace units;
|
||||
|
||||
template<typename Rep = double>
|
||||
using vector = std::math::fs_vector<Rep, 3>;
|
||||
@ -69,13 +67,18 @@ using vector = std::math::fs_vector<Rep, 3>;
|
||||
template<typename Rep = double>
|
||||
using matrix = std::math::fs_matrix<Rep, 3, 3>;
|
||||
|
||||
constexpr auto mm = isq::length[si::milli<si::metre>];
|
||||
constexpr auto m = isq::length[si::metre];
|
||||
constexpr auto km = isq::length[si::kilo<si::metre>];
|
||||
constexpr auto N = isq::force[si::newton];
|
||||
|
||||
void vector_of_quantity_add()
|
||||
{
|
||||
std::cout << "\nvector_of_quantity_add:\n";
|
||||
|
||||
vector<si::length<si::metre>> v = {1 * m, 2 * m, 3 * m};
|
||||
vector<si::length<si::metre>> u = {3 * m, 2 * m, 1 * m};
|
||||
vector<si::length<si::kilometre>> t = {3 * km, 2 * km, 1 * km};
|
||||
vector<quantity<m>> v = {1 * m, 2 * m, 3 * m};
|
||||
vector<quantity<m>> u = {3 * m, 2 * m, 1 * m};
|
||||
vector<quantity<km>> t = {3 * km, 2 * km, 1 * km};
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
std::cout << "u = " << u << "\n";
|
||||
@ -83,15 +86,15 @@ void vector_of_quantity_add()
|
||||
|
||||
std::cout << "v + u = " << v + u << "\n";
|
||||
std::cout << "v + t = " << v + t << "\n";
|
||||
std::cout << "t[m] = " << vector<si::length<si::metre>>(t) << "\n";
|
||||
std::cout << "t[m] = " << vector<quantity<m>>(t) << "\n";
|
||||
}
|
||||
|
||||
void vector_of_quantity_multiply_same()
|
||||
{
|
||||
std::cout << "\nvector_of_quantity_multiply_same:\n";
|
||||
|
||||
vector<si::length<si::metre>> v = {1 * m, 2 * m, 3 * m};
|
||||
vector<si::length<si::metre>> u = {3 * m, 2 * m, 1 * m};
|
||||
vector<quantity<m>> v = {1 * m, 2 * m, 3 * m};
|
||||
vector<quantity<m>> u = {3 * m, 2 * m, 1 * m};
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
std::cout << "u = " << u << "\n";
|
||||
@ -104,8 +107,8 @@ void vector_of_quantity_multiply_different()
|
||||
{
|
||||
std::cout << "\nvector_of_quantity_multiply_different:\n";
|
||||
|
||||
vector<si::force<si::newton>> v = {1 * N, 2 * N, 3 * N};
|
||||
vector<si::length<si::metre>> u = {3 * m, 2 * m, 1 * m};
|
||||
vector<quantity<N>> v = {1 * N, 2 * N, 3 * N};
|
||||
vector<quantity<m>> u = {3 * m, 2 * m, 1 * m};
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
std::cout << "u = " << u << "\n";
|
||||
@ -119,7 +122,7 @@ void vector_of_quantity_divide_by_scalar()
|
||||
{
|
||||
std::cout << "\nvector_of_quantity_divide_by_scalar:\n";
|
||||
|
||||
vector<si::length<si::metre>> v = {4 * m, 8 * m, 12 * m};
|
||||
vector<quantity<m>> v = {4 * m, 8 * m, 12 * m};
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
|
||||
@ -140,9 +143,9 @@ void matrix_of_quantity_add()
|
||||
{
|
||||
std::cout << "\nmatrix_of_quantity_add:\n";
|
||||
|
||||
matrix<si::length<si::metre>> v = {{1 * m, 2 * m, 3 * m}, {4 * m, 5 * m, 6 * m}, {7 * m, 8 * m, 9 * m}};
|
||||
matrix<si::length<si::metre>> u = {{3 * m, 2 * m, 1 * m}, {3 * m, 2 * m, 1 * m}, {3 * m, 2 * m, 1 * m}};
|
||||
matrix<si::length<si::millimetre>> t = {{3 * mm, 2 * mm, 1 * mm}, {3 * mm, 2 * mm, 1 * mm}, {3 * mm, 2 * mm, 1 * mm}};
|
||||
matrix<quantity<m>> v = {{1 * m, 2 * m, 3 * m}, {4 * m, 5 * m, 6 * m}, {7 * m, 8 * m, 9 * m}};
|
||||
matrix<quantity<m>> u = {{3 * m, 2 * m, 1 * m}, {3 * m, 2 * m, 1 * m}, {3 * m, 2 * m, 1 * m}};
|
||||
matrix<quantity<mm>> t = {{3 * mm, 2 * mm, 1 * mm}, {3 * mm, 2 * mm, 1 * mm}, {3 * mm, 2 * mm, 1 * mm}};
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
std::cout << "u =\n" << u << "\n";
|
||||
@ -159,8 +162,8 @@ void matrix_of_quantity_multiply_same()
|
||||
{
|
||||
std::cout << "\nmatrix_of_quantity_multiply_same:\n";
|
||||
|
||||
matrix<si::length<si::metre>> v = {{1 * m, 2 * m, 3 * m}, {4 * m, 5 * m, 6 * m}, {7 * m, 8 * m, 9 * m}};
|
||||
vector<si::length<si::metre>> u = {3 * m, 2 * m, 1 * m};
|
||||
matrix<quantity<m>> v = {{1 * m, 2 * m, 3 * m}, {4 * m, 5 * m, 6 * m}, {7 * m, 8 * m, 9 * m}};
|
||||
vector<quantity<m>> u = {3 * m, 2 * m, 1 * m};
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
std::cout << "u =\n" << u << "\n";
|
||||
@ -173,8 +176,8 @@ void matrix_of_quantity_multiply_different()
|
||||
{
|
||||
std::cout << "\nmatrix_of_quantity_multiply_different:\n";
|
||||
|
||||
vector<si::force<si::newton>> v = {1 * N, 2 * N, 3 * N};
|
||||
matrix<si::length<si::metre>> u = {{1 * m, 2 * m, 3 * m}, {4 * m, 5 * m, 6 * m}, {7 * m, 8 * m, 9 * m}};
|
||||
vector<quantity<N>> v = {1 * N, 2 * N, 3 * N};
|
||||
matrix<quantity<m>> u = {{1 * m, 2 * m, 3 * m}, {4 * m, 5 * m, 6 * m}, {7 * m, 8 * m, 9 * m}};
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
std::cout << "u =\n" << u << "\n";
|
||||
@ -188,7 +191,7 @@ void matrix_of_quantity_divide_by_scalar()
|
||||
{
|
||||
std::cout << "\nmatrix_of_quantity_divide_by_scalar:\n";
|
||||
|
||||
matrix<si::length<si::metre>> v = {{2 * m, 4 * m, 6 * m}, {4 * m, 6 * m, 8 * m}, {8 * m, 4 * m, 2 * m}};
|
||||
matrix<quantity<m>> v = {{2 * m, 4 * m, 6 * m}, {4 * m, 6 * m, 8 * m}, {8 * m, 4 * m, 2 * m}};
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
|
||||
@ -205,11 +208,11 @@ void matrix_of_quantity_tests()
|
||||
matrix_of_quantity_divide_by_scalar();
|
||||
}
|
||||
|
||||
template<units::Unit U = si::metre, units::Representation Rep = double>
|
||||
using length_v = si::length<U, vector<Rep>>;
|
||||
template<Unit auto U = si::metre, Representation Rep = double>
|
||||
using length_v = quantity<isq::length[U], vector<Rep>>;
|
||||
|
||||
template<units::Unit U = si::newton, units::Representation Rep = double>
|
||||
using force_v = si::force<U, vector<Rep>>;
|
||||
template<Unit auto U = si::newton, Representation Rep = double>
|
||||
using force_v = quantity<isq::force[U], vector<Rep>>;
|
||||
|
||||
void quantity_of_vector_add()
|
||||
{
|
||||
@ -217,7 +220,7 @@ void quantity_of_vector_add()
|
||||
|
||||
length_v<> v(vector<>{1, 2, 3});
|
||||
length_v<> u(vector<>{3, 2, 1});
|
||||
length_v<si::kilometre> t(vector<>{3, 2, 1});
|
||||
length_v<si::kilo<si::metre>> t(vector<>{3, 2, 1});
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
std::cout << "u = " << u << "\n";
|
||||
@ -278,8 +281,8 @@ void quantity_of_vector_tests()
|
||||
quantity_of_vector_divide_by_scalar();
|
||||
}
|
||||
|
||||
template<units::Unit U = si::metre, units::Representation Rep = double>
|
||||
using length_m = si::length<U, matrix<Rep>>;
|
||||
template<Unit auto U = si::metre, Representation Rep = double>
|
||||
using length_m = quantity<isq::length[U], matrix<Rep>>;
|
||||
|
||||
void quantity_of_matrix_add()
|
||||
{
|
||||
@ -287,7 +290,7 @@ void quantity_of_matrix_add()
|
||||
|
||||
length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
|
||||
length_m<> u(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}});
|
||||
length_m<si::kilometre> t(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}});
|
||||
length_m<si::kilo<si::metre>> t(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}});
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
std::cout << "u =\n" << u << "\n";
|
@ -1,62 +0,0 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2018 Mateusz Pusz
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
|
||||
#
|
||||
# add_example(target <depependencies>...)
|
||||
#
|
||||
function(add_example target)
|
||||
add_executable(${target}-literals ${target}.cpp)
|
||||
target_link_libraries(${target}-literals PRIVATE ${ARGN})
|
||||
target_compile_definitions(${target}-literals PRIVATE ${projectPrefix}NO_REFERENCES ${projectPrefix}NO_ALIASES)
|
||||
endfunction()
|
||||
|
||||
add_example(avg_speed mp-units::core-io mp-units::si mp-units::si-cgs mp-units::si-international)
|
||||
add_example(box_example mp-units::core-fmt mp-units::si)
|
||||
add_example(capacitor_time_curve mp-units::core-io mp-units::si)
|
||||
add_example(
|
||||
clcpp_response
|
||||
mp-units::core-fmt
|
||||
mp-units::core-io
|
||||
mp-units::si
|
||||
mp-units::si-iau
|
||||
mp-units::si-imperial
|
||||
mp-units::si-international
|
||||
mp-units::si-typographic
|
||||
mp-units::si-uscs
|
||||
)
|
||||
add_example(experimental_angle mp-units::core-fmt mp-units::core-io mp-units::si)
|
||||
add_example(foot_pound_second mp-units::core-fmt mp-units::si-fps)
|
||||
add_example(total_energy mp-units::core-io mp-units::si mp-units::isq-natural)
|
||||
add_example(unknown_dimension mp-units::core-io mp-units::si)
|
||||
|
||||
if(NOT ${projectPrefix}LIBCXX)
|
||||
add_example(glide_computer_example mp-units::core-fmt mp-units::si-international glide_computer)
|
||||
target_compile_definitions(
|
||||
glide_computer_example-literals PRIVATE ${projectPrefix}NO_REFERENCES ${projectPrefix}NO_ALIASES
|
||||
)
|
||||
|
||||
find_package(wg21_linear_algebra CONFIG REQUIRED)
|
||||
add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si)
|
||||
target_link_libraries(linear_algebra-literals PRIVATE wg21_linear_algebra::wg21_linear_algebra)
|
||||
endif()
|
@ -1,190 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/isq/si/cgs/length.h>
|
||||
#include <units/isq/si/cgs/speed.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/international/length.h>
|
||||
#include <units/isq/si/international/speed.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/length.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/speed.h>
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace units::isq;
|
||||
|
||||
constexpr si::speed<si::metre_per_second, int> fixed_int_si_avg_speed(si::length<si::metre, int> d,
|
||||
si::time<si::second, int> t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
|
||||
constexpr si::speed<si::metre_per_second> fixed_double_si_avg_speed(si::length<si::metre> d, si::time<si::second> t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
|
||||
template<typename U1, typename R1, typename U2, typename R2>
|
||||
constexpr Speed auto si_avg_speed(si::length<U1, R1> d, si::time<U2, R2> t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
|
||||
constexpr Speed auto avg_speed(Length auto d, Time auto t) { return d / t; }
|
||||
|
||||
template<Length D, Time T, Speed V>
|
||||
void print_result(D distance, T duration, V speed)
|
||||
{
|
||||
const auto result_in_kmph = units::quantity_cast<si::speed<si::kilometre_per_hour>>(speed);
|
||||
std::cout << "Average speed of a car that makes " << distance << " in " << duration << " is " << result_in_kmph
|
||||
<< ".\n";
|
||||
}
|
||||
|
||||
void example()
|
||||
{
|
||||
// SI (int)
|
||||
{
|
||||
using namespace units::isq::si::literals;
|
||||
constexpr auto distance = 220_q_km;
|
||||
constexpr auto duration = 2_q_h;
|
||||
|
||||
std::cout << "SI units with 'int' as representation\n";
|
||||
|
||||
print_result(distance, duration, fixed_int_si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
|
||||
// SI (double)
|
||||
{
|
||||
using namespace units::isq::si::literals;
|
||||
constexpr auto distance = 220._q_km;
|
||||
constexpr auto duration = 2._q_h;
|
||||
|
||||
std::cout << "\nSI units with 'double' as representation\n";
|
||||
|
||||
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
|
||||
print_result(distance, duration,
|
||||
fixed_int_si_avg_speed(quantity_cast<int>(distance), quantity_cast<int>(duration)));
|
||||
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
|
||||
// Customary Units (int)
|
||||
{
|
||||
using namespace units::isq::si::international::literals;
|
||||
using namespace units::isq::si::literals;
|
||||
constexpr auto distance = 140_q_mi;
|
||||
constexpr auto duration = 2_q_h;
|
||||
|
||||
std::cout << "\nUS Customary Units with 'int' as representation\n";
|
||||
|
||||
// it is not possible to make a lossless conversion of miles to meters on an integral type
|
||||
// (explicit cast needed)
|
||||
print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast<si::metre>(distance), duration));
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
|
||||
// Customary Units (double)
|
||||
{
|
||||
using namespace units::isq::si::international::literals;
|
||||
using namespace units::isq::si::literals;
|
||||
constexpr auto distance = 140._q_mi;
|
||||
constexpr auto duration = 2._q_h;
|
||||
|
||||
std::cout << "\nUS Customary Units with 'double' as representation\n";
|
||||
|
||||
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
|
||||
// also it is not possible to make a lossless conversion of miles to meters on an integral type
|
||||
// (explicit cast needed)
|
||||
print_result(
|
||||
distance, duration,
|
||||
fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
|
||||
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
|
||||
// CGS (int)
|
||||
{
|
||||
using namespace units::isq::si::cgs::literals;
|
||||
constexpr auto distance = 22'000'000_q_cm;
|
||||
constexpr si::cgs::time<si::hour, int> duration(2); // cannot use an SI literal here
|
||||
|
||||
std::cout << "\nCGS units with 'int' as representation\n";
|
||||
|
||||
// it is not possible to make a lossless conversion of centimeters to meters on an integral type
|
||||
// (explicit cast needed)
|
||||
print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast<si::metre>(distance), duration));
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
|
||||
// not possible to convert both a dimension and a unit with implicit cast
|
||||
print_result(distance, duration, si_avg_speed(quantity_cast<si::dim_length>(distance), duration));
|
||||
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
|
||||
// CGS (double)
|
||||
{
|
||||
using namespace units::isq::si::cgs::literals;
|
||||
constexpr auto distance = 22'000'000._q_cm;
|
||||
constexpr si::cgs::time<si::hour, double> duration(2); // cannot use an SI literal here
|
||||
|
||||
std::cout << "\nCGS units with 'double' as representation\n";
|
||||
|
||||
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
|
||||
// it is not possible to make a lossless conversion of centimeters to meters on an integral type
|
||||
// (explicit cast needed)
|
||||
print_result(
|
||||
distance, duration,
|
||||
fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
|
||||
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
|
||||
// not possible to convert both a dimension and a unit with implicit cast
|
||||
print_result(distance, duration, si_avg_speed(quantity_cast<si::dim_length>(distance), duration));
|
||||
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
example();
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
|
||||
} catch (...) {
|
||||
std::cerr << "Unhandled unknown exception caught\n";
|
||||
}
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/format.h>
|
||||
#include <units/generic/dimensionless.h>
|
||||
#include <units/isq/si/amount_of_substance.h>
|
||||
#include <units/isq/si/area.h>
|
||||
#include <units/isq/si/constants.h>
|
||||
#include <units/isq/si/density.h>
|
||||
#include <units/isq/si/force.h>
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/mass.h>
|
||||
#include <units/isq/si/speed.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/isq/si/volume.h>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace units::isq;
|
||||
|
||||
using m = si::metre;
|
||||
using m2 = si::square_metre;
|
||||
using m3 = si::cubic_metre;
|
||||
using kg = si::kilogram;
|
||||
using N = si::newton;
|
||||
using kgpm3 = si::kilogram_per_metre_cub;
|
||||
|
||||
inline constexpr auto g = si::si2019::standard_gravity<>;
|
||||
inline constexpr si::density<kgpm3> air_density(1.225);
|
||||
|
||||
|
||||
class Box {
|
||||
si::area<m2> base_;
|
||||
si::length<m> height_;
|
||||
si::density<kgpm3> density_ = air_density;
|
||||
public:
|
||||
constexpr Box(const si::length<m>& length, const si::length<m>& width, si::length<m> height) :
|
||||
base_(length * width), height_(std::move(height))
|
||||
{
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr si::force<N> filled_weight() const
|
||||
{
|
||||
const si::volume<m3> volume = base_ * height_;
|
||||
const si::mass<kg> mass = density_ * volume;
|
||||
return mass * g;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr si::length<m> fill_level(const si::mass<kg>& measured_mass) const
|
||||
{
|
||||
return height_ * measured_mass * g / filled_weight();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr si::volume<m3> spare_capacity(const si::mass<kg>& measured_mass) const
|
||||
{
|
||||
return (height_ - fill_level(measured_mass)) * base_;
|
||||
}
|
||||
|
||||
constexpr void set_contents_density(const si::density<kgpm3>& density_in)
|
||||
{
|
||||
assert(density_in > air_density);
|
||||
density_ = density_in;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace units;
|
||||
using namespace si::literals;
|
||||
|
||||
const si::length<m> height(200.0_q_mm);
|
||||
auto box = Box(1000.0_q_mm, 500.0_q_mm, height);
|
||||
box.set_contents_density(1000.0_q_kg_per_m3);
|
||||
|
||||
const auto fill_time = 200.0_q_s; // time since starting fill
|
||||
const auto measured_mass = 20.0_q_kg; // measured mass at fill_time
|
||||
|
||||
const Length auto fill_level = box.fill_level(measured_mass);
|
||||
const Dimensionless auto fill_percent = quantity_cast<percent>(fill_level / height);
|
||||
const Volume auto spare_capacity = box.spare_capacity(measured_mass);
|
||||
const auto input_flow_rate = measured_mass / fill_time; // unknown dimension
|
||||
const Speed auto float_rise_rate = fill_level / fill_time;
|
||||
const Time auto fill_time_left = (height / fill_level - 1) * fill_time;
|
||||
|
||||
std::cout << "mp-units box example...\n";
|
||||
std::cout << STD_FMT::format("fill height at {} = {} ({} full)\n", fill_time, fill_level, fill_percent);
|
||||
std::cout << STD_FMT::format("spare_capacity at {} = {}\n", fill_time, spare_capacity);
|
||||
std::cout << STD_FMT::format("input flow rate after {} = {}\n", fill_time, input_flow_rate);
|
||||
std::cout << STD_FMT::format("float rise rate = {}\n", float_rise_rate);
|
||||
std::cout << STD_FMT::format("box full E.T.A. at current flow rate = {}\n", fill_time_left);
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2003-2020 Andy Little.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses./
|
||||
*/
|
||||
|
||||
/*
|
||||
capacitor discharge curve using compile_time
|
||||
physical_quantities
|
||||
*/
|
||||
|
||||
#include <units/generic/dimensionless.h>
|
||||
#include <units/isq/dimensions/electric_current.h>
|
||||
#include <units/isq/si/capacitance.h>
|
||||
#include <units/isq/si/resistance.h>
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/isq/si/voltage.h>
|
||||
#include <units/math.h> // IWYU pragma: keep
|
||||
#include <units/quantity_io.h>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace units::isq;
|
||||
using namespace units::isq::si;
|
||||
|
||||
std::cout << "mp-units capacitor time curve example...\n";
|
||||
std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
|
||||
std::cout.precision(3);
|
||||
|
||||
constexpr auto C = 0.47_q_uF;
|
||||
constexpr auto V0 = 5.0_q_V;
|
||||
constexpr auto R = 4.7_q_kR;
|
||||
|
||||
for (auto t = 0_q_ms; t <= 50_q_ms; ++t) {
|
||||
const Voltage auto Vt = V0 * units::exp(-t / (R * C));
|
||||
|
||||
std::cout << "at " << t << " voltage is ";
|
||||
|
||||
if (Vt >= 1_q_V)
|
||||
std::cout << Vt;
|
||||
else if (Vt >= 1_q_mV)
|
||||
std::cout << quantity_cast<millivolt>(Vt);
|
||||
else if (Vt >= 1_q_uV)
|
||||
std::cout << quantity_cast<microvolt>(Vt);
|
||||
else if (Vt >= 1_q_nV)
|
||||
std::cout << quantity_cast<nanovolt>(Vt);
|
||||
else
|
||||
std::cout << quantity_cast<picovolt>(Vt);
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2003-2019 Andy Little.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses./
|
||||
*/
|
||||
|
||||
#include <units/format.h>
|
||||
#include <units/isq/si/area.h>
|
||||
#include <units/isq/si/iau/length.h>
|
||||
#include <units/isq/si/imperial/length.h>
|
||||
#include <units/isq/si/international/length.h>
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/isq/si/typographic/length.h>
|
||||
#include <units/isq/si/uscs/length.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace units;
|
||||
|
||||
void simple_quantities()
|
||||
{
|
||||
using namespace units::isq::si;
|
||||
using namespace units::isq::si::international;
|
||||
|
||||
using distance = length<metre>;
|
||||
using duration = isq::si::time<second>;
|
||||
|
||||
constexpr distance km = 1.0_q_km;
|
||||
constexpr distance miles = 1.0_q_mi;
|
||||
|
||||
constexpr duration sec = 1_q_s;
|
||||
constexpr duration min = 1_q_min;
|
||||
constexpr duration hr = 1_q_h;
|
||||
|
||||
std::cout << "A physical quantities library can choose the simple\n";
|
||||
std::cout << "option to provide output using a single type for each base unit:\n\n";
|
||||
std::cout << km << '\n';
|
||||
std::cout << miles << '\n';
|
||||
std::cout << sec << '\n';
|
||||
std::cout << min << '\n';
|
||||
std::cout << hr << "\n\n";
|
||||
}
|
||||
|
||||
void quantities_with_typed_units()
|
||||
{
|
||||
using namespace units::isq;
|
||||
using namespace units::isq::si;
|
||||
using namespace units::isq::si::international;
|
||||
|
||||
constexpr length<kilometre> km = 1.0_q_km;
|
||||
constexpr length<mile> miles = 1.0_q_mi;
|
||||
|
||||
std::cout.precision(6);
|
||||
|
||||
constexpr si::time<second> sec = 1_q_s;
|
||||
constexpr si::time<minute> min = 1_q_min;
|
||||
constexpr si::time<hour> hr = 1_q_h;
|
||||
|
||||
std::cout << "A more flexible option is to provide separate types for each unit,\n\n";
|
||||
std::cout << km << '\n';
|
||||
std::cout << miles << '\n';
|
||||
std::cout << sec << '\n';
|
||||
std::cout << min << '\n';
|
||||
std::cout << hr << "\n\n";
|
||||
|
||||
constexpr length<metre> meter = 1_q_m;
|
||||
std::cout << "then a wide range of pre-defined units can be defined and converted,\n"
|
||||
" for consistency and repeatability across applications:\n\n";
|
||||
|
||||
std::cout << meter << '\n';
|
||||
|
||||
std::cout << " = " << quantity_cast<si::astronomical_unit>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::iau::angstrom>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::imperial::chain>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::international::fathom>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::uscs::fathom>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::international::foot>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::uscs::foot>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::international::inch>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::iau::light_year>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::international::mile>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::international::nautical_mile>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::iau::parsec>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::typographic::pica_comp>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::typographic::pica_prn>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::typographic::point_comp>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::typographic::point_prn>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::imperial::rod>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::international::yard>(meter) << '\n';
|
||||
}
|
||||
|
||||
void calcs_comparison()
|
||||
{
|
||||
using namespace units::isq::si;
|
||||
|
||||
std::cout << "\nA distinct unit for each type is efficient and accurate\n"
|
||||
"when adding two values of the same very big\n"
|
||||
"or very small type:\n\n";
|
||||
|
||||
const length<femtometre, float> L1A = 2._q_fm;
|
||||
const length<femtometre, float> L2A = 3._q_fm;
|
||||
const length<femtometre, float> LrA = L1A + L2A;
|
||||
std::cout << STD_FMT::format("{:%.30Q %q}\n + {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, LrA);
|
||||
|
||||
std::cout << "The single unit method must convert large\n"
|
||||
"or small values in other units to the base unit.\n"
|
||||
"This is both inefficient and inaccurate\n\n";
|
||||
|
||||
const length<metre, float> L1B = L1A;
|
||||
const length<metre, float> L2B = L2A;
|
||||
const length<metre, float> LrB = L1B + L2B;
|
||||
std::cout << STD_FMT::format("{:%.30Q %q}\n + {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1B, L2B, LrB);
|
||||
|
||||
std::cout << "In multiplication and division:\n\n";
|
||||
|
||||
const area<square_femtometre, float> ArA = L1A * L2A;
|
||||
std::cout << STD_FMT::format("{:%.30Q %q}\n * {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, ArA);
|
||||
|
||||
std::cout << "similar problems arise\n\n";
|
||||
|
||||
const area<square_metre, float> ArB = L1B * L2B;
|
||||
std::cout << STD_FMT::format("{:%.30Q %q}\n * {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1B, L2B, ArB);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "This demo was originally posted on com.lang.c++.moderated in 2006\n";
|
||||
std::cout << "http://compgroups.net/comp.lang.c++.moderated/dimensional-analysis-units/51712\n";
|
||||
std::cout << "Here converted to use mp-units library.\n\n";
|
||||
|
||||
simple_quantities();
|
||||
quantities_with_typed_units();
|
||||
calcs_comparison();
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/generic/angle.h>
|
||||
#include <units/isq/si/energy.h>
|
||||
#include <units/isq/si/torque.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace units;
|
||||
using namespace units::isq;
|
||||
using namespace units::isq::si::literals;
|
||||
|
||||
const auto torque = 20.0_q_N_m_per_rad / std::numbers::pi;
|
||||
const auto energy = 20.0_q_J;
|
||||
|
||||
Angle auto angle = energy / torque;
|
||||
|
||||
std::cout << angle << '\n';
|
||||
std::cout << quantity_cast<revolution>(angle) << '\n';
|
||||
std::cout << quantity_cast<degree>(angle) << '\n';
|
||||
std::cout << quantity_cast<gradian>(angle) << '\n';
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/format.h>
|
||||
#include <units/isq/si/fps/density.h>
|
||||
#include <units/isq/si/fps/length.h>
|
||||
#include <units/isq/si/fps/mass.h>
|
||||
#include <units/isq/si/fps/power.h>
|
||||
#include <units/isq/si/fps/speed.h>
|
||||
#include <units/isq/si/international/speed.h>
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/mass.h>
|
||||
#include <units/isq/si/power.h>
|
||||
#include <units/isq/si/speed.h>
|
||||
#include <units/isq/si/volume.h>
|
||||
#include <iostream>
|
||||
#include <string_view>
|
||||
|
||||
using namespace units::isq;
|
||||
|
||||
|
||||
// Some basic specs for the warship
|
||||
struct Ship {
|
||||
si::fps::length<si::fps::foot> length;
|
||||
si::fps::length<si::fps::foot> draft;
|
||||
si::fps::length<si::fps::foot> beam;
|
||||
|
||||
si::fps::speed<si::fps::foot_per_second> speed;
|
||||
si::fps::mass<si::fps::pound> mass;
|
||||
|
||||
si::fps::length<si::fps::inch> mainGuns;
|
||||
si::fps::mass<si::fps::pound> shellMass;
|
||||
si::fps::speed<si::fps::foot_per_second> shellSpeed;
|
||||
si::fps::power<si::fps::foot_poundal_per_second> power;
|
||||
};
|
||||
|
||||
// Print 'a' in its current units and print its value cast to the units in each of Args
|
||||
template<class... Args, units::Quantity Q>
|
||||
auto fmt_line(const Q a)
|
||||
{
|
||||
return STD_FMT::format("{:22}", a) + (STD_FMT::format(",{:20}", units::quantity_cast<Args>(a)) + ...);
|
||||
}
|
||||
|
||||
// Print the ship details in the units as defined in the Ship struct, in other si::imperial units, and in SI
|
||||
void print_details(std::string_view description, const Ship& ship)
|
||||
{
|
||||
using namespace units::isq::si::fps::literals;
|
||||
const auto waterDensity = 62.4_q_lb_per_ft3;
|
||||
std::cout << STD_FMT::format("{}\n", description);
|
||||
std::cout << STD_FMT::format("{:20} : {}\n", "length",
|
||||
fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.length))
|
||||
<< STD_FMT::format("{:20} : {}\n", "draft",
|
||||
fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.draft))
|
||||
<< STD_FMT::format("{:20} : {}\n", "beam",
|
||||
fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.beam))
|
||||
<< STD_FMT::format("{:20} : {}\n", "mass",
|
||||
fmt_line<si::fps::mass<si::fps::long_ton>, si::mass<si::tonne>>(ship.mass))
|
||||
<< STD_FMT::format(
|
||||
"{:20} : {}\n", "speed",
|
||||
fmt_line<si::speed<si::international::knot>, si::speed<si::kilometre_per_hour>>(ship.speed))
|
||||
<< STD_FMT::format("{:20} : {}\n", "power",
|
||||
fmt_line<si::fps::power<si::fps::horse_power>, si::power<si::kilowatt>>(ship.power))
|
||||
<< STD_FMT::format("{:20} : {}\n", "main guns",
|
||||
fmt_line<si::fps::length<si::fps::inch>, si::length<si::millimetre>>(ship.mainGuns))
|
||||
<< STD_FMT::format("{:20} : {}\n", "fire shells weighing",
|
||||
fmt_line<si::fps::mass<si::fps::long_ton>, si::mass<si::kilogram>>(ship.shellMass))
|
||||
<< STD_FMT::format(
|
||||
"{:20} : {}\n", "fire shells at",
|
||||
fmt_line<si::fps::speed<si::fps::mile_per_hour>, si::speed<si::kilometre_per_hour>>(ship.shellSpeed))
|
||||
<< STD_FMT::format("{:20} : {}\n", "volume underwater",
|
||||
fmt_line<si::volume<si::cubic_metre>, si::volume<si::litre>>(ship.mass / waterDensity));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace units::isq::si::literals;
|
||||
using namespace units::isq::si::fps::literals;
|
||||
|
||||
// KMS Bismark, using the units the Germans would use, taken from Wiki
|
||||
auto bismark = Ship{.length{251._q_m},
|
||||
.draft{9.3_q_m},
|
||||
.beam{36_q_m},
|
||||
.speed{56_q_km_per_h},
|
||||
.mass{50'300_q_t},
|
||||
.mainGuns{380_q_mm},
|
||||
.shellMass{800_q_kg},
|
||||
.shellSpeed{820._q_m_per_s},
|
||||
.power{110.45_q_kW}};
|
||||
|
||||
// USS Iowa, using units from the foot-pound-second system
|
||||
auto iowa = Ship{.length{860._q_ft},
|
||||
.draft{37._q_ft + 2._q_in},
|
||||
.beam{108._q_ft + 2._q_in},
|
||||
.speed{si::speed<si::international::knot>{33}},
|
||||
.mass{57'540_q_lton},
|
||||
.mainGuns{16_q_in},
|
||||
.shellMass{2700_q_lb},
|
||||
.shellSpeed{2690._q_ft_per_s},
|
||||
.power{212'000_q_hp}};
|
||||
|
||||
// HMS King George V, using units from the foot-pound-second system
|
||||
auto kgv = Ship{.length{745.1_q_ft},
|
||||
.draft{33._q_ft + 7.5_q_in},
|
||||
.beam{103.2_q_ft + 2.5_q_in},
|
||||
.speed{si::speed<si::international::knot>{28.3}},
|
||||
.mass{42'245_q_lton},
|
||||
.mainGuns{14_q_in},
|
||||
.shellMass{1'590_q_lb},
|
||||
.shellSpeed{2483._q_ft_per_s},
|
||||
.power{110'000_q_hp}};
|
||||
|
||||
print_details("KMS Bismark, defined in appropriate units from the SI system", bismark);
|
||||
std::cout << "\n\n";
|
||||
print_details("USS Iowa, defined in appropriate units foot-pound-second system", iowa);
|
||||
std::cout << "\n\n";
|
||||
print_details("HMS King George V, defined in appropriate units foot-pound-second system", kgv);
|
||||
}
|
@ -1,201 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include "glide_computer.h"
|
||||
#include <units/bits/fmt_hacks.h>
|
||||
#include <units/chrono.h>
|
||||
#include <units/generic/angle.h>
|
||||
#include <units/generic/dimensionless.h>
|
||||
#include <units/isq/si/international/length.h>
|
||||
#include <array>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace glide_computer;
|
||||
|
||||
using namespace units::isq;
|
||||
|
||||
auto get_gliders()
|
||||
{
|
||||
using namespace si::literals;
|
||||
UNITS_DIAGNOSTIC_PUSH
|
||||
UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES
|
||||
static const std::array gliders = {
|
||||
glider{"SZD-30 Pirat", {velocity(83_q_km_per_h), rate_of_climb(-0.7389_q_m_per_s)}},
|
||||
glider{"SZD-51 Junior", {velocity(80_q_km_per_h), rate_of_climb(-0.6349_q_m_per_s)}},
|
||||
glider{"SZD-48 Jantar Std 3", {velocity(110_q_km_per_h), rate_of_climb(-0.77355_q_m_per_s)}},
|
||||
glider{"SZD-56 Diana", {velocity(110_q_km_per_h), rate_of_climb(-0.63657_q_m_per_s)}}};
|
||||
UNITS_DIAGNOSTIC_POP
|
||||
return gliders;
|
||||
}
|
||||
|
||||
auto get_weather_conditions()
|
||||
{
|
||||
using namespace si::literals;
|
||||
static const std::array weather_conditions = {
|
||||
std::pair("Good", weather{height(1900_q_m), rate_of_climb(4.3_q_m_per_s)}),
|
||||
std::pair("Medium", weather{height(1550_q_m), rate_of_climb(2.8_q_m_per_s)}),
|
||||
std::pair("Bad", weather{height(850_q_m), rate_of_climb(1.8_q_m_per_s)})};
|
||||
return weather_conditions;
|
||||
}
|
||||
|
||||
auto get_waypoints()
|
||||
{
|
||||
using namespace geographic::literals;
|
||||
using namespace units::isq::si::international::literals;
|
||||
static const std::array waypoints = {
|
||||
waypoint{"EPPR", {54.24772_N, 18.6745_E}, altitude(16_q_ft)}, // N54°14'51.8" E18°40'28.2"
|
||||
waypoint{"EPGI", {53.52442_N, 18.84947_E}, altitude(115_q_ft)} // N53°31'27.9" E18°50'58.1"
|
||||
};
|
||||
return waypoints;
|
||||
}
|
||||
|
||||
template<std::ranges::input_range R>
|
||||
requires(std::same_as<std::ranges::range_value_t<R>, glider>)
|
||||
void print(const R& gliders)
|
||||
{
|
||||
std::cout << "Gliders:\n";
|
||||
std::cout << "========\n";
|
||||
for (const auto& g : gliders) {
|
||||
std::cout << "- Name: " << g.name << "\n";
|
||||
std::cout << "- Polar:\n";
|
||||
for (const auto& p : g.polar) {
|
||||
const auto ratio = units::quantity_cast<units::one>(glide_ratio(g.polar[0]));
|
||||
std::cout << STD_FMT::format(" * {:%.4Q %q} @ {:%.1Q %q} -> {:%.1Q %q} ({:%.1Q %q})\n", p.climb, p.v, ratio,
|
||||
units::quantity_cast<units::degree>(asin(1 / ratio)));
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
template<std::ranges::input_range R>
|
||||
requires(std::same_as<std::ranges::range_value_t<R>, std::pair<const char*, weather>>)
|
||||
void print(const R& conditions)
|
||||
{
|
||||
std::cout << "Weather:\n";
|
||||
std::cout << "========\n";
|
||||
for (const auto& c : conditions) {
|
||||
std::cout << "- " << c.first << "\n";
|
||||
const auto& w = c.second;
|
||||
std::cout << " * Cloud base: " << STD_FMT::format("{:%.0Q %q}", w.cloud_base) << " AGL\n";
|
||||
std::cout << " * Thermals strength: " << STD_FMT::format("{:%.1Q %q}", w.thermal_strength) << "\n";
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
template<std::ranges::input_range R>
|
||||
requires(std::same_as<std::ranges::range_value_t<R>, waypoint>)
|
||||
void print(const R& waypoints)
|
||||
{
|
||||
std::cout << "Waypoints:\n";
|
||||
std::cout << "==========\n";
|
||||
for (const auto& w : waypoints)
|
||||
std::cout << STD_FMT::format("- {}: {} {}, {:%.1Q %q}\n", w.name, w.pos.lat, w.pos.lon, w.alt);
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void print(const task& t)
|
||||
{
|
||||
std::cout << "Task:\n";
|
||||
std::cout << "=====\n";
|
||||
|
||||
std::cout << "- Start: " << t.get_start().name << "\n";
|
||||
std::cout << "- Finish: " << t.get_finish().name << "\n";
|
||||
std::cout << "- Length: " << STD_FMT::format("{:%.1Q %q}", t.get_length()) << "\n";
|
||||
|
||||
std::cout << "- Legs: "
|
||||
<< "\n";
|
||||
for (const auto& l : t.get_legs())
|
||||
std::cout << STD_FMT::format(" * {} -> {} ({:%.1Q %q})\n", l.begin().name, l.end().name, l.get_length());
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void print(const safety& s)
|
||||
{
|
||||
std::cout << "Safety:\n";
|
||||
std::cout << "=======\n";
|
||||
std::cout << "- Min AGL separation: " << STD_FMT::format("{:%.0Q %q}", s.min_agl_height) << "\n";
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void print(const aircraft_tow& tow)
|
||||
{
|
||||
std::cout << "Tow:\n";
|
||||
std::cout << "====\n";
|
||||
std::cout << "- Type: aircraft\n";
|
||||
std::cout << "- Height: " << STD_FMT::format("{:%.0Q %q}", tow.height_agl) << "\n";
|
||||
std::cout << "- Performance: " << STD_FMT::format("{:%.1Q %q}", tow.performance) << "\n";
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void example()
|
||||
{
|
||||
using namespace si::literals;
|
||||
|
||||
const safety sfty = {height(300_q_m)};
|
||||
const auto gliders = get_gliders();
|
||||
const auto waypoints = get_waypoints();
|
||||
const auto weather_conditions = get_weather_conditions();
|
||||
const task t = {waypoints[0], waypoints[1], waypoints[0]};
|
||||
const aircraft_tow tow = {height(400_q_m), rate_of_climb(1.6_q_m_per_s)};
|
||||
// TODO use C++20 date library when available
|
||||
// set `start_time` to 11:00 am today
|
||||
const timestamp start_time(std::chrono::system_clock::now());
|
||||
|
||||
print(sfty);
|
||||
print(gliders);
|
||||
print(waypoints);
|
||||
print(weather_conditions);
|
||||
print(t);
|
||||
print(tow);
|
||||
|
||||
for (const auto& g : gliders) {
|
||||
for (const auto& c : weather_conditions) {
|
||||
std::string txt = "Scenario: Glider = " + g.name + ", Weather = " + c.first;
|
||||
std::cout << txt << "\n";
|
||||
std::cout << STD_FMT::format("{0:=^{1}}\n\n", "", txt.size());
|
||||
|
||||
estimate(start_time, g, c.second, t, sfty, tow);
|
||||
|
||||
std::cout << "\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
example();
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
|
||||
} catch (...) {
|
||||
std::cerr << "Unhandled unknown exception caught\n";
|
||||
}
|
||||
}
|
@ -1,361 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/format.h>
|
||||
#include <units/isq/si/energy.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/force.h>
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/speed.h> // IWYU pragma: keep
|
||||
#include <units/quantity_io.h>
|
||||
#include <iostream>
|
||||
#include <linear_algebra.hpp>
|
||||
|
||||
namespace STD_LA {
|
||||
|
||||
template<class ET, class OT>
|
||||
std::ostream& operator<<(std::ostream& os, const vector<ET, OT>& v)
|
||||
{
|
||||
os << "|";
|
||||
for (auto i = 0U; i < v.size(); ++i) {
|
||||
os << STD_FMT::format(" {:>9}", v(i));
|
||||
}
|
||||
os << " |";
|
||||
return os;
|
||||
}
|
||||
|
||||
template<class ET, class OT>
|
||||
std::ostream& operator<<(std::ostream& os, const matrix<ET, OT>& v)
|
||||
{
|
||||
for (auto i = 0U; i < v.rows(); ++i) {
|
||||
os << "|";
|
||||
for (auto j = 0U; j < v.columns(); ++j) {
|
||||
os << STD_FMT::format(" {:>9}", v(i, j));
|
||||
}
|
||||
os << (i != v.rows() - 1U ? " |\n" : " |");
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace STD_LA
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace units::isq;
|
||||
using namespace units::isq::si::literals;
|
||||
|
||||
template<typename Rep = double>
|
||||
using vector = std::math::fs_vector<Rep, 3>;
|
||||
|
||||
template<typename Rep = double>
|
||||
using matrix = std::math::fs_matrix<Rep, 3, 3>;
|
||||
|
||||
|
||||
void vector_of_quantity_add()
|
||||
{
|
||||
std::cout << "\nvector_of_quantity_add:\n";
|
||||
|
||||
vector<si::length<si::metre>> v = {1_q_m, 2_q_m, 3_q_m};
|
||||
vector<si::length<si::metre>> u = {3_q_m, 2_q_m, 1_q_m};
|
||||
vector<si::length<si::kilometre>> t = {3_q_km, 2_q_km, 1_q_km};
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
std::cout << "u = " << u << "\n";
|
||||
std::cout << "t = " << t << "\n";
|
||||
|
||||
std::cout << "v + u = " << v + u << "\n";
|
||||
std::cout << "v + t = " << v + t << "\n";
|
||||
std::cout << "t[m] = " << vector<si::length<si::metre>>(t) << "\n";
|
||||
}
|
||||
|
||||
void vector_of_quantity_multiply_same()
|
||||
{
|
||||
std::cout << "\nvector_of_quantity_multiply_same:\n";
|
||||
|
||||
vector<si::length<si::metre>> v = {1_q_m, 2_q_m, 3_q_m};
|
||||
vector<si::length<si::metre>> u = {3_q_m, 2_q_m, 1_q_m};
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
std::cout << "u = " << u << "\n";
|
||||
|
||||
std::cout << "v * u = " << v * u << "\n";
|
||||
std::cout << "2_q_m * v = " << 2._q_m * v << "\n";
|
||||
}
|
||||
|
||||
void vector_of_quantity_multiply_different()
|
||||
{
|
||||
std::cout << "\nvector_of_quantity_multiply_different:\n";
|
||||
|
||||
vector<si::force<si::newton>> v = {1_q_N, 2_q_N, 3_q_N};
|
||||
vector<si::length<si::metre>> u = {3_q_m, 2_q_m, 1_q_m};
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
std::cout << "u = " << u << "\n";
|
||||
|
||||
std::cout << "v * u = " << v * u << "\n";
|
||||
std::cout << "2_q_N * u = " << 2._q_N * u << "\n";
|
||||
std::cout << "2 * u = " << 2 * u << "\n";
|
||||
}
|
||||
|
||||
void vector_of_quantity_divide_by_scalar()
|
||||
{
|
||||
std::cout << "\nvector_of_quantity_divide_by_scalar:\n";
|
||||
|
||||
vector<si::length<si::metre>> v = {4_q_m, 8_q_m, 12_q_m};
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
|
||||
// TODO Uncomment when bug in the LA is fixed
|
||||
// std::cout << "v / 2_q_s = " << v / 2_q_s << "\n";
|
||||
// std::cout << "v / 2 = " << v / 2 << "\n";
|
||||
}
|
||||
|
||||
void vector_of_quantity_tests()
|
||||
{
|
||||
vector_of_quantity_add();
|
||||
vector_of_quantity_multiply_same();
|
||||
vector_of_quantity_multiply_different();
|
||||
vector_of_quantity_divide_by_scalar();
|
||||
}
|
||||
|
||||
void matrix_of_quantity_add()
|
||||
{
|
||||
std::cout << "\nmatrix_of_quantity_add:\n";
|
||||
|
||||
matrix<si::length<si::metre>> v = {{1_q_m, 2_q_m, 3_q_m}, {4_q_m, 5_q_m, 6_q_m}, {7_q_m, 8_q_m, 9_q_m}};
|
||||
matrix<si::length<si::metre>> u = {{3_q_m, 2_q_m, 1_q_m}, {3_q_m, 2_q_m, 1_q_m}, {3_q_m, 2_q_m, 1_q_m}};
|
||||
matrix<si::length<si::millimetre>> t = {{3_q_mm, 2_q_mm, 1_q_mm}, {3_q_mm, 2_q_mm, 1_q_mm}, {3_q_mm, 2_q_mm, 1_q_mm}};
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
std::cout << "u =\n" << u << "\n";
|
||||
std::cout << "t =\n" << t << "\n";
|
||||
|
||||
std::cout << "v + u =\n" << v + u << "\n";
|
||||
std::cout << "v + t =\n" << v + t << "\n";
|
||||
|
||||
// TODO Uncomment when fixed in the LA lib
|
||||
// std::cout << "v[mm] =\n" << matrix<si::length<si::millimetre>>(v) << "\n";
|
||||
}
|
||||
|
||||
void matrix_of_quantity_multiply_same()
|
||||
{
|
||||
std::cout << "\nmatrix_of_quantity_multiply_same:\n";
|
||||
|
||||
matrix<si::length<si::metre>> v = {{1_q_m, 2_q_m, 3_q_m}, {4_q_m, 5_q_m, 6_q_m}, {7_q_m, 8_q_m, 9_q_m}};
|
||||
vector<si::length<si::metre>> u = {3_q_m, 2_q_m, 1_q_m};
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
std::cout << "u =\n" << u << "\n";
|
||||
|
||||
std::cout << "v * u =\n" << v * u << "\n";
|
||||
std::cout << "2_q_m * u =\n" << 2._q_m * u << "\n";
|
||||
}
|
||||
|
||||
void matrix_of_quantity_multiply_different()
|
||||
{
|
||||
std::cout << "\nmatrix_of_quantity_multiply_different:\n";
|
||||
|
||||
vector<si::force<si::newton>> v = {1_q_N, 2_q_N, 3_q_N};
|
||||
matrix<si::length<si::metre>> u = {{1_q_m, 2_q_m, 3_q_m}, {4_q_m, 5_q_m, 6_q_m}, {7_q_m, 8_q_m, 9_q_m}};
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
std::cout << "u =\n" << u << "\n";
|
||||
|
||||
std::cout << "v * u =\n" << v * u << "\n";
|
||||
std::cout << "2_q_N * u =\n" << 2._q_N * u << "\n";
|
||||
std::cout << "2 * u =\n" << 2 * u << "\n";
|
||||
}
|
||||
|
||||
void matrix_of_quantity_divide_by_scalar()
|
||||
{
|
||||
std::cout << "\nmatrix_of_quantity_divide_by_scalar:\n";
|
||||
|
||||
matrix<si::length<si::metre>> v = {{2_q_m, 4_q_m, 6_q_m}, {4_q_m, 6_q_m, 8_q_m}, {8_q_m, 4_q_m, 2_q_m}};
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
|
||||
// TODO Uncomment when bug in the LA is fixed
|
||||
// std::cout << "v / 2_q_s =\n" << v / 2_q_s << "\n";
|
||||
// std::cout << "v / 2 =\n" << v / 2 << "\n";
|
||||
}
|
||||
|
||||
void matrix_of_quantity_tests()
|
||||
{
|
||||
matrix_of_quantity_add();
|
||||
matrix_of_quantity_multiply_same();
|
||||
matrix_of_quantity_multiply_different();
|
||||
matrix_of_quantity_divide_by_scalar();
|
||||
}
|
||||
|
||||
template<units::Unit U = si::metre, units::Representation Rep = double>
|
||||
using length_v = si::length<U, vector<Rep>>;
|
||||
|
||||
template<units::Unit U = si::newton, units::Representation Rep = double>
|
||||
using force_v = si::force<U, vector<Rep>>;
|
||||
|
||||
void quantity_of_vector_add()
|
||||
{
|
||||
std::cout << "\nquantity_of_vector_add:\n";
|
||||
|
||||
length_v<> v(vector<>{1, 2, 3});
|
||||
length_v<> u(vector<>{3, 2, 1});
|
||||
length_v<si::kilometre> t(vector<>{3, 2, 1});
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
std::cout << "u = " << u << "\n";
|
||||
std::cout << "t = " << t << "\n";
|
||||
|
||||
std::cout << "v + u = " << v + u << "\n";
|
||||
std::cout << "v + t = " << v + t << "\n";
|
||||
std::cout << "t[m] = " << quantity_cast<si::metre>(t) << "\n";
|
||||
}
|
||||
|
||||
void quantity_of_vector_multiply_same()
|
||||
{
|
||||
std::cout << "\nquantity_of_vector_multiply_same:\n";
|
||||
|
||||
length_v<> v(vector<>{1, 2, 3});
|
||||
length_v<> u(vector<>{3, 2, 1});
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
std::cout << "u = " << u << "\n";
|
||||
|
||||
std::cout << "v * u = " << v * u << "\n";
|
||||
std::cout << "2_q_m * v = " << 2._q_m * v << "\n";
|
||||
}
|
||||
|
||||
void quantity_of_vector_multiply_different()
|
||||
{
|
||||
std::cout << "\nquantity_of_vector_multiply_different:\n";
|
||||
|
||||
force_v<> v(vector<>{1, 2, 3});
|
||||
length_v<> u(vector<>{3, 2, 1});
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
std::cout << "u = " << u << "\n";
|
||||
|
||||
std::cout << "v * u = " << v * u << "\n";
|
||||
std::cout << "2_q_N * u = " << 2._q_N * u << "\n";
|
||||
std::cout << "2 * u = " << 2 * u << "\n";
|
||||
}
|
||||
|
||||
void quantity_of_vector_divide_by_scalar()
|
||||
{
|
||||
std::cout << "\nquantity_of_vector_divide_by_scalar:\n";
|
||||
|
||||
length_v<> v(vector<>{4, 8, 12});
|
||||
|
||||
std::cout << "v = " << v << "\n";
|
||||
|
||||
// TODO Uncomment when bug in the LA is fixed
|
||||
// std::cout << "v / 2_q_s = " << v / 2_q_s << "\n";
|
||||
// std::cout << "v / 2 = " << v / 2 << "\n";
|
||||
}
|
||||
|
||||
void quantity_of_vector_tests()
|
||||
{
|
||||
quantity_of_vector_add();
|
||||
quantity_of_vector_multiply_same();
|
||||
quantity_of_vector_multiply_different();
|
||||
quantity_of_vector_divide_by_scalar();
|
||||
}
|
||||
|
||||
template<units::Unit U = si::metre, units::Representation Rep = double>
|
||||
using length_m = si::length<U, matrix<Rep>>;
|
||||
|
||||
void quantity_of_matrix_add()
|
||||
{
|
||||
std::cout << "\nquantity_of_matrix_add:\n";
|
||||
|
||||
length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
|
||||
length_m<> u(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}});
|
||||
length_m<si::kilometre> t(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}});
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
std::cout << "u =\n" << u << "\n";
|
||||
std::cout << "t =\n" << t << "\n";
|
||||
|
||||
std::cout << "v + u =\n" << v + u << "\n";
|
||||
std::cout << "v + t =\n" << v + t << "\n";
|
||||
|
||||
// TODO Uncomment when fixed in the LA lib
|
||||
// std::cout << "v[mm] =\n" << matrix<si::length<si::millimetre>>(v) << "\n";
|
||||
}
|
||||
|
||||
void quantity_of_matrix_multiply_same()
|
||||
{
|
||||
std::cout << "\nquantity_of_matrix_multiply_same:\n";
|
||||
|
||||
length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
|
||||
length_v<> u(vector<>{3, 2, 1});
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
std::cout << "u =\n" << u << "\n";
|
||||
|
||||
std::cout << "v * u =\n" << v * u << "\n";
|
||||
std::cout << "2_q_m * u =\n" << 2._q_m * u << "\n";
|
||||
}
|
||||
|
||||
void quantity_of_matrix_multiply_different()
|
||||
{
|
||||
std::cout << "\nquantity_of_matrix_multiply_different:\n";
|
||||
|
||||
force_v<> v(vector<>{1, 2, 3});
|
||||
length_m<> u(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
std::cout << "u =\n" << u << "\n";
|
||||
|
||||
std::cout << "v * u =\n" << v * u << "\n";
|
||||
std::cout << "2_q_N * u =\n" << 2._q_N * u << "\n";
|
||||
std::cout << "2 * u =\n" << 2 * u << "\n";
|
||||
}
|
||||
|
||||
void quantity_of_matrix_divide_by_scalar()
|
||||
{
|
||||
std::cout << "\nquantity_of_matrix_divide_by_scalar:\n";
|
||||
|
||||
length_m<> v(matrix<>{{2, 4, 6}, {4, 6, 8}, {8, 4, 2}});
|
||||
|
||||
std::cout << "v =\n" << v << "\n";
|
||||
|
||||
// TODO Uncomment when bug in the LA is fixed
|
||||
// std::cout << "v / 2_q_s =\n" << v / 2_q_s << "\n";
|
||||
// std::cout << "v / 2 =\n" << v / 2 << "\n";
|
||||
}
|
||||
|
||||
void quantity_of_matrix_tests()
|
||||
{
|
||||
quantity_of_matrix_add();
|
||||
quantity_of_matrix_multiply_same();
|
||||
quantity_of_matrix_multiply_different();
|
||||
quantity_of_matrix_divide_by_scalar();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
vector_of_quantity_tests();
|
||||
matrix_of_quantity_tests();
|
||||
quantity_of_vector_tests();
|
||||
quantity_of_matrix_tests();
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/isq/natural/natural.h>
|
||||
#include <units/isq/si/constants.h>
|
||||
#include <units/isq/si/energy.h>
|
||||
#include <units/isq/si/mass.h>
|
||||
#include <units/isq/si/momentum.h>
|
||||
#include <units/isq/si/speed.h> // IWYU pragma: keep
|
||||
#include <units/math.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace units::isq;
|
||||
|
||||
Energy auto total_energy(Momentum auto p, Mass auto m, Speed auto c)
|
||||
{
|
||||
return sqrt(pow<2>(p * c) + pow<2>(m * pow<2>(c)));
|
||||
}
|
||||
|
||||
void si_example()
|
||||
{
|
||||
using namespace units::isq::si;
|
||||
|
||||
constexpr Speed auto c = si2019::speed_of_light<>;
|
||||
|
||||
std::cout << "\n*** SI units (c = " << c << ") ***\n";
|
||||
|
||||
const Momentum auto p = 4._q_GeV / c;
|
||||
const Mass auto m = 3._q_GeV / pow<2>(c);
|
||||
const Energy auto E = total_energy(p, m, c);
|
||||
|
||||
std::cout << "[in GeV]\n"
|
||||
<< "p = " << p << "\n"
|
||||
<< "m = " << m << "\n"
|
||||
<< "E = " << E << "\n";
|
||||
|
||||
const momentum<kilogram_metre_per_second> p_si = p;
|
||||
const mass<kilogram> m_si = m;
|
||||
const energy<joule> E_si = total_energy(p_si, m_si, c);
|
||||
|
||||
std::cout << "\n[in SI units]\n"
|
||||
<< "p = " << p_si << "\n"
|
||||
<< "m = " << m_si << "\n"
|
||||
<< "E = " << E_si << "\n";
|
||||
|
||||
std::cout << "\n[converted from SI units back to GeV]\n"
|
||||
<< "E = " << quantity_cast<gigaelectronvolt>(E_si) << "\n";
|
||||
}
|
||||
|
||||
void natural_example()
|
||||
{
|
||||
using namespace units::isq::natural;
|
||||
|
||||
// TODO Typical UDLs will not work here as the same units are reused by many quantities.
|
||||
// Should we define some strange ones (i.e. _q_mass_GeV)?
|
||||
|
||||
constexpr Speed auto c = speed_of_light<>;
|
||||
const momentum<gigaelectronvolt> p(4);
|
||||
const mass<gigaelectronvolt> m(3);
|
||||
const Energy auto E = total_energy(p, m, c);
|
||||
|
||||
std::cout << "\n*** Natural units (c = " << c << ") ***\n"
|
||||
<< "p = " << p << "\n"
|
||||
<< "m = " << m << "\n"
|
||||
<< "E = " << E << "\n";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
si_example();
|
||||
natural_example();
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
|
||||
} catch (...) {
|
||||
std::cerr << "Unhandled unknown exception caught\n";
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/speed.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
template<units::isq::Length D, units::isq::Time T>
|
||||
constexpr units::isq::Speed auto avg_speed(D d, T t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
|
||||
void example()
|
||||
{
|
||||
using namespace units::isq;
|
||||
using namespace units::isq::si::literals;
|
||||
|
||||
Length auto d1 = 123_q_m;
|
||||
Time auto t1 = 10_q_s;
|
||||
Speed auto v1 = avg_speed(d1, t1);
|
||||
|
||||
auto temp1 =
|
||||
v1 * 50_q_m; // produces intermediate unknown dimension with 'unknown_coherent_unit' as its 'coherent_unit'
|
||||
Speed auto v2 = temp1 / 100_q_m; // back to known dimensions again
|
||||
Length auto d2 = v2 * 60_q_s;
|
||||
|
||||
std::cout << "d1 = " << d1 << '\n';
|
||||
std::cout << "t1 = " << t1 << '\n';
|
||||
std::cout << "v1 = " << v1 << '\n';
|
||||
std::cout << "temp1 = " << temp1 << '\n';
|
||||
std::cout << "v2 = " << v2 << '\n';
|
||||
std::cout << "d2 = " << d2 << '\n';
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
example();
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
|
||||
} catch (...) {
|
||||
std::cerr << "Unhandled unknown exception caught\n";
|
||||
}
|
||||
}
|
@ -20,11 +20,10 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/isq/si/acceleration.h>
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/speed.h>
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/isq/space_and_time.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <units/si/unit_symbols.h>
|
||||
#include <units/si/units.h>
|
||||
#include <cmath>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
@ -45,12 +44,12 @@ public:
|
||||
uncertainty_ = abs(err);
|
||||
}
|
||||
|
||||
constexpr const value_type& value() const { return value_; }
|
||||
constexpr const value_type& uncertainty() const { return uncertainty_; }
|
||||
[[nodiscard]] constexpr const value_type& value() const { return value_; }
|
||||
[[nodiscard]] constexpr const value_type& uncertainty() const { return uncertainty_; }
|
||||
|
||||
constexpr value_type relative_uncertainty() const { return uncertainty() / value(); }
|
||||
constexpr value_type lower_bound() const { return value() - uncertainty(); }
|
||||
constexpr value_type upper_bound() const { return value() + uncertainty(); }
|
||||
[[nodiscard]] constexpr value_type relative_uncertainty() const { return uncertainty() / value(); }
|
||||
[[nodiscard]] constexpr value_type lower_bound() const { return value() - uncertainty(); }
|
||||
[[nodiscard]] constexpr value_type upper_bound() const { return value() + uncertainty(); }
|
||||
|
||||
[[nodiscard]] constexpr measurement operator-() const { return measurement(-value(), uncertainty()); }
|
||||
|
||||
@ -125,20 +124,16 @@ static_assert(units::Representation<measurement<double>>);
|
||||
|
||||
void example()
|
||||
{
|
||||
using namespace units::isq;
|
||||
using namespace units;
|
||||
using namespace units::si::unit_symbols;
|
||||
|
||||
const auto a = si::acceleration<si::metre_per_second_sq, measurement<double>>(measurement(9.8, 0.1));
|
||||
const auto t = si::time<si::second, measurement<double>>(measurement(1.2, 0.1));
|
||||
const auto a = measurement{9.8, 0.1} * isq::acceleration[m / s2];
|
||||
const auto t = measurement{1.2, 0.1} * isq::time[s];
|
||||
|
||||
const Speed auto v1 = a * t;
|
||||
#if UNITS_DOWNCAST_MODE == 0
|
||||
std::cout << a << " * " << t << " = " << v1 << " = " << quantity_cast<si::dim_speed, si::kilometre_per_hour>(v1)
|
||||
<< '\n';
|
||||
#else
|
||||
std::cout << a << " * " << t << " = " << v1 << " = " << quantity_cast<si::kilometre_per_hour>(v1) << '\n';
|
||||
#endif
|
||||
const weak_quantity_of<isq::speed> auto v = a * t;
|
||||
std::cout << a << " * " << t << " = " << v << " = " << v[km / h] << '\n';
|
||||
|
||||
si::length<si::metre, measurement<double>> length(measurement(123., 1.));
|
||||
const auto length = measurement{123., 1.} * isq::length[si::metre];
|
||||
std::cout << "10 * " << length << " = " << 10 * length << '\n';
|
||||
}
|
||||
|
||||
|
@ -1,62 +0,0 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2018 Mateusz Pusz
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
|
||||
#
|
||||
# add_example(target <depependencies>...)
|
||||
#
|
||||
function(add_example target)
|
||||
add_executable(${target}-references ${target}.cpp)
|
||||
target_link_libraries(${target}-references PRIVATE ${ARGN})
|
||||
target_compile_definitions(${target}-references PRIVATE ${projectPrefix}NO_LITERALS ${projectPrefix}NO_ALIASES)
|
||||
endfunction()
|
||||
|
||||
add_example(avg_speed mp-units::core-io mp-units::si mp-units::si-cgs mp-units::si-international)
|
||||
add_example(box_example mp-units::core-fmt mp-units::si)
|
||||
add_example(capacitor_time_curve mp-units::core-io mp-units::si)
|
||||
add_example(
|
||||
clcpp_response
|
||||
mp-units::core-fmt
|
||||
mp-units::core-io
|
||||
mp-units::si
|
||||
mp-units::si-iau
|
||||
mp-units::si-imperial
|
||||
mp-units::si-international
|
||||
mp-units::si-typographic
|
||||
mp-units::si-uscs
|
||||
)
|
||||
add_example(experimental_angle mp-units::core-fmt mp-units::core-io mp-units::si)
|
||||
add_example(foot_pound_second mp-units::core-fmt mp-units::si-fps)
|
||||
add_example(total_energy mp-units::core-io mp-units::si mp-units::isq-natural)
|
||||
add_example(unknown_dimension mp-units::core-io mp-units::si)
|
||||
|
||||
if(NOT ${projectPrefix}LIBCXX)
|
||||
add_example(glide_computer_example mp-units::core-fmt mp-units::si-international glide_computer)
|
||||
target_compile_definitions(
|
||||
glide_computer_example-references PRIVATE ${projectPrefix}NO_LITERALS ${projectPrefix}NO_ALIASES
|
||||
)
|
||||
|
||||
find_package(wg21_linear_algebra CONFIG REQUIRED)
|
||||
add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si)
|
||||
target_link_libraries(linear_algebra-references PRIVATE wg21_linear_algebra::wg21_linear_algebra)
|
||||
endif()
|
@ -1,192 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/isq/si/cgs/length.h>
|
||||
#include <units/isq/si/cgs/speed.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/international/length.h>
|
||||
#include <units/isq/si/international/speed.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/length.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/speed.h>
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace units::isq;
|
||||
|
||||
constexpr si::speed<si::metre_per_second, int> fixed_int_si_avg_speed(si::length<si::metre, int> d,
|
||||
si::time<si::second, int> t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
|
||||
constexpr si::speed<si::metre_per_second> fixed_double_si_avg_speed(si::length<si::metre> d, si::time<si::second> t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
|
||||
template<typename U1, typename R1, typename U2, typename R2>
|
||||
constexpr Speed auto si_avg_speed(si::length<U1, R1> d, si::time<U2, R2> t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
|
||||
constexpr Speed auto avg_speed(Length auto d, Time auto t) { return d / t; }
|
||||
|
||||
template<Length D, Time T, Speed V>
|
||||
void print_result(D distance, T duration, V speed)
|
||||
{
|
||||
const auto result_in_kmph = units::quantity_cast<si::speed<si::kilometre_per_hour>>(speed);
|
||||
std::cout << "Average speed of a car that makes " << distance << " in " << duration << " is " << result_in_kmph
|
||||
<< ".\n";
|
||||
}
|
||||
|
||||
void example()
|
||||
{
|
||||
// SI (int)
|
||||
{
|
||||
using namespace units::isq::si::references;
|
||||
constexpr auto distance = 220 * km;
|
||||
constexpr auto duration = 2 * h;
|
||||
|
||||
std::cout << "SI units with 'int' as representation\n";
|
||||
|
||||
print_result(distance, duration, fixed_int_si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
|
||||
// SI (double)
|
||||
{
|
||||
using namespace units::isq::si::references;
|
||||
constexpr auto distance = 220. * km;
|
||||
constexpr auto duration = 2. * h;
|
||||
|
||||
std::cout << "\nSI units with 'double' as representation\n";
|
||||
|
||||
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
|
||||
print_result(distance, duration,
|
||||
fixed_int_si_avg_speed(quantity_cast<int>(distance), quantity_cast<int>(duration)));
|
||||
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
|
||||
// Customary Units (int)
|
||||
{
|
||||
using namespace units::isq::si::time_references;
|
||||
using namespace units::isq::si::international::length_references;
|
||||
constexpr auto distance = 140 * mi;
|
||||
constexpr auto duration = 2 * h;
|
||||
|
||||
std::cout << "\nUS Customary Units with 'int' as representation\n";
|
||||
|
||||
// it is not possible to make a lossless conversion of miles to meters on an integral type
|
||||
// (explicit cast needed)
|
||||
print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast<si::metre>(distance), duration));
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
|
||||
// Customary Units (double)
|
||||
{
|
||||
using namespace units::isq::si::time_references;
|
||||
using namespace units::isq::si::international::length_references;
|
||||
constexpr auto distance = 140. * mi;
|
||||
constexpr auto duration = 2. * h;
|
||||
|
||||
std::cout << "\nUS Customary Units with 'double' as representation\n";
|
||||
|
||||
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
|
||||
// also it is not possible to make a lossless conversion of miles to meters on an integral type
|
||||
// (explicit cast needed)
|
||||
print_result(
|
||||
distance, duration,
|
||||
fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
|
||||
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, si_avg_speed(distance, duration));
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
|
||||
// CGS (int)
|
||||
{
|
||||
using namespace units::isq::si::time_references;
|
||||
using namespace units::isq::si::cgs::length_references;
|
||||
constexpr auto distance = 22'000'000 * cm;
|
||||
constexpr auto duration = 2 * h;
|
||||
|
||||
std::cout << "\nCGS units with 'int' as representation\n";
|
||||
|
||||
// it is not possible to make a lossless conversion of centimeters to meters on an integral type
|
||||
// (explicit cast needed)
|
||||
print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast<si::metre>(distance), duration));
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
|
||||
// not possible to convert both a dimension and a unit with implicit cast
|
||||
print_result(distance, duration, si_avg_speed(quantity_cast<si::dim_length>(distance), duration));
|
||||
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
|
||||
// CGS (double)
|
||||
{
|
||||
using namespace units::isq::si::time_references;
|
||||
using namespace units::isq::si::cgs::length_references;
|
||||
constexpr auto distance = 22'000'000. * cm;
|
||||
constexpr auto duration = 2. * h;
|
||||
|
||||
std::cout << "\nCGS units with 'double' as representation\n";
|
||||
|
||||
// conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed
|
||||
// it is not possible to make a lossless conversion of centimeters to meters on an integral type
|
||||
// (explicit cast needed)
|
||||
print_result(
|
||||
distance, duration,
|
||||
fixed_int_si_avg_speed(quantity_cast<si::length<si::metre, int>>(distance), quantity_cast<int>(duration)));
|
||||
|
||||
print_result(distance, duration, fixed_double_si_avg_speed(distance, duration));
|
||||
|
||||
// not possible to convert both a dimension and a unit with implicit cast
|
||||
print_result(distance, duration, si_avg_speed(quantity_cast<si::dim_length>(distance), duration));
|
||||
|
||||
print_result(distance, duration, avg_speed(distance, duration));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
example();
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
|
||||
} catch (...) {
|
||||
std::cerr << "Unhandled unknown exception caught\n";
|
||||
}
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/format.h>
|
||||
#include <units/generic/dimensionless.h>
|
||||
#include <units/isq/si/amount_of_substance.h>
|
||||
#include <units/isq/si/area.h>
|
||||
#include <units/isq/si/constants.h>
|
||||
#include <units/isq/si/density.h>
|
||||
#include <units/isq/si/force.h>
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/mass.h>
|
||||
#include <units/isq/si/speed.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/isq/si/volume.h>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace units::isq;
|
||||
using namespace si::mass_references;
|
||||
using namespace si::volume_references;
|
||||
|
||||
inline constexpr Acceleration auto g = si::si2019::standard_gravity<>;
|
||||
inline constexpr Density auto air_density = 1.225 * (kg / m3);
|
||||
|
||||
class Box {
|
||||
si::area<si::square_metre> base_;
|
||||
si::length<si::metre> height_;
|
||||
si::density<si::kilogram_per_metre_cub> density_ = air_density;
|
||||
public:
|
||||
constexpr Box(const si::length<si::metre>& length, const si::length<si::metre>& width, si::length<si::metre> height) :
|
||||
base_(length * width), height_(std::move(height))
|
||||
{
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr si::force<si::newton> filled_weight() const
|
||||
{
|
||||
const Volume auto volume = base_ * height_;
|
||||
const Mass auto mass = density_ * volume;
|
||||
return mass * g;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr si::length<si::metre> fill_level(const si::mass<si::kilogram>& measured_mass) const
|
||||
{
|
||||
return height_ * measured_mass * g / filled_weight();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr si::volume<si::cubic_metre> spare_capacity(const si::mass<si::kilogram>& measured_mass) const
|
||||
{
|
||||
return (height_ - fill_level(measured_mass)) * base_;
|
||||
}
|
||||
|
||||
constexpr void set_contents_density(const si::density<si::kilogram_per_metre_cub>& density_in)
|
||||
{
|
||||
assert(density_in > air_density);
|
||||
density_ = density_in;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace units;
|
||||
using namespace units::isq::si;
|
||||
using namespace length_references;
|
||||
using namespace time_references;
|
||||
|
||||
const auto height = quantity_cast<metre>(200.0 * mm);
|
||||
auto box = Box(1000.0 * mm, 500.0 * mm, height);
|
||||
box.set_contents_density(1000.0 * (kg / m3));
|
||||
|
||||
const auto fill_time = 200.0 * s; // time since starting fill
|
||||
const auto measured_mass = 20.0 * kg; // measured mass at fill_time
|
||||
|
||||
const Length auto fill_level = box.fill_level(measured_mass);
|
||||
const Dimensionless auto fill_percent = quantity_cast<percent>(fill_level / height);
|
||||
const Volume auto spare_capacity = box.spare_capacity(measured_mass);
|
||||
const auto input_flow_rate = measured_mass / fill_time; // unknown dimension
|
||||
const Speed auto float_rise_rate = fill_level / fill_time;
|
||||
const Time auto fill_time_left = (height / fill_level - 1) * fill_time;
|
||||
|
||||
std::cout << "mp-units box example...\n";
|
||||
std::cout << STD_FMT::format("fill height at {} = {} ({} full)\n", fill_time, fill_level, fill_percent);
|
||||
std::cout << STD_FMT::format("spare_capacity at {} = {}\n", fill_time, spare_capacity);
|
||||
std::cout << STD_FMT::format("input flow rate after {} = {}\n", fill_time, input_flow_rate);
|
||||
std::cout << STD_FMT::format("float rise rate = {}\n", float_rise_rate);
|
||||
std::cout << STD_FMT::format("box full E.T.A. at current flow rate = {}\n", fill_time_left);
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2003-2020 Andy Little.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses./
|
||||
*/
|
||||
|
||||
/*
|
||||
capacitor discharge curve using compile_time
|
||||
physical_quantities
|
||||
*/
|
||||
|
||||
#include <units/generic/dimensionless.h>
|
||||
#include <units/isq/dimensions/electric_current.h>
|
||||
#include <units/isq/si/capacitance.h>
|
||||
#include <units/isq/si/resistance.h>
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/isq/si/voltage.h>
|
||||
#include <units/math.h> // IWYU pragma: keep
|
||||
#include <units/quantity_io.h>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace units::isq;
|
||||
using namespace units::isq::si::capacitance_references;
|
||||
using namespace units::isq::si::voltage_references;
|
||||
using namespace units::isq::si::resistance_references;
|
||||
using namespace units::isq::si::time_references;
|
||||
|
||||
std::cout << "mp-units capacitor time curve example...\n";
|
||||
std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
|
||||
std::cout.precision(3);
|
||||
|
||||
constexpr auto C = 0.47 * uF;
|
||||
constexpr auto V0 = 5.0 * V;
|
||||
constexpr auto RR = 4.7 * kR; // cannot use just 'R' here
|
||||
|
||||
for (auto t = 0 * ms; t <= 50 * ms; ++t) {
|
||||
const Voltage auto Vt = V0 * units::exp(-t / (RR * C));
|
||||
|
||||
std::cout << "at " << t << " voltage is ";
|
||||
|
||||
if (Vt >= 1 * V)
|
||||
std::cout << Vt;
|
||||
else if (Vt >= 1 * mV)
|
||||
std::cout << quantity_cast<si::millivolt>(Vt);
|
||||
else if (Vt >= 1 * uV)
|
||||
std::cout << quantity_cast<si::microvolt>(Vt);
|
||||
else if (Vt >= 1 * nV)
|
||||
std::cout << quantity_cast<si::nanovolt>(Vt);
|
||||
else
|
||||
std::cout << quantity_cast<si::picovolt>(Vt);
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2003-2019 Andy Little.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses./
|
||||
*/
|
||||
|
||||
#include <units/format.h>
|
||||
#include <units/isq/si/area.h>
|
||||
#include <units/isq/si/iau/length.h>
|
||||
#include <units/isq/si/imperial/length.h>
|
||||
#include <units/isq/si/international/length.h>
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/isq/si/typographic/length.h>
|
||||
#include <units/isq/si/uscs/length.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
void simple_quantities()
|
||||
{
|
||||
using namespace units::isq;
|
||||
using namespace units::isq::si;
|
||||
using namespace units::isq::si::references;
|
||||
using namespace units::isq::si::international::references;
|
||||
|
||||
using distance = si::length<si::metre>;
|
||||
using duration = si::time<si::second>;
|
||||
|
||||
UNITS_DIAGNOSTIC_PUSH
|
||||
UNITS_DIAGNOSTIC_IGNORE_SHADOW
|
||||
constexpr distance km = 1.0 * references::km;
|
||||
constexpr distance miles = 1.0 * mi;
|
||||
|
||||
constexpr duration sec = 1 * s;
|
||||
constexpr duration min = 1 * references::min;
|
||||
constexpr duration hr = 1 * h;
|
||||
UNITS_DIAGNOSTIC_POP
|
||||
|
||||
std::cout << "A physical quantities library can choose the simple\n";
|
||||
std::cout << "option to provide output using a single type for each base unit:\n\n";
|
||||
std::cout << km << '\n';
|
||||
std::cout << miles << '\n';
|
||||
std::cout << sec << '\n';
|
||||
std::cout << min << '\n';
|
||||
std::cout << hr << "\n\n";
|
||||
}
|
||||
|
||||
void quantities_with_typed_units()
|
||||
{
|
||||
using namespace units::isq;
|
||||
using namespace units::isq::si;
|
||||
using namespace units::isq::si::references;
|
||||
using namespace units::isq::si::international;
|
||||
using namespace units::isq::si::international::references;
|
||||
|
||||
UNITS_DIAGNOSTIC_PUSH
|
||||
UNITS_DIAGNOSTIC_IGNORE_SHADOW
|
||||
constexpr length<kilometre> km = 1.0 * si::references::km;
|
||||
constexpr length<mile> miles = 1.0 * mi;
|
||||
|
||||
std::cout.precision(6);
|
||||
|
||||
constexpr si::time<second> sec = 1 * s;
|
||||
constexpr si::time<minute> min = 1 * si::references::min;
|
||||
constexpr si::time<hour> hr = 1 * h;
|
||||
UNITS_DIAGNOSTIC_POP
|
||||
|
||||
std::cout << "A more flexible option is to provide separate types for each unit,\n\n";
|
||||
std::cout << km << '\n';
|
||||
std::cout << miles << '\n';
|
||||
std::cout << sec << '\n';
|
||||
std::cout << min << '\n';
|
||||
std::cout << hr << "\n\n";
|
||||
|
||||
constexpr auto meter = 1 * m;
|
||||
std::cout << "then a wide range of pre-defined units can be defined and converted,\n"
|
||||
" for consistency and repeatability across applications:\n\n";
|
||||
|
||||
std::cout << meter << '\n';
|
||||
|
||||
std::cout << " = " << quantity_cast<si::astronomical_unit>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::iau::angstrom>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::imperial::chain>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::international::fathom>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::uscs::fathom>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::international::foot>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::uscs::foot>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::international::inch>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::iau::light_year>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::international::mile>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::international::nautical_mile>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::iau::parsec>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::typographic::pica_comp>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::typographic::pica_prn>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::typographic::point_comp>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::typographic::point_prn>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::imperial::rod>(meter) << '\n';
|
||||
std::cout << " = " << quantity_cast<si::international::yard>(meter) << '\n';
|
||||
}
|
||||
|
||||
void calcs_comparison()
|
||||
{
|
||||
using namespace units::isq::si;
|
||||
using namespace units::isq::si::references;
|
||||
|
||||
std::cout << "\nA distinct unit for each type is efficient and accurate\n"
|
||||
"when adding two values of the same very big\n"
|
||||
"or very small type:\n\n";
|
||||
|
||||
const length<femtometre, float> L1A = 2.f * fm;
|
||||
const length<femtometre, float> L2A = 3.f * fm;
|
||||
const length<femtometre, float> LrA = L1A + L2A;
|
||||
std::cout << STD_FMT::format("{:%.30Q %q}\n + {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, LrA);
|
||||
|
||||
std::cout << "The single unit method must convert large\n"
|
||||
"or small values in other units to the base unit.\n"
|
||||
"This is both inefficient and inaccurate\n\n";
|
||||
|
||||
const length<metre, float> L1B = L1A;
|
||||
const length<metre, float> L2B = L2A;
|
||||
const length<metre, float> LrB = L1B + L2B;
|
||||
std::cout << STD_FMT::format("{:%.30Q %q}\n + {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1B, L2B, LrB);
|
||||
|
||||
std::cout << "In multiplication and division:\n\n";
|
||||
|
||||
const area<square_femtometre, float> ArA = L1A * L2A;
|
||||
std::cout << STD_FMT::format("{:%.30Q %q}\n * {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, ArA);
|
||||
|
||||
std::cout << "similar problems arise\n\n";
|
||||
|
||||
const area<square_metre, float> ArB = L1B * L2B;
|
||||
std::cout << STD_FMT::format("{:%.30Q %q}\n * {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1B, L2B, ArB);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "This demo was originally posted on com.lang.c++.moderated in 2006\n";
|
||||
std::cout << "http://compgroups.net/comp.lang.c++.moderated/dimensional-analysis-units/51712\n";
|
||||
std::cout << "Here converted to use mp-units library.\n\n";
|
||||
|
||||
simple_quantities();
|
||||
quantities_with_typed_units();
|
||||
calcs_comparison();
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/bits/external/hacks.h> // IWYU pragma: keep
|
||||
|
||||
UNITS_DIAGNOSTIC_PUSH
|
||||
UNITS_DIAGNOSTIC_IGNORE_SHADOW
|
||||
#include <units/isq/si/force.h> // 'N' (Newton) shadows a template parameter traditionally used as a size of the array
|
||||
UNITS_DIAGNOSTIC_POP
|
||||
|
||||
#include <units/generic/angle.h>
|
||||
#include <units/isq/si/energy.h>
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/torque.h> // IWYU pragma: keep
|
||||
#include <units/quantity_io.h>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace units;
|
||||
using namespace units::isq;
|
||||
using namespace units::isq::si::references;
|
||||
using namespace units::references;
|
||||
|
||||
Torque auto torque = 20.0 / std::numbers::pi * (N * m / rad);
|
||||
Energy auto energy = 20.0 * J;
|
||||
|
||||
Angle auto angle = energy / torque;
|
||||
|
||||
std::cout << angle << '\n';
|
||||
std::cout << quantity_cast<revolution>(angle) << '\n';
|
||||
std::cout << quantity_cast<degree>(angle) << '\n';
|
||||
std::cout << quantity_cast<gradian>(angle) << '\n';
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/format.h>
|
||||
#include <units/isq/si/fps/density.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/fps/length.h>
|
||||
#include <units/isq/si/fps/mass.h>
|
||||
#include <units/isq/si/fps/power.h>
|
||||
#include <units/isq/si/fps/speed.h>
|
||||
#include <units/isq/si/fps/time.h>
|
||||
#include <units/isq/si/fps/volume.h>
|
||||
#include <units/isq/si/international/speed.h>
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/mass.h>
|
||||
#include <units/isq/si/power.h>
|
||||
#include <units/isq/si/speed.h>
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/isq/si/volume.h>
|
||||
#include <iostream>
|
||||
#include <string_view>
|
||||
|
||||
using namespace units::isq;
|
||||
|
||||
|
||||
// Some basic specs for the warship
|
||||
struct Ship {
|
||||
si::fps::length<si::fps::foot> length;
|
||||
si::fps::length<si::fps::foot> draft;
|
||||
si::fps::length<si::fps::foot> beam;
|
||||
|
||||
si::fps::speed<si::fps::foot_per_second> speed;
|
||||
si::fps::mass<si::fps::pound> mass;
|
||||
|
||||
si::fps::length<si::fps::inch> mainGuns;
|
||||
si::fps::mass<si::fps::pound> shellMass;
|
||||
si::fps::speed<si::fps::foot_per_second> shellSpeed;
|
||||
si::fps::power<si::fps::foot_poundal_per_second> power;
|
||||
};
|
||||
|
||||
// Print 'a' in its current units and print its value cast to the units in each of Args
|
||||
template<class... Args, units::Quantity Q>
|
||||
auto fmt_line(const Q a)
|
||||
{
|
||||
return STD_FMT::format("{:22}", a) + (STD_FMT::format(",{:20}", units::quantity_cast<Args>(a)) + ...);
|
||||
}
|
||||
|
||||
// Print the ship details in the units as defined in the Ship struct, in other si::imperial units, and in SI
|
||||
void print_details(std::string_view description, const Ship& ship)
|
||||
{
|
||||
using namespace units::isq::si::fps::references;
|
||||
const auto waterDensity = 62.4 * (lb / ft3);
|
||||
std::cout << STD_FMT::format("{}\n", description);
|
||||
std::cout << STD_FMT::format("{:20} : {}\n", "length",
|
||||
fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.length))
|
||||
<< STD_FMT::format("{:20} : {}\n", "draft",
|
||||
fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.draft))
|
||||
<< STD_FMT::format("{:20} : {}\n", "beam",
|
||||
fmt_line<si::fps::length<si::fps::yard>, si::length<si::metre>>(ship.beam))
|
||||
<< STD_FMT::format("{:20} : {}\n", "mass",
|
||||
fmt_line<si::fps::mass<si::fps::long_ton>, si::mass<si::tonne>>(ship.mass))
|
||||
<< STD_FMT::format(
|
||||
"{:20} : {}\n", "speed",
|
||||
fmt_line<si::speed<si::international::knot>, si::speed<si::kilometre_per_hour>>(ship.speed))
|
||||
<< STD_FMT::format("{:20} : {}\n", "power",
|
||||
fmt_line<si::fps::power<si::fps::horse_power>, si::power<si::kilowatt>>(ship.power))
|
||||
<< STD_FMT::format("{:20} : {}\n", "main guns",
|
||||
fmt_line<si::fps::length<si::fps::inch>, si::length<si::millimetre>>(ship.mainGuns))
|
||||
<< STD_FMT::format("{:20} : {}\n", "fire shells weighing",
|
||||
fmt_line<si::fps::mass<si::fps::long_ton>, si::mass<si::kilogram>>(ship.shellMass))
|
||||
<< STD_FMT::format(
|
||||
"{:20} : {}\n", "fire shells at",
|
||||
fmt_line<si::fps::speed<si::fps::mile_per_hour>, si::speed<si::kilometre_per_hour>>(ship.shellSpeed))
|
||||
<< STD_FMT::format("{:20} : {}\n", "volume underwater",
|
||||
fmt_line<si::volume<si::cubic_metre>, si::volume<si::litre>>(ship.mass / waterDensity));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace units::isq::si::references;
|
||||
using namespace units::isq::si::fps::references;
|
||||
using units::isq::si::fps::references::ft; // collides with si::femtotonne (alias unit of mass)
|
||||
|
||||
// KMS Bismark, using the units the Germans would use, taken from Wiki
|
||||
auto bismark = Ship{.length{251. * m},
|
||||
.draft{9.3 * m},
|
||||
.beam{36 * m},
|
||||
.speed{56 * (km / h)},
|
||||
.mass{50'300 * t},
|
||||
.mainGuns{380 * mm},
|
||||
.shellMass{800 * kg},
|
||||
.shellSpeed{820. * (m / s)},
|
||||
.power{110.45 * kW}};
|
||||
|
||||
// USS Iowa, using units from the foot-pound-second system
|
||||
auto iowa = Ship{.length{860. * ft},
|
||||
.draft{37. * ft + 2. * in},
|
||||
.beam{108. * ft + 2. * in},
|
||||
.speed{33 * units::isq::si::international::references::kn},
|
||||
.mass{57'540 * lton},
|
||||
.mainGuns{16 * in},
|
||||
.shellMass{2700 * lb},
|
||||
.shellSpeed{2690. * (ft / s)},
|
||||
.power{212'000 * hp}};
|
||||
|
||||
// HMS King George V, using units from the foot-pound-second system
|
||||
auto kgv = Ship{.length{745.1 * ft},
|
||||
.draft{33. * ft + 7.5 * in},
|
||||
.beam{103.2 * ft + 2.5 * in},
|
||||
.speed{28.3 * units::isq::si::international::references::kn},
|
||||
.mass{42'245 * lton},
|
||||
.mainGuns{14 * in},
|
||||
.shellMass{1'590 * lb},
|
||||
.shellSpeed{2483. * (ft / s)},
|
||||
.power{110'000 * hp}};
|
||||
|
||||
print_details("KMS Bismark, defined in appropriate units from the SI system", bismark);
|
||||
std::cout << "\n\n";
|
||||
print_details("USS Iowa, defined in appropriate units foot-pound-second system", iowa);
|
||||
std::cout << "\n\n";
|
||||
print_details("HMS King George V, defined in appropriate units foot-pound-second system", kgv);
|
||||
}
|
@ -1,201 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include "glide_computer.h"
|
||||
#include <units/bits/fmt_hacks.h>
|
||||
#include <units/chrono.h>
|
||||
#include <units/generic/angle.h>
|
||||
#include <units/generic/dimensionless.h>
|
||||
#include <units/isq/si/international/length.h>
|
||||
#include <array>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace glide_computer;
|
||||
|
||||
using namespace units::isq;
|
||||
|
||||
auto get_gliders()
|
||||
{
|
||||
using namespace si::references;
|
||||
UNITS_DIAGNOSTIC_PUSH
|
||||
UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES
|
||||
static const std::array gliders = {
|
||||
glider{"SZD-30 Pirat", {velocity(83 * (km / h)), rate_of_climb(-0.7389 * (m / s))}},
|
||||
glider{"SZD-51 Junior", {velocity(80 * (km / h)), rate_of_climb(-0.6349 * (m / s))}},
|
||||
glider{"SZD-48 Jantar Std 3", {velocity(110 * (km / h)), rate_of_climb(-0.77355 * (m / s))}},
|
||||
glider{"SZD-56 Diana", {velocity(110 * (km / h)), rate_of_climb(-0.63657 * (m / s))}}};
|
||||
UNITS_DIAGNOSTIC_POP
|
||||
return gliders;
|
||||
}
|
||||
|
||||
auto get_weather_conditions()
|
||||
{
|
||||
using namespace si::references;
|
||||
static const std::array weather_conditions = {
|
||||
std::pair("Good", weather{height(1900 * m), rate_of_climb(4.3 * (m / s))}),
|
||||
std::pair("Medium", weather{height(1550 * m), rate_of_climb(2.8 * (m / s))}),
|
||||
std::pair("Bad", weather{height(850 * m), rate_of_climb(1.8 * (m / s))})};
|
||||
return weather_conditions;
|
||||
}
|
||||
|
||||
auto get_waypoints()
|
||||
{
|
||||
using namespace geographic::literals;
|
||||
using namespace units::isq::si::international::references;
|
||||
static const std::array waypoints = {
|
||||
waypoint{"EPPR", {54.24772_N, 18.6745_E}, altitude(16 * ft)}, // N54°14'51.8" E18°40'28.2"
|
||||
waypoint{"EPGI", {53.52442_N, 18.84947_E}, altitude(115 * ft)} // N53°31'27.9" E18°50'58.1"
|
||||
};
|
||||
return waypoints;
|
||||
}
|
||||
|
||||
template<std::ranges::input_range R>
|
||||
requires(std::same_as<std::ranges::range_value_t<R>, glider>)
|
||||
void print(const R& gliders)
|
||||
{
|
||||
std::cout << "Gliders:\n";
|
||||
std::cout << "========\n";
|
||||
for (const auto& g : gliders) {
|
||||
std::cout << "- Name: " << g.name << "\n";
|
||||
std::cout << "- Polar:\n";
|
||||
for (const auto& p : g.polar) {
|
||||
const auto ratio = units::quantity_cast<units::one>(glide_ratio(g.polar[0]));
|
||||
std::cout << STD_FMT::format(" * {:%.4Q %q} @ {:%.1Q %q} -> {:%.1Q %q} ({:%.1Q %q})\n", p.climb, p.v, ratio,
|
||||
units::quantity_cast<units::degree>(asin(1 / ratio)));
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
template<std::ranges::input_range R>
|
||||
requires(std::same_as<std::ranges::range_value_t<R>, std::pair<const char*, weather>>)
|
||||
void print(const R& conditions)
|
||||
{
|
||||
std::cout << "Weather:\n";
|
||||
std::cout << "========\n";
|
||||
for (const auto& c : conditions) {
|
||||
std::cout << "- " << c.first << "\n";
|
||||
const auto& w = c.second;
|
||||
std::cout << " * Cloud base: " << STD_FMT::format("{:%.0Q %q}", w.cloud_base) << " AGL\n";
|
||||
std::cout << " * Thermals strength: " << STD_FMT::format("{:%.1Q %q}", w.thermal_strength) << "\n";
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
template<std::ranges::input_range R>
|
||||
requires(std::same_as<std::ranges::range_value_t<R>, waypoint>)
|
||||
void print(const R& waypoints)
|
||||
{
|
||||
std::cout << "Waypoints:\n";
|
||||
std::cout << "==========\n";
|
||||
for (const auto& w : waypoints)
|
||||
std::cout << STD_FMT::format("- {}: {} {}, {:%.1Q %q}\n", w.name, w.pos.lat, w.pos.lon, w.alt);
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void print(const task& t)
|
||||
{
|
||||
std::cout << "Task:\n";
|
||||
std::cout << "=====\n";
|
||||
|
||||
std::cout << "- Start: " << t.get_start().name << "\n";
|
||||
std::cout << "- Finish: " << t.get_finish().name << "\n";
|
||||
std::cout << "- Length: " << STD_FMT::format("{:%.1Q %q}", t.get_length()) << "\n";
|
||||
|
||||
std::cout << "- Legs: "
|
||||
<< "\n";
|
||||
for (const auto& l : t.get_legs())
|
||||
std::cout << STD_FMT::format(" * {} -> {} ({:%.1Q %q})\n", l.begin().name, l.end().name, l.get_length());
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void print(const safety& s)
|
||||
{
|
||||
std::cout << "Safety:\n";
|
||||
std::cout << "=======\n";
|
||||
std::cout << "- Min AGL separation: " << STD_FMT::format("{:%.0Q %q}", s.min_agl_height) << "\n";
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void print(const aircraft_tow& tow)
|
||||
{
|
||||
std::cout << "Tow:\n";
|
||||
std::cout << "====\n";
|
||||
std::cout << "- Type: aircraft\n";
|
||||
std::cout << "- Height: " << STD_FMT::format("{:%.0Q %q}", tow.height_agl) << "\n";
|
||||
std::cout << "- Performance: " << STD_FMT::format("{:%.1Q %q}", tow.performance) << "\n";
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void example()
|
||||
{
|
||||
using namespace si::references;
|
||||
|
||||
const safety sfty = {height(300 * m)};
|
||||
const auto gliders = get_gliders();
|
||||
const auto waypoints = get_waypoints();
|
||||
const auto weather_conditions = get_weather_conditions();
|
||||
const task t = {waypoints[0], waypoints[1], waypoints[0]};
|
||||
const aircraft_tow tow = {height(400 * m), rate_of_climb(1.6 * (m / s))};
|
||||
// TODO use C++20 date library when available
|
||||
// set `start_time` to 11:00 am today
|
||||
const timestamp start_time(std::chrono::system_clock::now());
|
||||
|
||||
print(sfty);
|
||||
print(gliders);
|
||||
print(waypoints);
|
||||
print(weather_conditions);
|
||||
print(t);
|
||||
print(tow);
|
||||
|
||||
for (const auto& g : gliders) {
|
||||
for (const auto& c : weather_conditions) {
|
||||
std::string txt = "Scenario: Glider = " + g.name + ", Weather = " + c.first;
|
||||
std::cout << txt << "\n";
|
||||
std::cout << STD_FMT::format("{0:=^{1}}\n\n", "", txt.size());
|
||||
|
||||
estimate(start_time, g, c.second, t, sfty, tow);
|
||||
|
||||
std::cout << "\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
example();
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
|
||||
} catch (...) {
|
||||
std::cerr << "Unhandled unknown exception caught\n";
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/isq/natural/natural.h>
|
||||
#include <units/isq/si/constants.h>
|
||||
#include <units/isq/si/energy.h>
|
||||
#include <units/isq/si/mass.h>
|
||||
#include <units/isq/si/momentum.h>
|
||||
#include <units/isq/si/speed.h> // IWYU pragma: keep
|
||||
#include <units/math.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace units::isq;
|
||||
|
||||
Energy auto total_energy(Momentum auto p, Mass auto m, Speed auto c)
|
||||
{
|
||||
return sqrt(pow<2>(p * c) + pow<2>(m * pow<2>(c)));
|
||||
}
|
||||
|
||||
void si_example()
|
||||
{
|
||||
using namespace units::isq::si;
|
||||
using namespace units::isq::si::energy_references;
|
||||
|
||||
constexpr Speed auto c = si2019::speed_of_light<>;
|
||||
|
||||
std::cout << "\n*** SI units (c = " << c << ") ***\n";
|
||||
|
||||
const Momentum auto p = 4. * GeV / c;
|
||||
const Mass auto m = 3. * GeV / pow<2>(c);
|
||||
const Energy auto E = total_energy(p, m, c);
|
||||
|
||||
std::cout << "[in GeV]\n"
|
||||
<< "p = " << p << "\n"
|
||||
<< "m = " << m << "\n"
|
||||
<< "E = " << E << "\n";
|
||||
|
||||
const momentum<kilogram_metre_per_second> p_si = p;
|
||||
const mass<kilogram> m_si = m;
|
||||
const energy<joule> E_si = total_energy(p_si, m_si, c);
|
||||
|
||||
std::cout << "\n[in SI units]\n"
|
||||
<< "p = " << p_si << "\n"
|
||||
<< "m = " << m_si << "\n"
|
||||
<< "E = " << E_si << "\n";
|
||||
|
||||
std::cout << "\n[converted from SI units back to GeV]\n"
|
||||
<< "E = " << quantity_cast<gigaelectronvolt>(E_si) << "\n";
|
||||
}
|
||||
|
||||
void natural_example()
|
||||
{
|
||||
using namespace units::isq::natural;
|
||||
using namespace units::isq::natural::references;
|
||||
|
||||
constexpr Speed auto c = speed_of_light<>;
|
||||
const auto p = 4. * momentum_references::GeV;
|
||||
const auto m = 3. * mass_references::GeV;
|
||||
const Energy auto E = total_energy(p, m, c);
|
||||
|
||||
std::cout << "\n*** Natural units (c = " << c << ") ***\n"
|
||||
<< "p = " << p << "\n"
|
||||
<< "m = " << m << "\n"
|
||||
<< "E = " << E << "\n";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
si_example();
|
||||
natural_example();
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
|
||||
} catch (...) {
|
||||
std::cerr << "Unhandled unknown exception caught\n";
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/isq/si/length.h>
|
||||
#include <units/isq/si/speed.h> // IWYU pragma: keep
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
template<units::isq::Length D, units::isq::Time T>
|
||||
constexpr units::isq::Speed auto avg_speed(D d, T t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
|
||||
void example()
|
||||
{
|
||||
using namespace units::isq;
|
||||
using namespace units::isq::si::references;
|
||||
|
||||
Length auto d1 = 123 * m;
|
||||
Time auto t1 = 10 * s;
|
||||
Speed auto v1 = avg_speed(d1, t1);
|
||||
|
||||
auto temp1 =
|
||||
v1 * (50 * m); // produces intermediate unknown dimension with 'unknown_coherent_unit' as its 'coherent_unit'
|
||||
Speed auto v2 = temp1 / (100 * m); // back to known dimensions again
|
||||
Length auto d2 = v2 * (60 * s);
|
||||
|
||||
std::cout << "d1 = " << d1 << '\n';
|
||||
std::cout << "t1 = " << t1 << '\n';
|
||||
std::cout << "v1 = " << v1 << '\n';
|
||||
std::cout << "temp1 = " << temp1 << '\n';
|
||||
std::cout << "v2 = " << v2 << '\n';
|
||||
std::cout << "d2 = " << d2 << '\n';
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
example();
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Unhandled std exception caught: " << ex.what() << '\n';
|
||||
} catch (...) {
|
||||
std::cerr << "Unhandled unknown exception caught\n";
|
||||
}
|
||||
}
|
@ -21,20 +21,30 @@
|
||||
// SOFTWARE.
|
||||
|
||||
#include <units/format.h>
|
||||
#include <units/isq/si/constants.h>
|
||||
#include <units/si/constants.h>
|
||||
#include <units/si/unit_symbols.h>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace units::isq::si::si2019;
|
||||
using namespace units::si;
|
||||
using namespace units::si::unit_symbols;
|
||||
|
||||
std::cout << "The seven defining constants of the SI and the seven corresponding units they define:\n";
|
||||
std::cout << STD_FMT::format("- hyperfine transition frequency of Cs: {:%.0Q %q}\n",
|
||||
hyperfine_structure_transition_frequency<>);
|
||||
std::cout << STD_FMT::format("- speed of light in vacuum: {:%.0Q %q}\n", speed_of_light<>);
|
||||
std::cout << STD_FMT::format("- Planck constant: {}\n", planck_constant<>);
|
||||
std::cout << STD_FMT::format("- elementary charge: {}\n", elementary_charge<>);
|
||||
std::cout << STD_FMT::format("- Boltzmann constant: {}\n", boltzmann_constant<>);
|
||||
std::cout << STD_FMT::format("- Avogadro constant: {}\n", avogadro_constant<>);
|
||||
std::cout << STD_FMT::format("- luminous efficacy: {}\n", luminous_efficacy<>);
|
||||
std::cout << STD_FMT::format("- hyperfine transition frequency of Cs: {} = {:%.0Q %q}\n",
|
||||
1. * si2019::hyperfine_structure_transition_frequency_of_cs,
|
||||
(1. * si2019::hyperfine_structure_transition_frequency_of_cs)[Hz]);
|
||||
std::cout << STD_FMT::format("- speed of light in vacuum: {} = {:%.0Q %q}\n",
|
||||
1. * si2019::speed_of_light_in_vacuum, (1. * si2019::speed_of_light_in_vacuum)[m / s]);
|
||||
std::cout << STD_FMT::format("- Planck constant: {} = {:%.8eQ %q}\n",
|
||||
1. * si2019::planck_constant, (1. * si2019::planck_constant)[J * s]);
|
||||
// TODO uncomment the below when ISQ is done
|
||||
// std::cout << STD_FMT::format("- elementary charge: {} = {:%.9eQ %q}\n",
|
||||
// 1. * si2019::elementary_charge, (1. * si2019::elementary_charge)[C]);
|
||||
// std::cout << STD_FMT::format("- Boltzmann constant: {} = {:%.6eQ %q}\n",
|
||||
// 1. * si2019::boltzmann_constant, (1. * si2019::boltzmann_constant)[J / K]);
|
||||
std::cout << STD_FMT::format("- Avogadro constant: {} = {:%.8eQ %q}\n",
|
||||
1. * si2019::avogadro_constant, (1. * si2019::avogadro_constant)[1 / mol]);
|
||||
// std::cout << STD_FMT::format("- luminous efficacy: {} = {}\n", 1. * si2019::luminous_efficacy,
|
||||
// (1. * si2019::luminous_efficacy)[lm / W]);
|
||||
}
|
||||
|
Reference in New Issue
Block a user