// 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 namespace { using namespace units; template inline constexpr bool is_of_type = std::is_same_v, T>; using one_dim_ = struct one_dim; // clang-format off inline constexpr struct length_dim_ : base_dimension<"L"> {} length_dim; inline constexpr struct time_dim_ : base_dimension<"T"> {} time_dim; inline constexpr struct mass_dim_ : base_dimension<"M"> {} mass_dim; inline constexpr struct frequency_dim_ : decltype(1 / time_dim) {} frequency_dim; inline constexpr struct action_dim_ : decltype(1 / time_dim) {} action_dim; inline constexpr struct area_dim_ : decltype(length_dim * length_dim) {} area_dim; inline constexpr struct volume_dim_ : decltype(area_dim * length_dim) {} volume_dim; inline constexpr struct speed_dim_ : decltype(length_dim / time_dim) {} speed_dim; inline constexpr struct velocity_dim_ : speed_dim_ {} velocity_dim; inline constexpr struct acceleration_dim_ : decltype(speed_dim / time_dim) {} acceleration_dim; inline constexpr struct force_dim_ : decltype(mass_dim * acceleration_dim) {} force_dim; inline constexpr struct moment_of_force_dim_ : decltype(length_dim * force_dim) {} moment_of_force_dim; inline constexpr struct torque_dim_ : decltype(moment_of_force_dim) {} torque_dim; inline constexpr struct pressure_dim_ : decltype(force_dim / area_dim) {} pressure_dim; inline constexpr struct stress_dim_ : decltype(pressure_dim) {} stress_dim; inline constexpr struct strain_dim_ : decltype(stress_dim / stress_dim) {} strain_dim; inline constexpr struct power_dim_ : decltype(force_dim * speed_dim) {} power_dim; inline constexpr struct efficiency_dim_ : decltype(power_dim / power_dim) {} efficiency_dim; inline constexpr struct energy_dim_ : decltype(force_dim * length_dim) {} energy_dim; // clang-format on // concepts verification static_assert(BaseDimension); static_assert(!BaseDimension); static_assert(!DerivedDimension); static_assert(DerivedDimension); static_assert(Dimension); static_assert(Dimension); static_assert(DerivedDimension); static_assert(DerivedDimension); // one_dim static_assert(BaseDimension); // length_dim // derived dimension expression template syntax verification static_assert(is_of_type<1 / time_dim, derived_dimension>>); static_assert(is_of_type<1 / (1 / time_dim), time_dim_>); static_assert(is_of_type); static_assert(is_of_type); static_assert(is_of_type>>); static_assert(is_of_type<1 / time_dim * one_dim, derived_dimension>>); static_assert(is_of_type>); static_assert(is_of_type>>); static_assert( is_of_type, time_dim_>>); static_assert( is_of_type, time_dim_>>); static_assert( is_of_type, time_dim_>>); static_assert( is_of_type, time_dim_>>); static_assert(is_of_type<1 / time_dim * length_dim, derived_dimension>>); static_assert(is_of_type<1 / time_dim * time_dim, one_dim_>); static_assert(is_of_type); static_assert(is_of_type<1 / time_dim / one_dim, derived_dimension>>); static_assert(is_of_type); static_assert(is_of_type<1 / time_dim * (1 / time_dim), derived_dimension>>>); static_assert(is_of_type<1 / (time_dim * time_dim), derived_dimension>>>); static_assert(is_of_type<1 / (1 / (time_dim * time_dim)), derived_dimension>>); static_assert( is_of_type>>>); static_assert(is_of_type, per>>>); static_assert(is_of_type); static_assert(is_of_type); static_assert(is_of_type>>); static_assert( is_of_type>>>); static_assert(is_of_type<1 / (speed_dim * speed_dim) * length_dim, derived_dimension, per>>); // comparisons of the same dimensions static_assert(length_dim == length_dim); static_assert(speed_dim == speed_dim); // comparisons of equivalent dimensions (named vs unnamed/derived) static_assert(length_dim / length_dim == one_dim); static_assert(1 / time_dim != frequency_dim); static_assert(convertible(1 / time_dim, frequency_dim)); static_assert(1 / frequency_dim == time_dim); static_assert(frequency_dim * time_dim == one_dim); static_assert(std::is_same_v, frequency_dim_>); static_assert(std::is_same_v, frequency_dim_>); static_assert(length_dim * length_dim != area_dim); static_assert(convertible(length_dim * length_dim, area_dim)); static_assert(length_dim * length_dim != volume_dim); static_assert(area_dim / length_dim == length_dim); static_assert(std::is_same_v, area_dim_>); static_assert(std::is_same_v, area_dim_>); static_assert(length_dim * length_dim * length_dim != volume_dim); static_assert(area_dim * length_dim != volume_dim); static_assert(volume_dim / length_dim != area_dim); static_assert(volume_dim / length_dim / length_dim == length_dim); static_assert(area_dim * area_dim / length_dim != volume_dim); static_assert(area_dim * (area_dim / length_dim) != volume_dim); static_assert(volume_dim / (length_dim * length_dim) == length_dim); static_assert(length_dim / time_dim != speed_dim); static_assert(length_dim * time_dim != speed_dim); static_assert(length_dim / time_dim / time_dim != speed_dim); static_assert(length_dim / speed_dim == time_dim); static_assert(speed_dim * time_dim == length_dim); static_assert(std::is_same_v, speed_dim_>); static_assert(std::is_same_v, speed_dim_>); static_assert(std::is_same_v, decltype(length_dim / time_dim)>); static_assert(length_dim / time_dim / time_dim != acceleration_dim); static_assert(length_dim / (time_dim * time_dim) != acceleration_dim); static_assert(speed_dim / time_dim != acceleration_dim); static_assert(speed_dim / acceleration_dim == time_dim); static_assert(acceleration_dim * time_dim != speed_dim); static_assert(acceleration_dim * (time_dim * time_dim) == length_dim); static_assert(acceleration_dim / speed_dim != frequency_dim); // comparison of convertible named dimensions static_assert(velocity_dim != speed_dim); static_assert(convertible(speed_dim, velocity_dim)); static_assert(std::is_same_v, velocity_dim_>); static_assert(std::is_same_v, velocity_dim_>); // comparisons of equivalent but not convertible dimensions static_assert(energy_dim != torque_dim); static_assert(!convertible(energy_dim, torque_dim)); static_assert(force_dim * length_dim != energy_dim); static_assert(force_dim * length_dim != torque_dim); static_assert(convertible(force_dim * length_dim, energy_dim)); static_assert(convertible(force_dim * length_dim, torque_dim)); template concept no_common_type = requires { requires !requires { typename std::common_type_t; }; requires !requires { typename std::common_type_t; }; }; static_assert(no_common_type); static_assert(frequency_dim != action_dim); static_assert(!convertible(frequency_dim, action_dim)); static_assert(no_common_type); // Dimensionless static_assert(convertible(power_dim / power_dim, efficiency_dim)); static_assert(power_dim / power_dim != efficiency_dim); static_assert(one_dim != efficiency_dim); static_assert(!convertible(efficiency_dim, strain_dim)); static_assert(efficiency_dim != strain_dim); static_assert(stress_dim / stress_dim != strain_dim); static_assert(stress_dim / stress_dim != efficiency_dim); static_assert(convertible(stress_dim / stress_dim, strain_dim)); static_assert(convertible(stress_dim / stress_dim, efficiency_dim)); // comparison of not equivalent dimensions static_assert(length_dim != time_dim); static_assert(!convertible(length_dim, time_dim)); static_assert(acceleration_dim != speed_dim); static_assert(!convertible(acceleration_dim, speed_dim)); } // namespace