diff --git a/test/unit_test/static/CMakeLists.txt b/test/unit_test/static/CMakeLists.txt index 1258f6f2..f5135edb 100644 --- a/test/unit_test/static/CMakeLists.txt +++ b/test/unit_test/static/CMakeLists.txt @@ -23,15 +23,11 @@ cmake_minimum_required(VERSION 3.2) add_library(unit_tests_static_truncating quantity_test.cpp) - -# if(NOT ${projectPrefix}LIBCXX) -# target_sources(unit_tests_static_truncating PRIVATE quantity_kind_test.cpp quantity_point_kind_test.cpp) -# endif() - target_link_libraries(unit_tests_static_truncating PRIVATE mp-units::mp-units) target_compile_options( unit_tests_static_truncating PRIVATE $,/wd4242 /wd4244,-Wno-conversion> ) + add_library( unit_tests_static angular_test.cpp @@ -49,7 +45,6 @@ add_library( international_test.cpp isq_test.cpp isq_angle_test.cpp - # kind_test.cpp # magnitude_test.cpp # math_test.cpp natural_test.cpp diff --git a/test/unit_test/static/kind_test.cpp b/test/unit_test/static/kind_test.cpp deleted file mode 100644 index 0c79059c..00000000 --- a/test/unit_test/static/kind_test.cpp +++ /dev/null @@ -1,206 +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 "test_tools.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace units; -using namespace isq::si; - -namespace { - -template -using downcast_result = std::conditional_t>; - - -// no library-defined base kind - - -// spherical coordinates -struct radius : kind {}; // program-defined base kind -struct colatitude : kind> {}; -struct azimuth : kind> {}; - -static_assert(Kind); -static_assert(Kind); -static_assert(Kind); -static_assert(Kind); -static_assert(Kind); - -static_assert(!PointKind); -static_assert(!PointKind); -static_assert(!PointKind); -static_assert(!PointKind); -static_assert(!PointKind); - -static_assert(is_same_v); -static_assert(is_same_v); -static_assert(compare, downcast_kind>); - -static_assert(equivalent); -static_assert(equivalent); -static_assert(equivalent); -static_assert(equivalent); -static_assert(equivalent); -static_assert(!equivalent); -static_assert(!equivalent); -static_assert(!equivalent); -static_assert(!equivalent); -static_assert(!equivalent); -static_assert(!equivalent>); -static_assert(!equivalent>); - -using radial_area = downcast_kind; // library-defined derived kind -using radial_point = downcast_point_kind; // library-defined base point kind - -static_assert(Kind); -static_assert(!PointKind); - -static_assert(is_same_v); -static_assert(is_same_v); -static_assert(is_same_v>); -static_assert(is_same_v>); -static_assert(is_same_v>); - -static_assert(equivalent); -static_assert(!equivalent); -static_assert(!equivalent); - -static_assert(!Kind); -static_assert(PointKind); - -static_assert(is_same_v); -static_assert(is_same_v); -static_assert(is_same_v>); - -static_assert(equivalent); -static_assert(!equivalent); -static_assert(!equivalent); - -static_assert(equivalent>); -static_assert(!equivalent); -static_assert(!equivalent); - - -struct width : kind {}; -using horizontal_speed = downcast_kind; - -struct abscissa : point_kind {}; // program-defined base point kind -using horizontal_velocity = downcast_point_kind>; // library-defined derived point kind - -static_assert(!Kind); -static_assert(!Kind); -static_assert(!Kind); -static_assert(PointKind); -static_assert(PointKind); -static_assert(PointKind); - -static_assert(is_same_v); -static_assert(is_same_v); -static_assert(compare, downcast_point_kind>); - -static_assert(equivalent); -static_assert(equivalent); -static_assert(equivalent); -static_assert(!equivalent); -static_assert(!equivalent); - -static_assert(!Kind); -static_assert(PointKind); - -static_assert(is_same_v); -static_assert(is_same_v); -static_assert(is_same_v>); - -static_assert(equivalent); -static_assert(!equivalent); -static_assert(!equivalent); -static_assert(!equivalent); - -static_assert(!equivalent); -static_assert(!equivalent); - - -struct height : kind {}; - -struct rate_of_climb : derived_kind {}; // program-defined derived kind -struct velocity_of_climb : point_kind {}; // program-defined derived point kind - -static_assert(Kind); -static_assert(Kind); -static_assert(Kind); -static_assert(!PointKind); -static_assert(!PointKind); -static_assert(!PointKind); - -static_assert(is_same_v); -static_assert(is_same_v); -static_assert(compare, downcast_kind>); -static_assert(compare, downcast_kind>); - -static_assert(equivalent); -static_assert(equivalent); -static_assert(equivalent); -static_assert(equivalent); -static_assert(!equivalent); -static_assert(!equivalent); - -static_assert(!Kind); -static_assert(!Kind); -static_assert(!Kind); -static_assert(PointKind); -static_assert(PointKind); -static_assert(PointKind); - -static_assert(is_same_v); -static_assert(is_same_v); -static_assert(compare, downcast_point_kind>); - -static_assert(equivalent); -static_assert(equivalent); -static_assert(equivalent); -static_assert(equivalent); -static_assert(equivalent); - -static_assert(!equivalent); -static_assert(!equivalent); -static_assert(!equivalent); - -static_assert(!equivalent); -static_assert(!equivalent); -static_assert(!equivalent); - -static_assert(!equivalent); -static_assert(!equivalent); - -static_assert(compare, downcast_kind>); - -} // namespace diff --git a/test/unit_test/static/point_origin_test.cpp b/test/unit_test/static/point_origin_test.cpp deleted file mode 100644 index b302d58a..00000000 --- a/test/unit_test/static/point_origin_test.cpp +++ /dev/null @@ -1,74 +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 -#include -#include -#include -#include -#include - -using namespace units; -namespace si = isq::si; - -namespace { - -struct width : kind {}; -struct abscissa : point_kind {}; - -struct ones_viewpoint1 : point_origin { - template - using rebind = ones_viewpoint1; -}; - -struct ones_viewpoint2 : point_origin { - template - using rebind = ones_viewpoint1; -}; - -static_assert(PointOrigin>); -static_assert(!PointOrigin>); -static_assert(!PointOrigin); -static_assert(!PointOrigin); - -static_assert(RebindablePointOriginFor, si::dim_length>); -static_assert(is_same_v, si::dim_length>, - dynamic_origin>); -static_assert(RebindablePointOriginFor, si::dim_time>); -static_assert( - is_same_v, si::dim_time>, dynamic_origin>); -static_assert(RebindablePointOriginFor); -static_assert(is_same_v, ones_viewpoint1>); -static_assert(RebindablePointOriginFor); -static_assert(is_same_v, ones_viewpoint1>); -static_assert(RebindablePointOriginFor); -static_assert(is_same_v, ones_viewpoint2>); -static_assert(!RebindablePointOriginFor); - -static_assert(equivalent, dynamic_origin>); -static_assert(equivalent, dynamic_origin>); -static_assert(!equivalent, clock_origin>); -static_assert(!equivalent, clock_origin>); -static_assert(!equivalent, dynamic_origin>); -static_assert(!equivalent); - -} // namespace diff --git a/test/unit_test/static/quantity_kind_test.cpp b/test/unit_test/static/quantity_kind_test.cpp deleted file mode 100644 index d8f427de..00000000 --- a/test/unit_test/static/quantity_kind_test.cpp +++ /dev/null @@ -1,869 +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 "test_tools.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace { - -using namespace units; -namespace si = isq::si; -using namespace si; -using namespace references; - -constexpr auto cgs_cm = cgs::references::cm; - -using namespace std::chrono_literals; - -struct radius_kind : kind {}; -struct width_kind : kind {}; -struct height_kind : kind {}; - -struct horizontal_area_kind : derived_kind {}; -struct rate_of_climb_kind : derived_kind {}; - -struct apple : kind {}; -struct orange : kind {}; - -struct time_kind : kind {}; - -struct cgs_width_kind : kind {}; - -template -using radius = quantity_kind; -template -using width = quantity_kind; -template -using height = quantity_kind; - -template -using horizontal_area = quantity_kind; -template -using rate_of_climb = quantity_kind; - -template -using apples = quantity_kind; -template -using oranges = quantity_kind; - -template -using cgs_width = quantity_kind; - -///////////// -// concepts -///////////// - -static_assert(QuantityKind>); -static_assert(QuantityKind>); -static_assert(!QuantityKind); -static_assert(!QuantityKind>); -static_assert(!QuantityKind, metre>>); - -static_assert(QuantityKindOf, width_kind>); -static_assert(!QuantityKindOf, height_kind>); -static_assert(!QuantityKindOf, metre>); -static_assert(!QuantityKindOf, width_kind>); -static_assert(!QuantityKindOf, metre>); -static_assert(!QuantityKindOf, metre>, width_kind>); -static_assert(!QuantityKindOf, metre>, dim_length>); -static_assert(!QuantityKindOf, metre>, metre>); - - -/////////////// -// invariants -/////////////// - -static_assert(sizeof(width) == sizeof(double)); -static_assert(sizeof(height) == sizeof(short)); - -template -concept invalid_types = requires { - requires !requires { typename quantity_kind; }; // unit of a different dimension - requires !requires { typename quantity_kind>; }; // quantity used as Rep - requires !requires { // quantity point used as Rep - typename quantity_kind, metre>>; - }; - requires !requires { typename quantity_kind>; }; // quantity kind used as Rep - requires !requires { typename quantity_kind; }; // reordered arguments - requires !requires { typename quantity_kind; }; // reordered arguments -}; -static_assert(invalid_types); - -static_assert(std::is_trivially_default_constructible_v>); -static_assert(std::is_trivially_copy_constructible_v>); -static_assert(std::is_trivially_move_constructible_v>); -static_assert(std::is_trivially_copy_assignable_v>); -static_assert(std::is_trivially_move_assignable_v>); -static_assert(std::is_trivially_destructible_v>); - -static_assert(std::is_nothrow_default_constructible_v>); -static_assert(std::is_nothrow_copy_constructible_v>); -static_assert(std::is_nothrow_move_constructible_v>); -static_assert(std::is_nothrow_copy_assignable_v>); -static_assert(std::is_nothrow_move_assignable_v>); -static_assert(std::is_nothrow_destructible_v>); - -static_assert(std::is_trivially_copyable_v>); -static_assert(std::is_standard_layout_v>); - -static_assert(std::default_initializable>); -static_assert(std::move_constructible>); -static_assert(std::copy_constructible>); -static_assert(std::equality_comparable>); -static_assert(std::totally_ordered>); -static_assert(std::regular>); - -static_assert(std::three_way_comparable>); - -static_assert(!std::is_aggregate_v>); - - -/////////////////// -// member aliases -/////////////////// - -static_assert(is_same_v::kind_type, width_kind>); -static_assert(is_same_v::quantity_type, length>); -static_assert(is_same_v::dimension, dim_length>); -static_assert(is_same_v::unit, metre>); -static_assert(is_same_v::rep, double>); - - -//////////////////// -// common observer -//////////////////// - -static_assert(same(radius{}.common(), length{})); -static_assert(radius{}.common() == // [VIM3] 1.2 kind of quantity - height{}.common()); // aspect common to mutually comparable quantities - // hence `.common()` -static_assert(!std::equality_comparable_with, oranges<>>); - - -//////////////////////////// -// static member functions -//////////////////////////// - -static_assert(width::zero().common() == 0 * m); -static_assert(width::one().common() == 1 * m); -static_assert(width::min().common() == 0 * m); -static_assert(width::max().common() == std::numeric_limits::max() * m); -static_assert(width::min().common().number() == std::numeric_limits::lowest()); -static_assert(width::max().common().number() == std::numeric_limits::max()); - - -//////////////////////// -// default constructor -//////////////////////// - -// default initialization -#if !defined(UNITS_COMP_MSVC) -static_assert([] { - const auto read_uninitialized_quantity = [] { - width w; - ++w; - }; - return !require_constant_invocation; -}()); -#endif - -// value initialization -static_assert(width{}.common() == 0 * m); - - -///////// -// CTAD -///////// - -static_assert(same(quantity_kind(rate_of_climb(0.01 * (km / h))), - rate_of_climb(0.01 * (km / h)))); - - -//////////////////////////// -// construction from a rep -//////////////////////////// - -static_assert(construct_from_only>(1).common() == 1); -static_assert(construct_from_only>(1.0).common() == 1); -static_assert(construct_from_only>(1LL).common().number() == 1); -static_assert(construct_from_only>(1.0L).common().number() == 1); -static_assert(!constructible_or_convertible_from>(1.0)); -static_assert(!constructible_or_convertible_from>(1.0)); -static_assert(!constructible_or_convertible_from>(1.0)); -static_assert(!constructible_or_convertible_from>(1.0f)); -static_assert(!constructible_or_convertible_from>(1.0)); -static_assert(!constructible_or_convertible_from>(1)); - - -///////////////////////////////// -// construction from a quantity -///////////////////////////////// - -static_assert(construct_from_only>(1 * m).common() == 1 * m); -static_assert(construct_from_only>(1 * km).common() == 1 * km); -// static_assert(construct_from_only>(1 * cgs_cm).common() == 1 * cm); // TODO: Fix #210 -static_assert(construct_from_only>(1 * cgs_cm).common() == 1 * cm); -static_assert(construct_from_only>(1 * mm).common() == 1 * mm); -static_assert(construct_from_only>(1 * m).common() == 1 * m); -static_assert(construct_from_only>(1 * km).common() == 1 * km); -static_assert(construct_from_only>(1.0 * mm).common() == 1 * mm); -static_assert(construct_from_only>(1.0 * m).common() == 1 * m); -static_assert(construct_from_only>(1.0 * km).common() == 1 * km); -static_assert(construct_from_only>(1.0 * mm).common() == 1 * mm); -static_assert(construct_from_only>(1.0 * m).common() == 1 * m); -static_assert(construct_from_only>(1.0 * km).common() == 1 * km); - -static_assert(!constructible_or_convertible_from>(1 * mm)); -static_assert(!constructible_or_convertible_from>(1.0 * mm)); -static_assert(!constructible_or_convertible_from>(1.0 * m)); -static_assert(!constructible_or_convertible_from>(1.0 * km)); -static_assert(!constructible_or_convertible_from>(1 * s)); -static_assert(!constructible_or_convertible_from>(1 * (m * m))); -static_assert(!constructible_or_convertible_from>(1 * (m / s))); - - -static_assert(construct_from_only>(1.0f * m).common() == 1 * m); -static_assert(construct_from_only>(short{1} * m).common() == 1 * m); -static_assert(construct_from_only>(1 * m).common() == 1 * m); - - -static_assert(construct_from_only>(quantity(1)).common() == 1); -static_assert(construct_from_only>(dimensionless(1)).common() == 0.01); -static_assert(construct_from_only>(quantity(1.0)).common().number() == 100); -static_assert(construct_from_only>(dimensionless(1)).common().number() == 1); -static_assert(construct_from_only>(quantity(1.0)).common() == 1); -static_assert(construct_from_only>(quantity(1.0f)).common() == 1); -static_assert(construct_from_only>(quantity(1.0)).common() == 1); -static_assert(construct_from_only>(quantity(1)).common() == 1); -static_assert(construct_from_only>(quantity(short{1})).common() == 1); -static_assert(construct_from_only>(quantity(1)).common() == 1); -static_assert(construct_from_only>(quantity(1.0)).common().number() == 1e2); -static_assert(construct_from_only>(quantity(1.0f)).common().number() == 1e2); -static_assert(construct_from_only>(quantity(1.0)).common().number() == 1e2f); -static_assert(construct_from_only>(quantity(1)).common().number() == 1e2); -static_assert(construct_from_only>(quantity(short{1})).common().number() == 1e2); -static_assert(construct_from_only>(quantity(1)).common().number() == 1e2); - -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); -static_assert(!constructible_or_convertible_from>(apples{})); - - -static_assert(construct_from_only>(42s).common() == 42 * s); - - -static_assert(!constructible_or_convertible_from>(1 * s)); -static_assert(!constructible_or_convertible_from>(1 * (m * m))); -static_assert(!constructible_or_convertible_from>(1 * (m / s))); - - -static_assert(construct_from_only>(1.0 * cgs_cm).common() == 1 * cm); -static_assert(construct_from_only>(1.0 * cm).common() == 1 * cm); - - -//////////////////////////////////////////// -// construction from another quantity kind -//////////////////////////////////////////// - -// clang-format off -static_assert(construct_and_convert_from>(width(1 * m)).common() == 1 * m); -static_assert(construct_and_convert_from>(width(1 * cgs_cm)).common() == 1 * cm); -static_assert(construct_and_convert_from>(width(1 * cgs_cm)).common() == 1 * cm); -// clang-format on - -static_assert(construct_and_convert_from>(width(1 * m)).common() == 1 * m); -static_assert(!constructible_or_convertible_from>(width(1.0 * m))); - -static_assert(construct_and_convert_from>(width(1 * km)).common() == 1 * km); -static_assert(!constructible_or_convertible_from>(width(1 * m))); - -static_assert(construct_and_convert_from>(width(1 * km)).common() == 1 * km); -static_assert(construct_and_convert_from>(width(1 * m)).common() == 1 * m); - -static_assert(!constructible_or_convertible_from>(height(1 * m))); -static_assert(!constructible_or_convertible_from>(width(1 * m) / (1 * m))); -static_assert(!constructible_or_convertible_from>(oranges(1))); - - -////////////////////////////////// -// construction from other types -////////////////////////////////// - -// clang-format off -static_assert(!constructible_or_convertible_from>(quantity_point(1 * m))); -static_assert(!constructible_or_convertible_from>(quantity_point(1 * km))); -static_assert(!constructible_or_convertible_from>(quantity_point(1 * m))); -static_assert(!constructible_or_convertible_from>(quantity_point(1 * km))); -static_assert(!constructible_or_convertible_from>(quantity_point(1.0 * m))); -static_assert(!constructible_or_convertible_from>(quantity_point(1.0 * km))); -static_assert(!constructible_or_convertible_from>(quantity_point(1.0 * (m * m)))); -static_assert(!constructible_or_convertible_from>(quantity_point(1.0 * s))); -static_assert(!constructible_or_convertible_from>(quantity_point(1.0 * s))); -static_assert(!constructible_or_convertible_from>(1s)); -static_assert(!constructible_or_convertible_from>(1.0s)); -static_assert(!constructible_or_convertible_from>(quantity_point(1))); -static_assert(!constructible_or_convertible_from>(quantity_point(dimensionless(1)))); -static_assert(!constructible_or_convertible_from>(quantity_point(1))); -static_assert(!constructible_or_convertible_from>(quantity_point(dimensionless(1)))); -static_assert(!constructible_or_convertible_from>(quantity_point(1.0))); -static_assert(!constructible_or_convertible_from>(quantity_point(dimensionless(1.0)))); -static_assert(!constructible_or_convertible_from>(quantity_point(1.0 * m))); -static_assert(!constructible_or_convertible_from>(1s)); -static_assert(!constructible_or_convertible_from>(1.0s)); -// clang-format on - - -//////////////////////// -// assignment operator -//////////////////////// - -static_assert((width(2 * m) = width(1 * m)).common() == 1 * m); -static_assert((width(2 * m) = width(1 * km)).common() == 1 * km); -static_assert(!std::is_assignable_v, width>); -static_assert(!std::is_assignable_v, width>); - - -///////////////////// -// member operators -///////////////////// - -#if !defined(UNITS_COMP_MSVC) || defined(NDEBUG) -static_assert([]() { - width w(1 * m); - assert(+w.common() == 1 * m); - assert(-w.common() == -1 * m); - assert(&++w == &w && w.common() == 2 * m); - assert(&--w == &w && w.common() == 1 * m); - assert((w++).common() == 1 * m && w.common() == 2 * m); - assert((w--).common() == 2 * m && w.common() == 1 * m); - assert(&(w += w) == &w && w.common() == 2 * m); - assert(&(w -= w) == &w && w.common() == 0 * m); - w = width(3 * m); - assert(&(w *= 3) == &w && w.common() == 9 * m); - assert(&(w *= quantity(1)) == &w && w.common() == 9 * m); - assert(&(w *= (w / w)) == &w && w.common() == 9 * m); - assert(&(w /= 2) == &w && w.common() == 4 * m); - assert(&(w /= quantity(1)) == &w && w.common() == 4 * m); - assert(&(w /= (w / w)) == &w && w.common() == 4 * m); - assert(&(w %= 3) == &w && w.common() == 1 * m); - assert(&(w %= quantity(3)) == &w && w.common() == 1 * m); - assert(&(w %= 3 * (w / w)) == &w && w.common() == 1 * m); - assert(&(w %= w) == &w && w.common() == 0 * m); - w = width(3 * m); - assert(&(w *= 3.9) == &w && w.common() == 11 * m); - assert(&(w *= quantity(1.0)) == &w && w.common() == 11 * m); - assert(&(w *= 1.0 * (w / w)) == &w && w.common() == 11 * m); - assert(&(w /= 3.9) == &w && w.common() == 2 * m); - assert(&(w /= quantity(1.0)) == &w && w.common() == 2 * m); - assert(&(w /= 1.0 * (w / w)) == &w && w.common() == 2 * m); - return true; -}()); -#endif - -static_assert((std::uint8_t(255) * m %= 256) == (width(255 * m) %= 256).common()); -static_assert((std::uint8_t(255) * m %= quantity(256)) == - (width(255 * m) %= quantity(256)).common()); -// static_assert((std::uint8_t(255) * m %= 256 * m) == -// (width(255 * m) %= -// quantity_kind, one, std::uint8_t>(256)).common()); // UB -// static_assert((std::uint8_t(255) * m %= 256 * m) != -// (width(255 * m) %= width(256 * m)).common()); // UB -static_assert((std::uint8_t(255) * m %= 257) == (width(255 * m) %= 257).common()); -static_assert((std::uint8_t(255) * m %= quantity(257)) == - (width(255 * m) %= quantity(257)).common()); -static_assert((std::uint8_t(255) * m %= 257 * m) == - (width(255 * m) %= - quantity_kind, one, std::uint8_t>(257)) - .common()); -static_assert((std::uint8_t(255) * m %= 257 * m) == - (width(255 * m) %= width(257 * m)).common()); - -static_assert(same((-width(short{1} * m)).common(), int{-1} * m)); - -template -concept invalid_compound_assignments_ = requires(quantity_kind w, Qx q) { - requires !requires { w += q; }; - requires !requires { w -= q; }; - requires !requires { w *= q; }; - requires !requires { w /= q; }; - requires !requires { w %= q; }; -}; -template -concept invalid_compound_assignments = requires(quantity_kind w, height h) { - requires !requires { w += 1; }; - requires !requires { w -= 1; }; - requires !requires { w *= 1 * (km / m); }; - requires !requires { w /= 1 * (km / m); }; - requires !requires { w %= 1 * (km / m); }; - requires !requires { w += m; }; - requires !requires { w -= m; }; - requires !requires { w *= m; }; - requires !requires { w /= m; }; - requires !requires { w %= m; }; - requires !requires { - w *= quantity_kind, scaled_unit(), one>, int>{1}; - }; - requires !requires { - w /= quantity_kind, scaled_unit(), one>, int>{1}; - }; - requires !requires { - w %= quantity_kind, scaled_unit(), one>, int>{1}; - }; - requires !requires { w %= 1.0; }; - requires !requires { w %= quantity(1.0); }; - requires !requires { w %= 1.0 * (w / w); }; - requires !requires { w %= 1.0 * w; }; - requires !requires { w %= h / h; }; - requires invalid_compound_assignments_>; - requires invalid_compound_assignments_>; - requires invalid_compound_assignments_>; - requires invalid_compound_assignments_, metre, int>>; - requires invalid_compound_assignments_; -}; -static_assert(invalid_compound_assignments); -static_assert(invalid_compound_assignments_); - - -///////////////////////// -// non-member operators -///////////////////////// - -static_assert(same(width(2 * m) + width(3 * m), width(5 * m))); -static_assert(same(width(2 * m) + width(3. * m), width(5. * m))); -static_assert(same(width(2. * m) + width(3 * m), width(5. * m))); -static_assert(comp(width(2 * km) + width(3e3 * m), width(5e3 * m))); -static_assert(same(width(2 * m) - width(3 * m), width(-1 * m))); -static_assert(same(width(2 * m) - width(3. * m), width(-1. * m))); -static_assert(same(width(2. * m) - width(3 * m), width(-1. * m))); -static_assert(comp(width(2e3 * m) - width(3 * km), width(-1e3 * m))); - -static_assert( - is_same_v(0 * m) + width(0 * m)).common().number()), - int&&>); -static_assert( - is_same_v(0 * m) - width(0 * m)).common().number()), - int&&>); -static_assert((width(128 * m) + width(128 * m)).common().number() == - std::uint8_t(128) + std::uint8_t(128)); -static_assert((width(0 * m) - width(1 * m)).common().number() == - std::uint8_t(0) - std::uint8_t(1)); - -static_assert(!std::is_invocable_v, width, double>); -static_assert(!std::is_invocable_v, width, length>); -static_assert(!std::is_invocable_v, width, quantity_point, metre>>); -static_assert(!std::is_invocable_v, width, height>); -static_assert(!std::is_invocable_v, width, reference>); -static_assert(!std::is_invocable_v, width, double>); -static_assert(!std::is_invocable_v, width, length>); -static_assert(!std::is_invocable_v, width, quantity_point, metre>>); -static_assert(!std::is_invocable_v, width, height>); -static_assert(!std::is_invocable_v, width, reference>); - -// clang-format off -static_assert(!std::is_invocable_v, quantity_kind, one>, quantity_kind, one>>); -static_assert(!std::is_invocable_v, quantity_kind, one>, quantity_kind< height_kind, metre>>); -static_assert(!std::is_invocable_v, quantity_kind< width_kind, metre>, quantity_kind, one>>); -static_assert(!std::is_invocable_v, quantity_kind, day>, quantity_kind< height_kind, metre>>); -static_assert(!std::is_invocable_v, quantity_kind< width_kind, metre>, quantity_kind, day>>); -static_assert(!std::is_invocable_v, quantity_kind, day>, quantity_kind, day>>); -static_assert(!std::is_invocable_v, quantity_kind, one>, quantity_kind, one>>); -static_assert(!std::is_invocable_v, quantity_kind, one>, quantity_kind< height_kind, metre>>); -static_assert(!std::is_invocable_v, quantity_kind< width_kind, metre>, quantity_kind, one>>); -static_assert(!std::is_invocable_v, quantity_kind, day>, quantity_kind< height_kind, metre>>); -static_assert(!std::is_invocable_v, quantity_kind< width_kind, metre>, quantity_kind, day>>); -static_assert(!std::is_invocable_v, quantity_kind, day>, quantity_kind, day>>); -// clang-format on - -static_assert(same(width(2 * m) * 3, width(6 * m))); -static_assert(same(width(2 * m) * 3., width(6. * m))); -static_assert(same(width(2. * m) * 3, width(6. * m))); -static_assert(same(2 * width(3 * m), width(6 * m))); -static_assert(same(2 * width(3. * m), width(6. * m))); -static_assert(same(2. * width(3 * m), width(6. * m))); - -static_assert(comp(width(2 * m) * quantity(3), width(6 * m))); -static_assert(comp(width(2 * m) * quantity(3.), width(6. * m))); -static_assert(comp(width(2. * m) * quantity(3), width(6. * m))); -static_assert(comp(quantity(2) * width(3 * m), width(6 * m))); -static_assert(comp(quantity(2) * width(3. * m), width(6. * m))); -static_assert(comp(quantity(2.) * width(3 * m), width(6. * m))); - -static_assert(comp(width(2 * m) * quantity_kind, one, int>(3), - width(6 * m))); -static_assert(comp(width(2 * m) * quantity_kind, one, double>(3.), - width(6. * m))); -static_assert(comp(width(2. * m) * quantity_kind, one, int>(3), - width(6. * m))); -static_assert(comp(quantity_kind, one, int>(2) * width(3 * m), - width(6 * m))); -static_assert(comp(quantity_kind, one, int>(2) * width(3. * m), - width(6. * m))); -static_assert(comp(quantity_kind, one, double>(2.) * width(3 * m), - width(6. * m))); - -static_assert(comp(height(2 * m) * (3 * Hz), rate_of_climb(6 * (m / s)))); -static_assert(comp(height(2 * m) * (3. * Hz), rate_of_climb(6. * (m / s)))); -static_assert(comp(height(2. * m) * (3 * Hz), rate_of_climb(6. * (m / s)))); -static_assert(comp((2 * Hz) * height(3 * m), rate_of_climb(6 * (m / s)))); -static_assert(comp((2 * Hz) * height(3. * m), rate_of_climb(6. * (m / s)))); -static_assert(comp((2. * Hz) * height(3 * m), rate_of_climb(6. * (m / s)))); - -static_assert(comp(quantity_kind(2 * s) * (3 * Hz), - quantity_kind, one, int>(6))); -static_assert(comp((3 * Hz) * quantity_kind(2 * s), - quantity_kind, one, int>(6))); - -static_assert(comp(apples(2) * quantity(2), apples(4))); -static_assert(comp(quantity(2) * apples(2), apples(4))); - -// clang-format off -static_assert(comp(width(4 * m) * (1 * m), horizontal_area(4 * (m * m)))); -static_assert(comp(width(2 * m) * width(2 * m), horizontal_area(4 * (m * m)))); -static_assert(comp(width(2 * m) * width(2 * m), horizontal_area(4 * (m * m)))); -static_assert(comp(width(2 * m) * width(2 * m), horizontal_area(4 * (m * m)))); -// clang-format on - -static_assert(comp(apples(2) * apples(2), apples(4))); -static_assert(comp(apples(2) * (2 / apples(1)), apples(4))); - -static_assert(comp(width(4 * m) * (1 * mm), horizontal_area(4 * (m * mm)))); -static_assert(comp(width(2 * m) * width(2 * m), horizontal_area(4 * (m * m)))); -static_assert(comp(width(2 * m) * (1 / width(2 * m)), - quantity_kind, one>(1))); - -static_assert(same(width(2 * m) / 3, width(0 * m))); -static_assert(same(width(2 * m) / 3., width(2 / 3. * m))); -static_assert(same(width(2. * m) / 3, width(2. / 3 * m))); - -static_assert(comp(width(2 * m) / quantity(3), width(0 * m))); -static_assert(comp(width(2 * m) / quantity(3.), width(2 / 3. * m))); -static_assert(comp(width(2. * m) / quantity(3), width(2. / 3 * m))); - -static_assert(comp(width(2 * m) / quantity_kind, one, int>(3), - width(0 * m))); -static_assert(comp(width(2 * m) / quantity_kind, one, double>(3.), - width(2 / 3. * m))); -static_assert(comp(width(2. * m) / - quantity_kind, one, double>(3), - width(2. / 3 * m))); - -static_assert(comp(2 / quantity_kind(3 * s), - quantity_kind, hertz, int>(2 / 3 / (1 * s)))); -static_assert(comp(2 / quantity_kind(3. * s), - quantity_kind, hertz, double>(2 / 3. / (1 * s)))); -static_assert(comp(2. / quantity_kind(3 * s), - quantity_kind, hertz, double>(2 / 3. / (1 * s)))); - -static_assert(comp(quantity(2) / quantity_kind(3 * s), - quantity_kind, hertz, int>(2 / 3 / (1 * s)))); -static_assert(comp(quantity(2) / quantity_kind(3. * s), - quantity_kind, hertz, double>(2 / 3. / (1 * s)))); -static_assert(comp(quantity(2.) / quantity_kind(3 * s), - quantity_kind, hertz, double>(2 / 3. / (1 * s)))); - -static_assert(comp(quantity_kind, one, int>(2) / - quantity_kind(3 * s), - quantity_kind, hertz, int>(2 / 3 / (1 * s)))); -static_assert(comp(quantity_kind, one, int>(2) / - quantity_kind(3. * s), - quantity_kind, hertz, double>(2 / 3. / (1 * s)))); -static_assert(comp(quantity_kind, one, double>(2.) / - quantity_kind(3 * s), - quantity_kind, hertz, double>(2 / 3. / (1 * s)))); - -static_assert(comp(height(2 * m) / (3 * s), rate_of_climb(0 * (m / s)))); -static_assert(comp(height(2 * m) / (3. * s), rate_of_climb(2 / 3. * (m / s)))); -static_assert(comp(height(2. * m) / (3 * s), rate_of_climb(2. / 3 * (m / s)))); - -static_assert(comp(width(2 * m) * dimensionless(3), width(6 * cm))); -static_assert(comp(dimensionless(2) * width(3 * m), width(6 * cm))); -static_assert(comp(width(2 * m) / dimensionless(3), - width(2. / 3 * hm))); -static_assert(same(width(2 * m) % dimensionless(3), width(2 * m))); - -static_assert(comp(height(2 * m) / (3 * m), - quantity_kind, one, int>(0))); -static_assert(comp(height(2 * m) / (3. * m), - quantity_kind, one, double>(2 / 3.))); -static_assert(comp(height(2. * m) / (3 * m), - quantity_kind, one, double>(2. / 3))); - -static_assert(comp((2 * m) / height(3 * m), - quantity_kind, one, int>(0))); -static_assert(comp((2 * m) / height(3. * m), - quantity_kind, one, double>(2 / 3.))); -static_assert(comp((2. * m) / height(3 * m), - quantity_kind, one, double>(2. / 3))); - -static_assert(comp(width(8 * m) / width(2 * m), - quantity_kind, one, int>(4))); -static_assert(comp(width(8 * m) / width(2 * m), - quantity_kind, one, double>(4.0))); -static_assert(comp(width(8 * m) / width(2 * m), - quantity_kind, one, double>(4.0))); - -static_assert(comp(apples(8) / apples(2), apples(4))); -static_assert(comp(apples(8) / (2 / apples(1)), apples(4))); - -static_assert(comp(horizontal_area(8 * (m * m)) / width(2 * m), width(4 * m))); -static_assert(comp(horizontal_area(4 * (m * m)) / (1 * m), width(4 * m))); - -static_assert(same(width(2 * m) % 3, width(2 * m))); -static_assert(same(width(3 * m) % width(2 * m), width(1 * m))); - -static_assert( - is_same_v(0 * m) % width(0 * m)).common().number()), - decltype(std::uint8_t(0) % std::uint8_t(0))&&>); - -static_assert(!std::is_invocable_v, reference, width>); -static_assert(!std::is_invocable_v, width, height>); -static_assert( - !std::is_invocable_v, height, quantity_point, metre>>); -static_assert( - !std::is_invocable_v, quantity_point, metre>, height>); - -static_assert(!std::is_invocable_v, reference, width>); -static_assert(!std::is_invocable_v, width, height>); -static_assert(!std::is_invocable_v, height, quantity_point, metre>>); -static_assert(!std::is_invocable_v, quantity_point, metre>, height>); - -static_assert(!std::is_invocable_v, width, reference>); -static_assert(!std::is_invocable_v, width, length>); -static_assert( - !std::is_invocable_v, width, quantity_point, metre, int>>); -static_assert(!std::is_invocable_v, width, double>); -static_assert(!std::is_invocable_v, width, width>); - -// clang-format off -static_assert(!std::is_invocable_v, quantity_kind, one>, quantity_kind, one>>); -static_assert(!std::is_invocable_v, quantity_kind, one>, quantity_kind< height_kind, metre>>); -static_assert(!std::is_invocable_v, quantity_kind< width_kind, metre>, quantity_kind, one>>); -static_assert(!std::is_invocable_v, quantity_kind, day>, quantity_kind< height_kind, metre>>); -static_assert(!std::is_invocable_v, quantity_kind< width_kind, metre>, quantity_kind, day>>); -static_assert(!std::is_invocable_v, quantity_kind, day>, quantity_kind, day>>); -static_assert(!std::is_invocable_v, quantity_kind, one>, quantity_kind, one>>); -static_assert(!std::is_invocable_v, quantity_kind, one>, quantity_kind< height_kind, metre>>); -static_assert(!std::is_invocable_v, quantity_kind< width_kind, metre>, quantity_kind, one>>); -static_assert(!std::is_invocable_v, quantity_kind, day>, quantity_kind< height_kind, metre>>); -static_assert(!std::is_invocable_v, quantity_kind< width_kind, metre>, quantity_kind, day>>); -static_assert(!std::is_invocable_v, quantity_kind, day>, quantity_kind, day>>); -static_assert(!std::is_invocable_v, quantity_kind, one>, quantity_kind, one>>); -static_assert(!std::is_invocable_v, quantity_kind, one>, quantity_kind< height_kind, metre>>); -static_assert(!std::is_invocable_v, quantity_kind< width_kind, metre>, quantity_kind, one>>); -static_assert(!std::is_invocable_v, quantity_kind, day>, quantity_kind< height_kind, metre>>); -static_assert(!std::is_invocable_v, quantity_kind< width_kind, metre>, quantity_kind, day>>); -static_assert(!std::is_invocable_v, quantity_kind, day>, quantity_kind, day>>); -// clang-format on - - -///////////////////////// -// comparison operators -///////////////////////// - -static_assert(width(1 * m) == width(1 * m)); -static_assert(width(1 * m) == width(1.0 * m)); -static_assert(width(1 * m) == width(1000 * mm)); -static_assert(width(1 * m) == width(1e3 * mm)); -static_assert(width(2 * m) != width(1 * m)); -static_assert(width(2 * m) != width(1.0 * cgs_cm)); -static_assert(std::equality_comparable_with, width>); -static_assert(std::equality_comparable_with, width>); -static_assert(std::equality_comparable_with, width>); -static_assert(std::equality_comparable_with, width>); -template -concept invalid_equality = requires(quantity_kind w) { - requires !requires { w == 1; }; - requires !requires { w != 1.0; }; - requires !requires { w == 1 * m; }; - requires !requires { w != 1.0 * cgs_cm; }; - requires !requires { w == 1 * km; }; - requires !requires { w != m; }; - requires !requires { w == km; }; - requires !requires { w != quantity(1); }; - requires !requires { w == dimensionless(1.0); }; - requires !requires { w != height(1 * m); }; - requires !requires { w == height(1.0 * km); }; - requires !requires { w != horizontal_area(1 * (m * m)); }; - requires !requires { w == rate_of_climb(1.0 * (km / h)); }; - requires !requires { w != quantity_point(1 * m); }; - requires !requires { w == quantity_point(1.0 * mm); }; - requires !requires { w != quantity_point(quantity(1)); }; - requires !requires { w == quantity_point(dimensionless(1.0)); }; -}; -static_assert(invalid_equality); - -static_assert(width(1 * m) < width(2 * m)); -static_assert(width(1 * m) <= width(2.0 * m)); -static_assert(width(1 * m) <= width(1 * km)); -static_assert(width(1 * m) >= width(1e3 * mm)); -static_assert(width(2 * m) >= width(1 * mm)); -static_assert(width(2 * m) > width(1 * cgs_cm)); -static_assert(std::three_way_comparable_with, width>); -static_assert(std::three_way_comparable_with, width>); -static_assert(std::three_way_comparable_with, width>); -static_assert(std::three_way_comparable_with, width>); -template -concept invalid_relational = requires(quantity_kind w) { - requires !requires { w < 1; }; - requires !requires { w <= 1.0; }; - requires !requires { w >= 1 * m; }; - requires !requires { w > 1.0 * cgs_cm; }; - requires !requires { w <=> 1 * km; }; - requires !requires { w < quantity(1); }; - requires !requires { w <= dimensionless(1.0); }; - requires !requires { w >= height(1 * m); }; - requires !requires { w > height(1.0 * km); }; - requires !requires { w <=> horizontal_area(1 * (m * m)); }; - requires !requires { w < rate_of_climb(1.0 * (km / h)); }; - requires !requires { w <= quantity_point(1 * m); }; - requires !requires { w >= quantity_point(1.0 * mm); }; - requires !requires { w > quantity_point(quantity(1)); }; - requires !requires { w <=> quantity_point(dimensionless(1.0)); }; -}; -static_assert(invalid_relational); - - -/////////////////////// -// quantity_kind_cast -/////////////////////// - -// clang-format off -static_assert(same(quantity_kind_cast>(width(1 * m)), width(1 * m))); -static_assert(same(quantity_kind_cast>(width(1 * m)), width(1.0 * m))); -static_assert(same(quantity_kind_cast>(width(999 * m)), width(0 * km))); -static_assert(same(quantity_kind_cast>(width(1000 * m)), width(1 * km))); -static_assert(same(quantity_kind_cast>(width(999 * m)), width(0.999 * km))); -static_assert(same(quantity_kind_cast(width(1 * m)), width(1.0 * m))); -static_assert(same(quantity_kind_cast(width(1 * m)), width(1 * m))); -static_assert(same(quantity_kind_cast(width(999 * m)), width(0 * km))); -static_assert(same(quantity_kind_cast(width(1000 * m)), width(1 * km))); -static_assert(same(quantity_kind_cast>(width(1 * m)), height(1 * m))); -static_assert(same(quantity_kind_cast>(width(1 * m)), height(1.0 * m))); -static_assert(same(quantity_kind_cast>(width(999 * m)), height(0 * km))); -static_assert(same(quantity_kind_cast>(width(1000 * m)), height(1 * km))); -static_assert(same(quantity_kind_cast>(width(999 * m)), height(0.999 * km))); -static_assert(same(quantity_kind_cast(width(1 * m)), height(1 * m))); -static_assert(same(quantity_kind_cast(width(1 * m)), height(1 * m))); -static_assert(same(quantity_kind_cast(width(999 * m)), height(0 * km))); -static_assert(same(quantity_kind_cast(width(1000 * m)), height(1 * km))); -static_assert(same(quantity_kind_cast>(width(1 * cm)), cgs_width(1 * cgs_cm))); -static_assert(same(quantity_kind_cast(width(1 * cm)), cgs_width(1 * cgs_cm))); -static_assert(same(quantity_kind_cast(width(1 * cm)), cgs_width(1 * cgs_cm))); -static_assert(same(quantity_kind_cast(width(1 * m)), cgs_width(1 * m))); -static_assert(same(quantity_kind_cast(width(1 * m)), cgs_width(1 * m))); -static_assert(comp(quantity_kind_cast(width(1 * cm)), width(1 * cgs_cm))); -static_assert(same(quantity_kind_cast>(width(1 * m)), width(0 * km))); -static_assert(same(quantity_kind_cast>(width(1 * m)), width(100 * cm))); -static_assert(same(quantity_kind_cast>(width(0.01 * m)), width(1 * cm))); -static_assert(same(quantity_kind_cast>(width(1 * cgs_cm)), width(1 * cgs_cm))); -// clang-format on -template -concept invalid_cast = requires { - requires !requires { quantity_kind_cast>(quantity_kind(1 * m)); }; - requires !requires { - quantity_kind_cast>(quantity_kind(1 * m)); - }; - requires !requires { - quantity_kind_cast>(quantity_kind(1 * m)); - }; - requires !requires { quantity_kind_cast(quantity_kind(1 * m)); }; - requires !requires { quantity_kind_cast(quantity_kind(1 * m)); }; - requires !requires { quantity_kind_cast(quantity_kind(1 * m)); }; - requires !requires { quantity_kind_cast(quantity_kind(1 * m)); }; - requires !requires { - quantity_kind_cast(quantity_kind(1 * m)); - }; - requires !requires { - quantity_kind_cast(quantity_kind(1 * m)); - }; - requires !requires { quantity_kind_cast>(quantity_kind(1 * m)); }; - requires !requires { quantity_kind_cast(quantity_kind(1 * m)); }; - requires !requires { quantity_kind_cast(quantity_kind(1 * m)); }; - requires !requires { - quantity_kind_cast, metre, int>>(quantity_kind(1 * m)); - }; - requires !requires { - quantity_kind_cast, one, int>>( - quantity_kind(1 * m)); - }; -}; -static_assert(invalid_cast); - - -///////////////////////// -// extensible interface -///////////////////////// - -namespace mylib { - -struct radius_kind : kind {}; - -struct cylinder_size {}; - -template Radius, units::QuantityKindOf Height> -cylinder_size operator+(Radius, Height); - -} // namespace mylib - -namespace yourapp { - -static_assert(is_same_v(1. * m) + - height(1. * m))>); - -} // namespace yourapp - -} // namespace diff --git a/test/unit_test/static/quantity_point_kind_test.cpp b/test/unit_test/static/quantity_point_kind_test.cpp deleted file mode 100644 index 07de439b..00000000 --- a/test/unit_test/static/quantity_point_kind_test.cpp +++ /dev/null @@ -1,727 +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 "test_tools.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace { - -using namespace units; -namespace si = isq::si; -using namespace si; -using namespace references; -using sys_seconds = std::chrono::time_point; - -constexpr auto cgs_cm = cgs::references::cm; - -using namespace std::chrono_literals; - -struct width_kind : kind {}; -struct height_kind : kind {}; -struct abscissa_kind : point_kind {}; -struct ordinate_kind : point_kind {}; - -struct distance_kind : kind {}; -struct cgs_width_kind : kind {}; -struct cgs_height_kind : kind {}; -struct rate_of_climb_kind : derived_kind {}; -struct altitude_kind : point_kind {}; - -struct sea_level_origin : point_origin {}; -struct sea_level_altitude_kind : point_kind {}; - -template -struct screen_origin : point_origin { - template - using rebind = screen_origin; -}; -struct screen_si_width_kind : point_kind> {}; -struct screen_si_cgs_width_kind : - point_kind> {}; - -struct apple : kind {}; -struct orange : kind {}; -struct nth_apple_kind : point_kind {}; -struct nth_orange_kind : point_kind {}; - -struct time_kind : kind {}; -struct time_point_kind : point_kind {}; - -struct sys_time_point_kind : point_kind> {}; - -template -using width = quantity_kind; -template -using height = quantity_kind; -template -using abscissa = quantity_point_kind; -template -using ordinate = quantity_point_kind; - -template -using distance = quantity_kind; -template -using cgs_width = quantity_kind; -template -using cgs_height = quantity_kind; -template -using rate_of_climb = quantity_kind; -template -using altitude = quantity_point_kind; - -template -using sea_level_altitude = quantity_point_kind; -template -using screen_si_width = quantity_point_kind; -template -using screen_si_cgs_width = quantity_point_kind; - -template -using apples = quantity_kind; -template -using oranges = quantity_kind; -template -using nth_apple = quantity_point_kind; -template -using nth_orange = quantity_point_kind; - -///////////// -// concepts -///////////// - -static_assert(QuantityPointKind>); -static_assert(QuantityPointKind>); -static_assert(!QuantityPointKind); -static_assert(!QuantityPointKind>); -static_assert(!QuantityPointKind, metre>>); -static_assert(!QuantityPointKind>); - -static_assert(QuantityPointKindOf, abscissa_kind>); -static_assert(!QuantityPointKindOf, ordinate_kind>); -static_assert(!QuantityPointKindOf, metre>); -static_assert(!QuantityPointKindOf, abscissa_kind>); -static_assert(!QuantityPointKindOf, metre>); -static_assert(!QuantityPointKindOf, abscissa_kind>); -static_assert(!QuantityPointKindOf, width_kind>); -static_assert(!QuantityPointKindOf, metre>); -static_assert(!QuantityPointKindOf, sea_level_altitude_kind>); -static_assert(!QuantityPointKindOf, sea_level_altitude_kind>); -static_assert(!QuantityPointKindOf, metre>, width_kind>); -static_assert(!QuantityPointKindOf, metre>, dim_length>); -static_assert(!QuantityPointKindOf, metre>, dynamic_origin>); -static_assert(!QuantityPointKindOf, metre>, metre>); - - -/////////////// -// invariants -/////////////// - -static_assert(sizeof(abscissa) == sizeof(double)); -static_assert(sizeof(ordinate) == sizeof(short)); - -template -concept invalid_types = requires { - requires !requires { typename quantity_point_kind; }; // width_kind is not a point kind - requires !requires { typename quantity_point_kind; }; // unit of a different dimension - requires !requires { typename quantity_point_kind>; }; // quantity used as Rep - requires !requires { - typename quantity_point_kind, metre>>; - }; // quantity point used as Rep - requires !requires { typename quantity_point_kind>; }; // quantity kind used as Rep - requires !requires { - typename quantity_point_kind>; - }; // quantity point kind used as Rep - requires !requires { typename quantity_point_kind; }; // reordered arguments - requires !requires { typename quantity_point_kind; }; // reordered arguments -}; -static_assert(invalid_types); - -static_assert(std::is_trivially_default_constructible_v>); -static_assert(std::is_trivially_copy_constructible_v>); -static_assert(std::is_trivially_move_constructible_v>); -static_assert(std::is_trivially_copy_assignable_v>); -static_assert(std::is_trivially_move_assignable_v>); -static_assert(std::is_trivially_destructible_v>); - -static_assert(std::is_nothrow_default_constructible_v>); -static_assert(std::is_nothrow_copy_constructible_v>); -static_assert(std::is_nothrow_move_constructible_v>); -static_assert(std::is_nothrow_copy_assignable_v>); -static_assert(std::is_nothrow_move_assignable_v>); -static_assert(std::is_nothrow_destructible_v>); - -static_assert(std::is_trivially_copyable_v>); -static_assert(std::is_standard_layout_v>); - -static_assert(std::default_initializable>); -static_assert(std::move_constructible>); -static_assert(std::copy_constructible>); -static_assert(std::equality_comparable>); -static_assert(std::totally_ordered>); -static_assert(std::regular>); - -static_assert(std::three_way_comparable>); - -static_assert(!std::is_aggregate_v>); - - -/////////////////// -// member aliases -/////////////////// - -static_assert(is_same_v::point_kind_type, abscissa_kind>); -static_assert(is_same_v::kind_type, width_kind>); -static_assert(is_same_v::origin, dynamic_origin>); -static_assert(is_same_v::quantity_kind_type, width>); -static_assert(is_same_v::quantity_type, length>); -static_assert(is_same_v::dimension, dim_length>); -static_assert(is_same_v::unit, metre>); -static_assert(is_same_v::rep, double>); - - -////////////////////// -// relative observer -////////////////////// - -static_assert(same(abscissa{}.relative(), width{})); - - -//////////////////////////// -// static member functions -//////////////////////////// - -static_assert(abscissa::min().relative().common() == 0 * m); -static_assert(abscissa::max().relative().common() == std::numeric_limits::max() * m); -static_assert(abscissa::min().relative().common().number() == std::numeric_limits::lowest()); -static_assert(abscissa::max().relative().common().number() == std::numeric_limits::max()); - - -//////////////////////// -// default constructor -//////////////////////// - -// default initialization -#if !defined(UNITS_COMP_MSVC) -static_assert([] { - const auto read_uninitialized_quantity = [] { - abscissa w; - ++w; - }; - return !require_constant_invocation; -}()); -#endif - -// value initialization -static_assert(abscissa{}.relative().common() == 0 * m); - - -///////// -// CTAD -///////// - -static_assert(comp(quantity_point_kind(width(0 * m)), abscissa{})); -static_assert(same(quantity_point_kind(abscissa(0 * m)), abscissa{})); - - -//////////////////////////// -// construction from a rep -//////////////////////////// - -static_assert(construct_from_only>(1.0).relative().common() == 1); -static_assert(construct_from_only>(1.0f).relative().common() == 1); -static_assert(construct_from_only>(1).relative().common() == 1); -static_assert(construct_from_only>(short{1}).relative().common() == 1); -static_assert(construct_from_only>(1).relative().common() == 1); -static_assert(construct_from_only>(1).relative().common() == 1); -static_assert(construct_from_only>(1LL).relative().common().number() == 1); -static_assert(construct_from_only>(1).relative().common().number() == 1); -static_assert(!constructible_or_convertible_from>(1.0)); -static_assert(!constructible_or_convertible_from>(1.0)); -static_assert(!constructible_or_convertible_from>(1.0)); -static_assert(!constructible_or_convertible_from>(1.0f)); -static_assert(!constructible_or_convertible_from>(1)); -static_assert(!constructible_or_convertible_from>(short{1})); -static_assert(!constructible_or_convertible_from>(1)); - - -///////////////////////////////// -// construction from a quantity -///////////////////////////////// - -// clang-format off -static_assert(construct_from_only>(1 * m).relative().common() == 1 * m); -static_assert(construct_from_only>(1 * m).relative().common() == 1 * m); -static_assert(construct_from_only>(1 * km).relative().common() == 1 * km); -static_assert(construct_from_only>(1ULL * m).relative().common() == 1 * m); -// static_assert(construct_from_only>(1 * cgs_cm).relative().common() == 1 * cm); // TODO: Fix #210 -static_assert(construct_from_only>(1 * m).relative().common() == 1 * m); -static_assert(construct_from_only>(1.0 * km).relative().common() == 1 * km); -static_assert(construct_from_only>(1 * cgs_cm).relative().common() == 1 * cm); -static_assert(construct_from_only>(1.0 * cgs_cm).relative().common() == 1 * cm); -static_assert(!constructible_or_convertible_from>(1 * mm)); -static_assert(!constructible_or_convertible_from>(1.0 * m)); -static_assert(!constructible_or_convertible_from>(1.0 * km)); -static_assert(!constructible_or_convertible_from>(1 * cgs_cm)); -static_assert(!constructible_or_convertible_from>(quantity(1))); -static_assert(!constructible_or_convertible_from>(1 * s)); -static_assert(!constructible_or_convertible_from>(1s)); - -static_assert(construct_from_only>(quantity(1)).relative().common() == 1); -static_assert(construct_from_only>(dimensionless(1)).relative().common() == 0.01); -static_assert(construct_from_only>(dimensionless(1)).relative().common() == 0.01); -static_assert(construct_from_only>(dimensionless(1)).relative().common().number() == 1); -static_assert(construct_from_only>(quantity(1)).relative().common().number() == 100); -static_assert(!constructible_or_convertible_from>(quantity(1.0))); -static_assert(!constructible_or_convertible_from>(dimensionless(1))); -static_assert(!constructible_or_convertible_from>(quantity(1.0))); -static_assert(!constructible_or_convertible_from>(dimensionless(1))); -static_assert(!constructible_or_convertible_from>(1 * m)); -static_assert(!constructible_or_convertible_from>(1 * s)); -static_assert(!constructible_or_convertible_from>(1s)); -// clang-format on - - -/////////////////////////////////////// -// construction from a quantity point -/////////////////////////////////////// - -static_assert(construct_from_only>(1 * m).relative().common() == 1 * m); -static_assert(construct_from_only>(quantity_point(short{1} * m)).relative().common() == 1 * m); -static_assert(construct_from_only>(quantity_point(1 * m)).relative().common() == 1 * m); -static_assert(construct_from_only>(quantity_point(1 * km)).relative().common() == 1 * km); -static_assert(construct_from_only>(quantity_point(1 * m)).relative().common() == 1 * m); -static_assert(construct_from_only>(quantity_point(1 * km)).relative().common() == 1 * km); -static_assert(construct_from_only>(quantity_point(1.0 * m)).relative().common() == 1 * m); -static_assert(construct_from_only>(quantity_point(1.0 * mm)).relative().common() == 1 * mm); -static_assert(!constructible_or_convertible_from>(quantity_point(1 * mm))); -static_assert(!constructible_or_convertible_from>(quantity_point(1.0 * m))); -static_assert(!constructible_or_convertible_from>(quantity_point(1.0 * km))); -static_assert(!constructible_or_convertible_from>(quantity_point(1.0 * (m * m)))); -static_assert(!constructible_or_convertible_from>(quantity_point(1.0 * s))); - -static_assert(construct_from_only>(quantity_point, metre>(1 * m)) - .relative() - .common() == 1 * m); -static_assert(construct_from_only>(quantity_point, metre>(1 * m)) - .relative() - .common() == 1 * m); -static_assert(!constructible_or_convertible_from>(quantity_point(1.0 * m))); - -// clang-format off -static_assert(construct_from_only>(quantity_point(1)).relative().common() == 1); -static_assert(construct_from_only>(quantity_point(1)).relative().common() == 1); -static_assert(construct_from_only>(quantity_point(1)).relative().common() == 1); -static_assert(construct_from_only>(quantity_point(dimensionless(1))).relative().common() == 0.01); -static_assert(construct_from_only>(quantity_point(1.0)).relative().common() == 1); -static_assert(construct_from_only>(quantity_point(dimensionless(1.0))).relative().common() == 0.01); -static_assert(construct_from_only>(quantity_point(1)).relative().common().number() == 100); -static_assert(construct_from_only>(quantity_point(dimensionless(1))).relative().common().number() == 1); -static_assert(!constructible_or_convertible_from>(quantity_point(1.0))); -static_assert(!constructible_or_convertible_from>(quantity_point(dimensionless(1)))); -static_assert(!constructible_or_convertible_from>(quantity_point(1.0))); -static_assert(!constructible_or_convertible_from>(quantity_point(dimensionless(1)))); -static_assert(!constructible_or_convertible_from>(quantity_point(dimensionless(1)))); -static_assert(!constructible_or_convertible_from>(quantity_point(1.0 * s))); - -// clang-format on -static_assert( - construct_from_only>(sys_seconds{42s}).relative().common() == - 42 * s); -static_assert(!constructible_or_convertible_from>(sys_seconds{42s}), - "no implicit conversion to/from dynamic_origin"); - - -////////////////////////////////////// -// construction from a quantity kind -////////////////////////////////////// - -// clang-format off -static_assert(construct_from_only>(width(1 * m)).relative().common() == 1 * m); -static_assert(construct_from_only>(width(1ULL * km)).relative().common() == 1 * km); -static_assert(construct_from_only>(width(1 * cgs_cm)).relative().common() == 1 * cm); -static_assert(construct_from_only>(width(1 * cgs_cm)).relative().common() == 1 * cm); -static_assert(construct_from_only>(width(1 * m)).relative().common() == 1 * m); -static_assert(construct_from_only>(width(1.0 * mm)).relative().common() == 1 * mm); -static_assert(construct_from_only>(width(1ULL * km)).relative().common() == 1 * km); -static_assert(!constructible_or_convertible_from>(width(1.0 * m))); -static_assert(!constructible_or_convertible_from>(width(1 * mm))); -static_assert(!constructible_or_convertible_from>(height(1 * m))); -static_assert(!constructible_or_convertible_from>(abscissa_kind{}, width(1.0 * m))); -static_assert(!constructible_or_convertible_from>(abscissa_kind{}, width(1 * mm))); -static_assert(!constructible_or_convertible_from>(abscissa_kind{}, height(1 * m))); - -static_assert(construct_from_only>(apples(1)).relative().common() == 1); -static_assert(construct_from_only>(apples(dimensionless(1))).relative().common() == 0.01); -static_assert(construct_from_only>(apples(1)).relative().common().number() == 100); -static_assert(construct_from_only>(apples(dimensionless(1))).relative().common().number() == 1); -static_assert(!constructible_or_convertible_from>(apples(1.0))); -static_assert(!constructible_or_convertible_from>(apples(dimensionless(1)))); -static_assert(!constructible_or_convertible_from>(apples(1.0))); -static_assert(!constructible_or_convertible_from>(apples(dimensionless(1)))); -static_assert(!constructible_or_convertible_from>(oranges(1))); -// clang-format on - - -////////////////////////////////////////////////// -// construction from another quantity point kind -////////////////////////////////////////////////// - -// clang-format off -static_assert(construct_and_convert_from>(abscissa(1 * m)).relative().common() == 1 * m); -static_assert(construct_and_convert_from>(abscissa(1ULL * km)).relative().common() == 1 * km); -static_assert(construct_and_convert_from>(abscissa(1ULL * m)).relative().common() == 1 * m); -static_assert(construct_and_convert_from>(abscissa(1 * cgs_cm)).relative().common() == 1 * cm); -static_assert(construct_and_convert_from>(abscissa(1 * cgs_cm)).relative().common() == 1 * cm); -static_assert(!constructible_or_convertible_from>(abscissa(1.0 * m))); -static_assert(!constructible_or_convertible_from>(abscissa(1 * m))); -static_assert(!constructible_or_convertible_from>(ordinate(1 * m))); -static_assert(!constructible_or_convertible_from>(quantity_point_kind(1 * s))); - -static_assert(construct_and_convert_from>(nth_apple(1)).relative().common() == 1); -static_assert(construct_and_convert_from>(nth_apple(dimensionless(1))).relative().common() == 0.01); -static_assert(construct_and_convert_from>(nth_apple(1)).relative().common().number() == 100); -static_assert(construct_and_convert_from>(nth_apple(dimensionless(1))).relative().common().number() == 1); -static_assert(!constructible_or_convertible_from>(nth_apple(1.0))); -static_assert(!constructible_or_convertible_from>(nth_apple(dimensionless(1)))); -static_assert(!constructible_or_convertible_from>(nth_apple(1.0))); -static_assert(!constructible_or_convertible_from>(nth_apple(dimensionless(1)))); -static_assert(!constructible_or_convertible_from>(nth_orange(1))); -static_assert(!constructible_or_convertible_from>(abscissa(1 * m))); -// clang-format on - -static_assert(!constructible_or_convertible_from>( - quantity_point_kind{}), - "no implicit conversion to/from dynamic_origin"); -static_assert(!constructible_or_convertible_from>( - quantity_point_kind{}), - "no implicit conversion to/from dynamic_origin"); -static_assert(!constructible_or_convertible_from>(screen_si_cgs_width(1 * m)), - "base kinds are not the same (required by equivalent)"); - - -////////////////////// -// other conversions -////////////////////// - -static_assert(!std::is_convertible_v, int>); -static_assert(!std::is_convertible_v, dimensionless>); -static_assert(!std::is_convertible_v, length>); -static_assert(!std::is_convertible_v, width>); -static_assert(!std::is_convertible_v, height>); -static_assert(!std::is_convertible_v, quantity_point, metre, int>>); - - -//////////////////////// -// assignment operator -//////////////////////// - -// clang-format off -static_assert((abscissa(2 * m) = abscissa(1 * m)).relative().common() == 1 * m); -static_assert((abscissa(2 * m) = abscissa(1 * km)).relative().common() == 1 * km); -static_assert(!std::is_assignable_v, abscissa>); -static_assert(!std::is_assignable_v, abscissa>); -// clang-format on - - -///////////////////// -// member operators -///////////////////// - -#if !defined(UNITS_COMP_MSVC) || defined(NDEBUG) -static_assert([]() { - const width w(1 * m); - [[maybe_unused]] quantity_point_kind x(w); - assert(&++x == &x && x.relative().common() == 2 * m); - assert(&--x == &x && x.relative().common() == 1 * m); - assert((x++).relative().common() == 1 * m && x.relative().common() == 2 * m); - assert((x--).relative().common() == 2 * m && x.relative().common() == 1 * m); - assert(&(x += w) == &x && x.relative().common() == 2 * m); - assert(&(x -= w) == &x && x.relative().common() == 1 * m); - return true; -}()); -#endif - -template -concept invalid_compound_assignments_ = requires(quantity_point_kind x, Qx q) { - requires !requires { x += q; }; - requires !requires { x -= q; }; -}; -template -concept invalid_compound_assignments = requires(quantity_point_kind x) { - requires !requires { x += 1; }; - requires !requires { x -= 1; }; - requires invalid_compound_assignments_>; - requires invalid_compound_assignments_>; - requires invalid_compound_assignments_>; - requires invalid_compound_assignments_, metre, int>>; - requires invalid_compound_assignments_; -}; -static_assert(invalid_compound_assignments); -static_assert(invalid_compound_assignments_); -#if __cpp_lib_chrono >= 201907L -static_assert(invalid_compound_assignments_); -#endif - - -///////////////////////// -// non-member operators -///////////////////////// - -// clang-format off -static_assert(comp(abscissa(2 * m) + width(3 * m), abscissa(5 * m))); -static_assert(comp(abscissa(2 * m) + width(3. * m), abscissa(5. * m))); -static_assert(comp(abscissa(2. * m) + width(3 * m), abscissa(5. * m))); -static_assert(comp(abscissa(2 * km) + width(3e3 * m), abscissa(5e3 * m))); -static_assert(comp(abscissa(2e3 * m) + width(3 * km), abscissa(5e3 * m))); -static_assert(comp(width(2 * m) + abscissa(3 * m), abscissa(5 * m))); -static_assert(comp(width(2 * m) + abscissa(3. * m), abscissa(5. * m))); -static_assert(comp(width(2. * m) + abscissa(3 * m), abscissa(5. * m))); -static_assert(comp(width(2 * km) + abscissa(3e3 * m), abscissa(5e3 * m))); -static_assert(comp(width(2e3 * m) + abscissa(3 * km), abscissa(5e3 * m))); -static_assert(!std::is_invocable_v, abscissa, double>); -static_assert(!std::is_invocable_v, abscissa, length>); -static_assert(!std::is_invocable_v, abscissa, quantity_point, metre>>); -static_assert(!std::is_invocable_v, abscissa, height>); -static_assert(!std::is_invocable_v, abscissa, abscissa>); -static_assert(!std::is_invocable_v, abscissa, abscissa>); -static_assert(!std::is_invocable_v, abscissa, abscissa>); -static_assert(!std::is_invocable_v, height, abscissa>); -static_assert(!std::is_invocable_v, quantity_point, metre>, abscissa>); -static_assert(!std::is_invocable_v, length, abscissa>); -static_assert(!std::is_invocable_v, double, abscissa>); - -static_assert(comp(abscissa(2 * m) - width(3 * m), abscissa(-1 * m))); -static_assert(comp(abscissa(2 * m) - width(3. * m), abscissa(-1. * m))); -static_assert(comp(abscissa(2. * m) - width(3 * m), abscissa(-1. * m))); -static_assert(comp(abscissa(2 * km) - width(3e3 * m), abscissa(-1e3 * m))); -static_assert(comp(abscissa(2e3 * m) - width(3 * km), abscissa(-1e3 * m))); -static_assert(same(abscissa(2 * m) - abscissa(3 * m), width(-1 * m))); -static_assert(same(abscissa(2 * m) - abscissa(3. * m), width(-1. * m))); -static_assert(same(abscissa(2. * m) - abscissa(3 * m), width(-1. * m))); -static_assert(comp(abscissa(2 * km) - abscissa(3e3 * m), width(-1e3 * m))); -static_assert(comp(abscissa(2e3 * m) - abscissa(3 * km), width(-1e3 * m))); -static_assert(!std::is_invocable_v, abscissa, double>); -static_assert(!std::is_invocable_v, abscissa, length>); -static_assert(!std::is_invocable_v, abscissa, quantity_point, metre>>); -static_assert(!std::is_invocable_v, abscissa, height>); -static_assert(!std::is_invocable_v, abscissa, ordinate>); -static_assert(!std::is_invocable_v, ordinate, abscissa>); -static_assert(!std::is_invocable_v, height, abscissa>); -static_assert(!std::is_invocable_v, quantity_point, metre>, abscissa>); -static_assert(!std::is_invocable_v, length, abscissa>); -static_assert(!std::is_invocable_v, double, abscissa>); -static_assert(!std::is_invocable_v, screen_si_width, screen_si_cgs_width>); -// clang-format on - - -///////////////////////// -// comparison operators -///////////////////////// - -// clang-format off -static_assert(abscissa(1 * m) == abscissa(1 * m)); -static_assert(abscissa(1 * m) == abscissa(1.0 * m)); -static_assert(abscissa(1 * m) == abscissa(1000 * mm)); -static_assert(abscissa(1 * m) == abscissa(1e3 * mm)); -static_assert(abscissa(2 * m) != abscissa(1 * m)); -static_assert(abscissa(2 * m) != abscissa(1.0 * cgs_cm)); -static_assert(std::equality_comparable_with, abscissa>); -static_assert(std::equality_comparable_with, abscissa>); -static_assert(std::equality_comparable_with, abscissa>); -static_assert(std::equality_comparable_with, abscissa>); -// clang-format on -template -concept invalid_equality = requires(quantity_point_kind x, Int i) { - requires !requires { x == 1; }; - requires !requires { x != 1.0; }; - requires !requires { x == 1 * m; }; - requires !requires { x != 1.0 * cgs_cm; }; - requires !requires { x == 1 * km; }; - requires !requires { x != quantity(1); }; - requires !requires { x == dimensionless(1.0); }; - requires !requires { x != width(1 * m); }; - requires !requires { x == width(1.0 * km); }; - requires !requires { x != height(1 * m); }; - requires !requires { x == height(1.0 * km); }; - requires !requires { x == rate_of_climb(1.0 * (km / h)); }; - requires !requires { x != quantity_point(1 * m); }; - requires !requires { x == quantity_point(1.0 * mm); }; - requires !requires { x != quantity_point(quantity(1)); }; - requires !requires { x == quantity_point(dimensionless(1.0)); }; - requires !requires { x != quantity_point_kind(cgs_width(1 * m)); }; - requires !requires { x == ordinate(1 * m); }; - requires !requires { screen_si_width{} != screen_si_cgs_width{}; }; -}; -static_assert(invalid_equality); - -// clang-format off -static_assert(abscissa(1 * m) < abscissa(2 * m)); -static_assert(abscissa(1 * m) <= abscissa(2.0 * m)); -static_assert(abscissa(1 * m) <= abscissa(1 * km)); -static_assert(abscissa(1 * m) >= abscissa(1e3 * mm)); -static_assert(abscissa(2 * m) >= abscissa(1 * mm)); -static_assert(abscissa(2 * m) > abscissa(1 * cgs_cm)); -static_assert(std::three_way_comparable_with, abscissa>); -static_assert(std::three_way_comparable_with, abscissa>); -static_assert(std::three_way_comparable_with, abscissa>); -static_assert(std::three_way_comparable_with, abscissa>); -// clang-format on -template -concept invalid_relational = requires(quantity_point_kind x, Int i) { - requires !requires { x < 1; }; - requires !requires { x <= 1.0; }; - requires !requires { x >= 1 * m; }; - requires !requires { x > 1.0 * cgs_cm; }; - requires !requires { x <=> 1 * km; }; - requires !requires { x < quantity(1); }; - requires !requires { x <= dimensionless(1.0); }; - requires !requires { x >= width(1 * m); }; - requires !requires { x > width(1.0 * km); }; - requires !requires { x <=> height(1 * m); }; - requires !requires { x < height(1.0 * km); }; - requires !requires { x <= rate_of_climb(1.0 * (km / h)); }; - requires !requires { x >= quantity_point(1 * m); }; - requires !requires { x > quantity_point(1.0 * mm); }; - requires !requires { x <=> quantity_point(quantity(1)); }; - requires !requires { x < quantity_point(dimensionless(1.0)); }; - requires !requires { x <= quantity_point_kind(cgs_width(1 * m)); }; - requires !requires { x >= ordinate(1 * m); }; - requires !requires { screen_si_width{} > screen_si_cgs_width{}; }; -}; -static_assert(invalid_relational); - - -///////////////////////////// -// quantity_point_kind_cast -///////////////////////////// - -// clang-format off -static_assert(same(quantity_point_kind_cast>(abscissa(1 * m)), abscissa(1 * m))); -static_assert(same(quantity_point_kind_cast>(abscissa(1 * m)), abscissa(1.0 * m))); -static_assert(same(quantity_point_kind_cast>(abscissa(999 * m)), abscissa(0 * km))); -static_assert(same(quantity_point_kind_cast>(abscissa(1000 * m)), abscissa(1 * km))); -static_assert(same(quantity_point_kind_cast>(abscissa(999 * m)), abscissa(0.999 * km))); -static_assert(comp(quantity_point_kind_cast>(abscissa(1 * m)), abscissa(1 * m))); -static_assert(comp(quantity_point_kind_cast>(abscissa(1 * m)), abscissa(1.0 * m))); -static_assert(comp(quantity_point_kind_cast>(abscissa(999 * m)), abscissa(0 * km))); -static_assert(comp(quantity_point_kind_cast>(abscissa(1000 * m)), abscissa(1 * km))); -static_assert(comp(quantity_point_kind_cast>(abscissa(999 * m)), abscissa(0.999 * km))); -static_assert(comp(quantity_point_kind_cast(abscissa(1 * m)), abscissa(1.0 * m))); -static_assert(comp(quantity_point_kind_cast(abscissa(1 * m)), abscissa(1 * m))); -static_assert(comp(quantity_point_kind_cast(abscissa(999 * m)), abscissa(0 * km))); -static_assert(comp(quantity_point_kind_cast(abscissa(1000 * m)), abscissa(1 * km))); -static_assert(same(quantity_point_kind_cast>(abscissa(1 * m)), ordinate(1 * m))); -static_assert(same(quantity_point_kind_cast>(abscissa(1 * m)), ordinate(1.0 * m))); -static_assert(same(quantity_point_kind_cast>(abscissa(999 * m)), ordinate(0 * km))); -static_assert(same(quantity_point_kind_cast>(abscissa(1000 * m)), ordinate(1 * km))); -static_assert(same(quantity_point_kind_cast>(abscissa(999 * m)), ordinate(0.999 * km))); -static_assert(comp(quantity_point_kind_cast>(abscissa(1 * m)), ordinate(1 * m))); -static_assert(comp(quantity_point_kind_cast>(abscissa(1 * m)), ordinate(1.0 * m))); -static_assert(comp(quantity_point_kind_cast>(abscissa(999 * m)), ordinate(0 * km))); -static_assert(comp(quantity_point_kind_cast>(abscissa(1000 * m)), ordinate(1 * km))); -static_assert(comp(quantity_point_kind_cast>(abscissa(999 * m)), ordinate(0.999 * km))); -static_assert(comp(quantity_point_kind_cast(abscissa(1 * m)), ordinate(1 * m))); -static_assert(same(quantity_point_kind_cast(abscissa(1 * m)), ordinate(1 * m))); -static_assert(same(quantity_point_kind_cast(abscissa(999 * m)), ordinate(0 * km))); -static_assert(same(quantity_point_kind_cast(abscissa(1000 * m)), ordinate(1 * km))); -static_assert(same(quantity_point_kind_cast>(abscissa(1 * cm)), quantity_point_kind(cgs_width(1 * cgs_cm)))); -static_assert(same(quantity_point_kind_cast(abscissa(1 * cm)), quantity_point_kind(cgs_width(1 * cgs_cm)))); -static_assert(comp(quantity_point_kind_cast(abscissa(1 * cm)), altitude(1 * cgs_cm))); -static_assert(same(quantity_point_kind_cast(abscissa(1 * cm)), altitude(1 * cgs_cm))); -static_assert(same(quantity_point_kind_cast(abscissa(1 * m)), quantity_point_kind(cgs_width(1 * m)))); -static_assert(comp(quantity_point_kind_cast(abscissa(1 * m)), altitude(1 * m))); -static_assert(same(quantity_point_kind_cast(abscissa(1 * m)), altitude(1 * m))); -static_assert(comp(quantity_point_kind_cast(abscissa(1 * cm)), abscissa(1 * cgs_cm))); -static_assert(comp(quantity_point_kind_cast>(abscissa(1 * m)), abscissa(0 * km))); -static_assert(comp(quantity_point_kind_cast>(abscissa(1 * m)), abscissa(100 * cm))); -static_assert(comp(quantity_point_kind_cast>(abscissa(0.01 * m)), abscissa(1 * cm))); -static_assert(comp(quantity_point_kind_cast>(abscissa(1 * cgs_cm)), abscissa(1 * cgs_cm))); -static_assert(same(quantity_point_kind_cast>(screen_si_width(1 * m)), screen_si_cgs_width(1 * m))); -// clang-format on -template -concept invalid_cast = requires(Int i) { - requires !requires { quantity_point_kind_cast>(abscissa(i * m)); }; - requires !requires { quantity_point_kind_cast>(abscissa(i * m)); }; - requires !requires { quantity_point_kind_cast(abscissa(i * m)); }; - requires !requires { quantity_point_kind_cast(abscissa(i * m)); }; - requires !requires { quantity_point_kind_cast(abscissa(i * m)); }; - requires !requires { quantity_point_kind_cast(abscissa(i * m)); }; - requires !requires { quantity_point_kind_cast(abscissa(i * m)); }; - requires !requires { quantity_point_kind_cast(abscissa(i * m)); }; - requires !requires { quantity_point_kind_cast(abscissa(i * m)); }; - requires !requires { quantity_point_kind_cast(abscissa(i * m)); }; - requires !requires { quantity_point_kind_cast(abscissa(i * m)); }; - requires !requires { quantity_point_kind_cast>(abscissa(i * m)); }; - requires !requires { quantity_point_kind_cast(abscissa(i * m)); }; - requires !requires { quantity_point_kind_cast(abscissa(i * m)); }; - requires !requires { - quantity_point_kind_cast, metre, Int>>(abscissa(i * m)); - }; - requires !requires { - quantity_point_kind_cast, one, Int>>(abscissa(i * m)); - }; - requires !requires { - quantity_point_kind_cast, metre, Int>>( - screen_si_width(i * m)); - }; -}; -static_assert(invalid_cast); - - -///////////////////////// -// extensible interface -///////////////////////// - -namespace mylib { - -struct width_kind : kind {}; -struct height_kind : kind {}; -struct abscissa_kind : point_kind {}; -struct ordinate_kind : point_kind {}; - -struct point {}; - -template Abscissa, units::QuantityPointKindOf Ordinate> -point operator+(Abscissa, Ordinate); - -} // namespace mylib - -namespace yourapp { - -static_assert( - is_same_v(1 * m)) + - quantity_point_kind(quantity_kind(1 * m)))>); - -} // namespace yourapp - -} // namespace