feat: allow configuring GSL library use

Resolves #576
This commit is contained in:
Mateusz Pusz
2024-05-30 12:23:14 +02:00
parent 3a792b4057
commit a6562acde5
20 changed files with 199 additions and 94 deletions
+3
View File
@@ -68,6 +68,9 @@ cache_var_values(API_STRING_VIEW_RET AUTO TRUE FALSE)
set(${projectPrefix}API_NO_CRTP AUTO CACHE STRING "Enable class definitions without CRTP idiom")
cache_var_values(API_NO_CRTP AUTO TRUE FALSE)
set(${projectPrefix}API_CONTRACTS GSL-LITE CACHE STRING "Enable contract checking")
cache_var_values(API_CONTRACTS NONE GSL-LITE MS-GSL)
# C++ features
check_cxx_feature_supported(__cpp_lib_format ${projectPrefix}LIB_FORMAT_SUPPORTED)
check_cxx_feature_supported("__cpp_constexpr >= 202211L" ${projectPrefix}STATIC_CONSTEXPR_VARS_IN_CONSTEXPR_FUNCTIONS)
+1 -1
View File
@@ -54,7 +54,7 @@ function(add_mp_units_module name target_name)
# validate and process arguments
validate_unparsed(${name} ARG)
validate_arguments_exists(${name} ARG DEPENDENCIES MODULE_INTERFACE_UNIT)
validate_arguments_exists(${name} ARG MODULE_INTERFACE_UNIT)
if(${projectPrefix}TARGET_SCOPE STREQUAL INTERFACE)
set(SCOPE "INTERFACE")
+20 -6
View File
@@ -31,15 +31,9 @@ function(set_feature_flag name)
endif()
endfunction()
# find dependencies
if(NOT TARGET gsl::gsl-lite)
find_package(gsl-lite REQUIRED)
endif()
# core library definition
add_mp_units_module(
core mp-units-core
DEPENDENCIES gsl::gsl-lite
HEADERS include/mp-units/bits/core_gmf.h
include/mp-units/bits/fmt.h
include/mp-units/bits/get_associated_quantity.h
@@ -91,6 +85,7 @@ set_feature_flag(API_STD_FORMAT)
set_feature_flag(API_STRING_VIEW_RET)
set_feature_flag(API_NO_CRTP)
# Text formatting
if(${projectPrefix}API_STD_FORMAT STREQUAL "FALSE" OR (${projectPrefix}API_STD_FORMAT STREQUAL "AUTO"
AND NOT ${projectPrefix}LIB_FORMAT_SUPPORTED)
)
@@ -100,6 +95,24 @@ if(${projectPrefix}API_STD_FORMAT STREQUAL "FALSE" OR (${projectPrefix}API_STD_F
target_link_libraries(mp-units-core ${${projectPrefix}TARGET_SCOPE} fmt::fmt)
endif()
# Contracts checking
if(${projectPrefix}API_CONTRACTS STREQUAL "NONE")
target_compile_definitions(mp-units-core ${${projectPrefix}TARGET_SCOPE} ${projectPrefix}API_CONTRACTS=0)
elseif(${projectPrefix}API_CONTRACTS STREQUAL "GSL-LITE")
if(NOT TARGET gsl::gsl-lite)
find_package(gsl-lite REQUIRED)
endif()
target_link_libraries(mp-units-core ${${projectPrefix}TARGET_SCOPE} gsl::gsl-lite)
target_compile_definitions(mp-units-core ${${projectPrefix}TARGET_SCOPE} ${projectPrefix}API_CONTRACTS=2)
elseif(${projectPrefix}API_CONTRACTS STREQUAL "MS-GSL")
if(NOT TARGET Microsoft.GSL::GSL)
find_package(Microsoft.GSL REQUIRED)
endif()
target_link_libraries(mp-units-core ${${projectPrefix}TARGET_SCOPE} Microsoft.GSL::GSL)
target_compile_definitions(mp-units-core ${${projectPrefix}TARGET_SCOPE} ${projectPrefix}API_CONTRACTS=3)
endif()
# C++20 modules
if(${projectPrefix}BUILD_CXX_MODULES)
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18)
@@ -112,6 +125,7 @@ if(${projectPrefix}BUILD_CXX_MODULES)
endif()
endif()
# UTF-8 source and execution character set
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
target_compile_options(
mp-units-core ${${projectPrefix}TARGET_SCOPE}
@@ -22,7 +22,6 @@
#pragma once
#include <gsl/gsl-lite.hpp>
#include <mp-units/bits/hacks.h>
#include <mp-units/compat_macros.h>
#include <array>
+5 -6
View File
@@ -35,7 +35,6 @@
#include <mp-units/ext/algorithm.h>
#ifndef MP_UNITS_IN_MODULE_INTERFACE
#include <gsl/gsl-lite.hpp>
#include <array>
#include <concepts>
#include <cstdint>
@@ -138,7 +137,7 @@ template<typename Char>
template<typename Int>
[[nodiscard]] constexpr std::make_unsigned_t<Int> to_unsigned(Int value)
{
gsl_Expects(std::is_unsigned_v<Int> || value >= 0);
MP_UNITS_EXPECTS(std::is_unsigned_v<Int> || value >= 0);
return static_cast<std::make_unsigned_t<Int>>(value);
}
@@ -201,7 +200,7 @@ MP_UNITS_EXPORT_END
template<typename Char>
[[nodiscard]] constexpr int parse_nonnegative_int(const Char*& begin, const Char* end, int error_value)
{
gsl_Expects(begin != end && '0' <= *begin && *begin <= '9');
MP_UNITS_EXPECTS(begin != end && '0' <= *begin && *begin <= '9');
unsigned value = 0, prev = 0;
auto p = begin;
do {
@@ -262,7 +261,7 @@ template<typename Char, typename Handler>
template<typename Char, typename Handler>
[[nodiscard]] constexpr const Char* parse_arg_id(const Char* begin, const Char* end, Handler& handler)
{
gsl_Expects(begin != end);
MP_UNITS_EXPECTS(begin != end);
Char c = *begin;
if (c != '}' && c != ':') return ::mp_units::detail::do_parse_arg_id(begin, end, handler);
handler.on_auto();
@@ -304,7 +303,7 @@ template<typename Char>
fmt_arg_ref<Char>& ref,
MP_UNITS_STD_FMT::basic_format_parse_context<Char>& ctx)
{
gsl_Expects(begin != end);
MP_UNITS_EXPECTS(begin != end);
if ('0' <= *begin && *begin <= '9') {
const int val = ::mp_units::detail::parse_nonnegative_int(begin, end, -1);
if (val != -1)
@@ -341,7 +340,7 @@ template<typename Char, typename Specs>
[[nodiscard]] constexpr const Char* parse_align(const Char* begin, const Char* end, Specs& specs,
fmt_align default_align = fmt_align::none)
{
gsl_Expects(begin != end);
MP_UNITS_EXPECTS(begin != end);
auto align = fmt_align::none;
auto p = begin + code_point_length(begin);
if (end - p <= 0) p = begin;
+13 -13
View File
@@ -24,9 +24,9 @@
#include <mp-units/bits/hacks.h>
#include <mp-units/bits/module_macros.h>
#include <mp-units/compat_macros.h>
#ifndef MP_UNITS_IN_MODULE_INTERFACE
#include <gsl/gsl-lite.hpp>
#include <compare> // IWYU pragma: export
#include <cstdint>
#include <numeric>
@@ -44,16 +44,16 @@ template<typename T>
{
constexpr std::intmax_t c = std::uintmax_t{1} << (sizeof(std::intmax_t) * 4);
const std::intmax_t a0 = abs(lhs) % c;
const std::intmax_t a1 = abs(lhs) / c;
const std::intmax_t b0 = abs(rhs) % c;
const std::intmax_t b1 = abs(rhs) / c;
[[maybe_unused]] const std::intmax_t a0 = abs(lhs) % c;
[[maybe_unused]] const std::intmax_t a1 = abs(lhs) / c;
[[maybe_unused]] const std::intmax_t b0 = abs(rhs) % c;
[[maybe_unused]] const std::intmax_t b1 = abs(rhs) / c;
// overflow in multiplication
gsl_Assert(a1 == 0 || b1 == 0);
gsl_Assert(a0 * b1 + b0 * a1 < (c >> 1)); // NOLINT(hicpp-signed-bitwise)
gsl_Assert(b0 * a0 <= INTMAX_MAX);
gsl_Assert((a0 * b1 + b0 * a1) * c <= INTMAX_MAX - b0 * a0);
MP_UNITS_ASSERT(a1 == 0 || b1 == 0);
MP_UNITS_ASSERT(a0 * b1 + b0 * a1 < (c >> 1)); // NOLINT(hicpp-signed-bitwise)
MP_UNITS_ASSERT(b0 * a0 <= INTMAX_MAX);
MP_UNITS_ASSERT((a0 * b1 + b0 * a1) * c <= INTMAX_MAX - b0 * a0);
return lhs * rhs;
}
@@ -72,7 +72,7 @@ MP_UNITS_EXPORT struct ratio {
// NOLINTNEXTLINE(bugprone-easily-swappable-parameters, google-explicit-constructor, hicpp-explicit-conversions)
MP_UNITS_CONSTEVAL explicit(false) ratio(std::intmax_t n, std::intmax_t d = 1) : num{n}, den{d}
{
gsl_Expects(den != 0);
MP_UNITS_EXPECTS(den != 0);
if (num == 0)
den = 1;
else {
@@ -112,9 +112,9 @@ MP_UNITS_EXPORT struct ratio {
if (r1.num == r2.num && r1.den == r2.den) return ratio{r1.num, r1.den};
// gcd(a/b,c/d) = gcd(a⋅d, c⋅b) / b⋅d
gsl_Assert(std::numeric_limits<std::intmax_t>::max() / r1.num > r2.den);
gsl_Assert(std::numeric_limits<std::intmax_t>::max() / r2.num > r1.den);
gsl_Assert(std::numeric_limits<std::intmax_t>::max() / r1.den > r2.den);
MP_UNITS_ASSERT(std::numeric_limits<std::intmax_t>::max() / r1.num > r2.den);
MP_UNITS_ASSERT(std::numeric_limits<std::intmax_t>::max() / r2.num > r1.den);
MP_UNITS_ASSERT(std::numeric_limits<std::intmax_t>::max() / r1.den > r2.den);
const std::intmax_t num = std::gcd(r1.num * r2.den, r2.num * r1.den);
const std::intmax_t den = r1.den * r2.den;
+32
View File
@@ -102,5 +102,37 @@ MP_UNITS_DIAGNOSTIC_POP
#endif
// IWYU pragma: end_exports
#endif
#if MP_UNITS_API_CONTRACTS == 2 || __has_include(<gsl/gsl-lite.hpp>)
#include <gsl/gsl-lite.hpp>
#define MP_UNITS_EXPECTS(expr) gsl_Expects(expr)
#define MP_UNITS_EXPECTS_DEBUG(expr) gsl_ExpectsDebug(expr)
#define MP_UNITS_ASSERT(expr) gsl_Assert(expr)
#define MP_UNITS_ASSERT_DEBUG(expr) gsl_AssertDebug(expr)
#elif MP_UNITS_API_CONTRACTS == 3 || __has_include(<gsl/gsl>)
#include <gsl/gsl>
#include <cassert>
#define MP_UNITS_EXPECTS(expr) Expects(expr)
#if defined NDEBUG
#define MP_UNITS_EXPECTS_DEBUG(expr) static_cast<void>(0)
#else
#define MP_UNITS_EXPECTS_DEBUG(expr) Expects(expr)
#endif
#define MP_UNITS_ASSERT(expr) Expects(expr)
#define MP_UNITS_ASSERT_DEBUG(expr) assert(expr)
#else
#define MP_UNITS_EXPECTS(expr) static_cast<void>(0)
#define MP_UNITS_EXPECTS_DEBUG(expr) static_cast<void>(0)
#define MP_UNITS_ASSERT(expr) static_cast<void>(0)
#define MP_UNITS_ASSERT_DEBUG(expr) static_cast<void>(0)
#endif
// NOLINTEND(cppcoreguidelines-macro-usage)
+10 -11
View File
@@ -32,7 +32,6 @@
#include <mp-units/ext/type_traits.h>
#ifndef MP_UNITS_IN_MODULE_INTERFACE
#include <gsl/gsl-lite.hpp>
#include <compare> // IWYU pragma: export
#include <cstddef>
#include <cstdlib>
@@ -78,7 +77,7 @@ public:
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
consteval explicit(false) basic_fixed_string(const CharT (&txt)[N + 1]) noexcept
{
gsl_Expects(txt[N] == CharT{});
MP_UNITS_EXPECTS(txt[N] == CharT{});
for (std::size_t i = 0; i < N; ++i) data_[i] = txt[i];
}
@@ -86,7 +85,7 @@ public:
requires std::convertible_to<std::iter_value_t<It>, CharT>
constexpr basic_fixed_string(It begin, S end)
{
gsl_Expects(std::distance(begin, end) == N);
MP_UNITS_EXPECTS(std::distance(begin, end) == N);
for (auto it = data_; begin != end; ++begin, ++it) *it = *begin;
}
@@ -94,7 +93,7 @@ public:
requires std::convertible_to<std::ranges::range_reference_t<R>, CharT>
constexpr basic_fixed_string(std::from_range_t, R&& r)
{
gsl_Expects(std::ranges::size(r) == N);
MP_UNITS_EXPECTS(std::ranges::size(r) == N);
for (auto it = data_; auto&& v : std::forward<R>(r)) *it++ = std::forward<decltype(v)>(v);
}
@@ -120,7 +119,7 @@ public:
// element access
[[nodiscard]] constexpr const_reference operator[](size_type pos) const
{
gsl_Expects(pos < N);
MP_UNITS_EXPECTS(pos < N);
return data()[pos];
}
@@ -131,12 +130,12 @@ public:
}
[[nodiscard]] constexpr const_reference front() const
{
gsl_Expects(!empty());
MP_UNITS_EXPECTS(!empty());
return (*this)[0];
}
[[nodiscard]] constexpr const_reference back() const
{
gsl_Expects(!empty());
MP_UNITS_EXPECTS(!empty());
return (*this)[N - 1];
}
@@ -191,7 +190,7 @@ public:
[[nodiscard]] consteval friend basic_fixed_string<CharT, N + N2 - 1, Traits> operator+(
const basic_fixed_string& lhs, const CharT (&rhs)[N2]) noexcept
{
gsl_Expects(rhs[N2 - 1] == CharT{});
MP_UNITS_EXPECTS(rhs[N2 - 1] == CharT{});
CharT txt[N + N2];
CharT* it = txt;
for (CharT c : lhs) *it++ = c;
@@ -203,7 +202,7 @@ public:
[[nodiscard]] consteval friend basic_fixed_string<CharT, N1 + N - 1, Traits> operator+(
const CharT (&lhs)[N1], const basic_fixed_string& rhs) noexcept
{
gsl_Expects(lhs[N1 - 1] == CharT{});
MP_UNITS_EXPECTS(lhs[N1 - 1] == CharT{});
CharT txt[N1 + N];
CharT* it = txt;
for (size_t i = 0; i != N1 - 1; ++i) *it++ = lhs[i];
@@ -222,7 +221,7 @@ public:
template<size_t N2>
[[nodiscard]] friend consteval bool operator==(const basic_fixed_string& lhs, const CharT (&rhs)[N2])
{
gsl_Expects(rhs[N2 - 1] == CharT{});
MP_UNITS_EXPECTS(rhs[N2 - 1] == CharT{});
return lhs.view() == std::basic_string_view<CharT, Traits>(std::cbegin(rhs), std::cend(rhs) - 1);
}
@@ -235,7 +234,7 @@ public:
template<size_t N2>
[[nodiscard]] friend consteval auto operator<=>(const basic_fixed_string& lhs, const CharT (&rhs)[N2])
{
gsl_Expects(rhs[N2 - 1] == CharT{});
MP_UNITS_EXPECTS(rhs[N2 - 1] == CharT{});
return lhs.view() <=> std::basic_string_view<CharT, Traits>(std::cbegin(rhs), std::cend(rhs) - 1);
}
@@ -26,6 +26,7 @@
#include <mp-units/bits/hacks.h>
#include <mp-units/bits/module_macros.h>
#include <mp-units/bits/text_tools.h>
#include <mp-units/compat_macros.h>
#include <mp-units/ext/fixed_string.h>
#include <mp-units/ext/type_traits.h>
#include <mp-units/framework/dimension_concepts.h>
@@ -33,7 +34,6 @@
#include <mp-units/framework/symbol_text.h>
#ifndef MP_UNITS_IN_MODULE_INTERFACE
#include <gsl/gsl-lite.hpp>
#include <array>
#include <cstdint>
#include <iterator>
@@ -280,7 +280,8 @@ template<typename CharT, std::output_iterator<CharT> Out, typename... Expr>
constexpr Out dimension_symbol_impl(Out out, const derived_dimension<Expr...>&, const dimension_symbol_formatting& fmt,
bool negative_power)
{
gsl_Expects(negative_power == false);
(void)negative_power;
MP_UNITS_EXPECTS(negative_power == false);
return dimension_symbol_impl<CharT>(out, typename derived_dimension<Expr...>::_num_{},
typename derived_dimension<Expr...>::_den_{}, fmt);
}
@@ -26,6 +26,7 @@
// IWYU pragma: private, include <mp-units/framework.h>
#include <mp-units/bits/module_macros.h>
#include <mp-units/bits/sudo_cast.h>
#include <mp-units/compat_macros.h>
#include <mp-units/framework/customization_points.h>
#include <mp-units/framework/dimension_concepts.h>
#include <mp-units/framework/quantity_concepts.h>
@@ -36,7 +37,6 @@
#include <mp-units/framework/unit_concepts.h>
#ifndef MP_UNITS_IN_MODULE_INTERFACE
#include <gsl/gsl-lite.hpp>
#include <compare> // IWYU pragma: export
#include <utility>
#endif
@@ -353,7 +353,7 @@ public:
friend constexpr decltype(auto) operator%=(Q&& lhs, const quantity& rhs)
{
gsl_ExpectsDebug(rhs != zero());
MP_UNITS_EXPECTS_DEBUG(rhs != zero());
lhs.numerical_value_is_an_implementation_detail_ %= rhs.numerical_value_is_an_implementation_detail_;
return std::forward<Q>(lhs);
}
@@ -393,7 +393,7 @@ public:
}
friend constexpr decltype(auto) operator/=(Q&& lhs, const Value& v)
{
gsl_ExpectsDebug(v != quantity_values<Value>::zero());
MP_UNITS_EXPECTS_DEBUG(v != quantity_values<Value>::zero());
lhs.numerical_value_is_an_implementation_detail_ /= v;
return std::forward<Q>(lhs);
}
@@ -407,7 +407,7 @@ public:
}
friend constexpr decltype(auto) operator/=(Q1&& lhs, const Q2& rhs)
{
gsl_ExpectsDebug(rhs != rhs.zero());
MP_UNITS_EXPECTS_DEBUG(rhs != rhs.zero());
lhs.numerical_value_is_an_implementation_detail_ /= rhs.numerical_value_is_an_implementation_detail_;
return std::forward<Q1>(lhs);
}
@@ -451,7 +451,7 @@ template<auto R1, typename Rep1, auto R2, typename Rep2>
detail::CommonlyInvocableQuantities<std::modulus<>, quantity<R1, Rep1>, quantity<R2, Rep2>>
[[nodiscard]] constexpr Quantity auto operator%(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs)
{
gsl_ExpectsDebug(rhs != rhs.zero());
MP_UNITS_EXPECTS_DEBUG(rhs != rhs.zero());
using ret = detail::common_quantity_for<std::modulus<>, quantity<R1, Rep1>, quantity<R2, Rep2>>;
const ret ret_lhs(lhs);
const ret ret_rhs(rhs);
@@ -486,7 +486,7 @@ template<auto R1, typename Rep1, auto R2, typename Rep2>
requires detail::InvocableQuantities<std::divides<>, quantity<R1, Rep1>, quantity<R2, Rep2>>
[[nodiscard]] constexpr Quantity auto operator/(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs)
{
gsl_ExpectsDebug(rhs != rhs.zero());
MP_UNITS_EXPECTS_DEBUG(rhs != rhs.zero());
return quantity{lhs.numerical_value_ref_in(get_unit(R1)) / rhs.numerical_value_ref_in(get_unit(R2)), R1 / R2};
}
@@ -495,7 +495,7 @@ template<auto R, typename Rep, typename Value>
detail::InvokeResultOf<get_quantity_spec(R).character, std::divides<>, Rep, const Value&>
[[nodiscard]] constexpr QuantityOf<get_quantity_spec(R)> auto operator/(const quantity<R, Rep>& q, const Value& v)
{
gsl_ExpectsDebug(v != quantity_values<Value>::zero());
MP_UNITS_EXPECTS_DEBUG(v != quantity_values<Value>::zero());
return quantity{q.numerical_value_ref_in(get_unit(R)) / v, R};
}
@@ -27,11 +27,11 @@
// TODO use <algorithm> when moved to C++20 modules (parsing takes too long for each translation unit)
#include <mp-units/bits/hacks.h>
#include <mp-units/bits/module_macros.h>
#include <mp-units/compat_macros.h>
#include <mp-units/ext/algorithm.h>
#include <mp-units/ext/fixed_string.h>
#ifndef MP_UNITS_IN_MODULE_INTERFACE
#include <gsl/gsl-lite.hpp>
#include <compare> // IWYU pragma: export
#include <cstddef>
#include <cstdint>
@@ -95,34 +95,34 @@ public:
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
constexpr explicit(false) symbol_text(char ch) : unicode_(static_cast<char8_t>(ch)), ascii_(ch)
{
gsl_Expects(detail::is_basic_literal_character_set_char(ch));
MP_UNITS_EXPECTS(detail::is_basic_literal_character_set_char(ch));
}
// NOLINTNEXTLINE(*-avoid-c-arrays, google-explicit-constructor, hicpp-explicit-conversions)
consteval explicit(false) symbol_text(const char (&txt)[N + 1]) :
unicode_(detail::to_u8string(basic_fixed_string{txt})), ascii_(txt)
{
gsl_Expects(txt[N] == char{});
gsl_Expects(detail::is_basic_literal_character_set(txt));
MP_UNITS_EXPECTS(txt[N] == char{});
MP_UNITS_EXPECTS(detail::is_basic_literal_character_set(txt));
}
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
constexpr explicit(false) symbol_text(const fixed_string<N>& txt) : unicode_(detail::to_u8string(txt)), ascii_(txt)
{
gsl_Expects(detail::is_basic_literal_character_set(txt.data_));
MP_UNITS_EXPECTS(detail::is_basic_literal_character_set(txt.data_));
}
// NOLINTNEXTLINE(*-avoid-c-arrays)
consteval symbol_text(const char8_t (&u)[N + 1], const char (&a)[M + 1]) : unicode_(u), ascii_(a)
{
gsl_Expects(u[N] == char8_t{});
gsl_Expects(a[M] == char{});
gsl_Expects(detail::is_basic_literal_character_set(a));
MP_UNITS_EXPECTS(u[N] == char8_t{});
MP_UNITS_EXPECTS(a[M] == char{});
MP_UNITS_EXPECTS(detail::is_basic_literal_character_set(a));
}
constexpr symbol_text(const fixed_u8string<N>& u, const fixed_string<M>& a) : unicode_(u), ascii_(a)
{
gsl_Expects(detail::is_basic_literal_character_set(a.data_));
MP_UNITS_EXPECTS(detail::is_basic_literal_character_set(a.data_));
}
[[nodiscard]] constexpr const auto& unicode() const { return unicode_; }
@@ -130,7 +130,7 @@ public:
[[nodiscard]] constexpr bool empty() const
{
gsl_AssertDebug(unicode().empty() == ascii().empty());
MP_UNITS_ASSERT_DEBUG(unicode().empty() == ascii().empty());
return unicode().empty();
}
+3 -2
View File
@@ -28,6 +28,7 @@
#include <mp-units/bits/module_macros.h>
#include <mp-units/bits/ratio.h>
#include <mp-units/bits/text_tools.h>
#include <mp-units/compat_macros.h>
#include <mp-units/ext/algorithm.h>
#include <mp-units/ext/fixed_string.h>
#include <mp-units/ext/type_name.h>
@@ -40,7 +41,6 @@
#include <mp-units/framework/unit_concepts.h>
#ifndef MP_UNITS_IN_MODULE_INTERFACE
#include <gsl/gsl-lite.hpp>
#include <array>
#include <cstdint>
#include <iterator>
@@ -808,7 +808,8 @@ template<typename CharT, std::output_iterator<CharT> Out, typename... Expr>
constexpr Out unit_symbol_impl(Out out, const derived_unit<Expr...>&, const unit_symbol_formatting& fmt,
bool negative_power)
{
gsl_Expects(negative_power == false);
(void)negative_power;
MP_UNITS_EXPECTS(negative_power == false);
return unit_symbol_impl<CharT>(out, typename derived_unit<Expr...>::_num_{}, typename derived_unit<Expr...>::_den_{},
fmt);
}
+5 -1
View File
@@ -26,6 +26,10 @@ if(NOT MP_UNITS_API_STD_FORMAT)
find_dependency(fmt)
endif()
find_dependency(gsl-lite)
if(MP_UNITS_API_CONTRACTS STREQUAL "GSL-LITE")
find_dependency(gsl-lite)
elseif(MP_UNITS_API_CONTRACTS STREQUAL "MS-GSL")
find_dependency(Microsoft.GSL)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/mp-unitsTargets.cmake")