feat: freestanding support added

Resolves #564, #565, and #556
This commit is contained in:
Mateusz Pusz
2024-05-30 19:50:02 +02:00
parent c151740a43
commit cd36e6f974
30 changed files with 387 additions and 60 deletions
+7
View File
@@ -42,6 +42,9 @@ message(STATUS "${projectPrefix}BUILD_AS_SYSTEM_HEADERS: ${${projectPrefix}BUILD
option(${projectPrefix}BUILD_CXX_MODULES "Add C++ modules to the list of default targets" OFF)
message(STATUS "${projectPrefix}BUILD_CXX_MODULES: ${${projectPrefix}BUILD_CXX_MODULES}")
option(${projectPrefix}API_FREESTANDING "Builds only freestanding part of the library" OFF)
message(STATUS "${projectPrefix}API_FREESTANDING: ${${projectPrefix}API_FREESTANDING}")
if(${projectPrefix}BUILD_AS_SYSTEM_HEADERS)
set(${projectPrefix}_AS_SYSTEM SYSTEM)
endif()
@@ -71,6 +74,10 @@ 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)
if(${projectPrefix}API_FREESTANDING AND NOT ${projectPrefix}API_CONTRACTS STREQUAL "NONE")
message(FATAL_ERROR "'${projectPrefix}API_CONTRACTS' should be set to 'NONE' for a freestanding build")
endif()
# 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)
+22 -6
View File
@@ -35,7 +35,6 @@ endfunction()
add_mp_units_module(
core mp-units-core
HEADERS include/mp-units/bits/core_gmf.h
include/mp-units/bits/fmt.h
include/mp-units/bits/get_associated_quantity.h
include/mp-units/bits/get_common_base.h
include/mp-units/bits/hacks.h
@@ -73,14 +72,27 @@ add_mp_units_module(
include/mp-units/framework/value_cast.h
include/mp-units/compat_macros.h
include/mp-units/concepts.h
include/mp-units/format.h
include/mp-units/framework.h
include/mp-units/math.h
include/mp-units/ostream.h
include/mp-units/random.h
MODULE_INTERFACE_UNIT mp-units-core.cpp
)
if(NOT ${projectPrefix}API_FREESTANDING)
target_sources(
mp-units-core
PUBLIC FILE_SET
HEADERS
BASE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/include
FILES
include/mp-units/bits/fmt.h
include/mp-units/bits/requires_hosted.h
include/mp-units/math.h
include/mp-units/ostream.h
include/mp-units/format.h
include/mp-units/random.h
)
endif()
set_feature_flag(API_STD_FORMAT)
set_feature_flag(API_STRING_VIEW_RET)
set_feature_flag(API_NO_CRTP)
@@ -133,4 +145,8 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
)
endif()
# target_compile_options(mp-units-core ${${projectPrefix}TARGET_SCOPE} "-ftime-trace")
# Freestanding
target_compile_definitions(
mp-units-core ${${projectPrefix}TARGET_SCOPE}
${projectPrefix}HOSTED=$<NOT:$<BOOL:${${projectPrefix}API_FREESTANDING}>>
)
+11 -5
View File
@@ -25,7 +25,6 @@
#include <mp-units/bits/hacks.h>
#include <mp-units/compat_macros.h>
#include <array>
#include <cmath>
#include <compare>
#include <concepts>
#include <cstddef>
@@ -35,18 +34,23 @@
#include <initializer_list>
#include <iterator>
#include <limits>
#include <locale>
#include <numbers>
#include <numeric>
#include <optional>
#include <random>
#include <sstream>
#include <string>
#include <ranges>
#include <string_view>
#include <tuple>
#include <type_traits>
#include <utility>
#if MP_UNITS_HOSTED
#include <cmath>
#include <locale>
#include <ostream>
#include <random>
#include <sstream>
#include <string>
#if MP_UNITS_USE_FMTLIB
MP_UNITS_DIAGNOSTIC_PUSH
MP_UNITS_DIAGNOSTIC_IGNORE_UNREACHABLE
@@ -57,6 +61,8 @@ MP_UNITS_DIAGNOSTIC_POP
#include <format>
#endif
#endif
#if __cpp_lib_text_encoding
#include <text_encoding>
#endif
+4
View File
@@ -73,6 +73,10 @@
#define MP_UNITS_DIAGNOSTIC_IGNORE_DEPRECATED
#endif
#if !defined MP_UNITS_HOSTED && defined __STDC_HOSTED__
#define MP_UNITS_HOSTED __STDC_HOSTED__
#endif
#if MP_UNITS_COMP_MSVC
#define MP_UNITS_TYPENAME typename
@@ -0,0 +1,29 @@
// 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.
#pragma once
#include <mp-units/bits/hacks.h>
#if !MP_UNITS_HOSTED
#error "This header is not available in freestanding mode."
#endif
+3 -2
View File
@@ -23,6 +23,7 @@
#pragma once
#include <mp-units/bits/ratio.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/symbol_text.h>
@@ -100,12 +101,12 @@ constexpr Out copy(const symbol_text<N, M>& txt, text_encoding encoding, Out out
for (const char8_t ch : txt.unicode()) *out++ = static_cast<char>(ch);
return out;
} else
throw std::invalid_argument("Unicode text can't be copied to CharT output");
MP_UNITS_THROW(std::invalid_argument("Unicode text can't be copied to CharT output"));
} else {
if constexpr (is_same_v<CharT, char>)
return ::mp_units::detail::copy(txt.ascii().begin(), txt.ascii().end(), out);
else
throw std::invalid_argument("ASCII text can't be copied to CharT output");
MP_UNITS_THROW(std::invalid_argument("ASCII text can't be copied to CharT output"));
}
}
+13 -18
View File
@@ -40,6 +40,15 @@
#endif
#if MP_UNITS_HOSTED
#define MP_UNITS_THROW(expr) throw expr
#else
#include <cstdlib>
#define MP_UNITS_THROW(expr) std::abort()
#endif
#if MP_UNITS_HOSTED
#if defined MP_UNITS_API_STD_FORMAT && !MP_UNITS_API_STD_FORMAT
#define MP_UNITS_USE_FMTLIB 1
@@ -59,21 +68,7 @@
#define MP_UNITS_FMT_TO_ARG_ID(arg) (arg)
#define MP_UNITS_FMT_FROM_ARG_ID(arg) (arg)
// This re-uses code from fmt;
#if FMT_EXCEPTIONS
#if FMT_MSC_VERSION || defined(__NVCC__)
#define MP_UNITS_THROW(x) ::fmt::detail::do_throw(x)
#else
#define MP_UNITS_THROW(x) throw x
#endif
#else
#define MP_UNITS_THROW(x) \
do { \
FMT_ASSERT(false, (x).what()); \
} while (false)
#endif
#else
#else // MP_UNITS_USE_FMTLIB
#if !defined __cpp_lib_format && !defined MP_UNITS_COMP_CLANG
#error "std::formatting facility not supported"
@@ -83,10 +78,8 @@
#define MP_UNITS_FMT_LOCALE(loc) loc
#define MP_UNITS_FMT_TO_ARG_ID(arg) static_cast<std::size_t>(arg)
#define MP_UNITS_FMT_FROM_ARG_ID(arg) static_cast<int>(arg)
#define MP_UNITS_THROW(arg) throw arg
#endif
#endif // MP_UNITS_USE_FMTLIB
#ifndef MP_UNITS_IN_MODULE_INTERFACE
@@ -104,6 +97,8 @@ MP_UNITS_DIAGNOSTIC_POP
#endif
#endif // MP_UNITS_HOSTED
#if MP_UNITS_API_CONTRACTS == 2 || __has_include(<gsl/gsl-lite.hpp>)
#include <gsl/gsl-lite.hpp>
+12 -1
View File
@@ -35,8 +35,11 @@
#include <compare> // IWYU pragma: export
#include <cstddef>
#include <cstdlib>
#include <ostream>
#include <ranges>
#include <string_view>
#if MP_UNITS_HOSTED
#include <ostream>
#endif
#endif
MP_UNITS_EXPORT
@@ -123,11 +126,14 @@ public:
return data()[pos];
}
#if MP_UNITS_HOSTED
[[nodiscard]] constexpr const_reference at(size_type pos) const
{
if (pos >= size()) throw std::out_of_range("basic_fixed_string::at");
return (*this)[pos];
}
#endif
[[nodiscard]] constexpr const_reference front() const
{
MP_UNITS_EXPECTS(!empty());
@@ -239,11 +245,13 @@ public:
}
// inserters and extractors
#if MP_UNITS_HOSTED
friend std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os,
const basic_fixed_string& str)
{
return os << str.c_str();
}
#endif
};
// deduction guides
@@ -282,6 +290,7 @@ struct std::hash<mp_units::fixed_u32string<N>> : std::hash<std::u32string_view>
template<std::size_t N>
struct std::hash<mp_units::fixed_wstring<N>> : std::hash<std::wstring_view> {};
#if MP_UNITS_HOSTED
// formatting support
template<typename CharT, std::size_t N>
struct MP_UNITS_STD_FMT::formatter<mp_units::basic_fixed_string<CharT, N>> : formatter<std::basic_string_view<CharT>> {
@@ -291,4 +300,6 @@ struct MP_UNITS_STD_FMT::formatter<mp_units::basic_fixed_string<CharT, N>> : for
return formatter<std::basic_string_view<CharT>>::format(std::basic_string_view<CharT>(str), ctx);
}
};
#endif
// NOLINTEND(*-avoid-c-arrays)
+2
View File
@@ -24,6 +24,8 @@
#pragma once
#include <mp-units/bits/requires_hosted.h>
//
#include <mp-units/bits/fmt.h>
#include <mp-units/bits/module_macros.h>
#include <mp-units/compat_macros.h>
@@ -37,8 +37,10 @@
#include <array>
#include <cstdint>
#include <iterator>
#include <string>
#include <string_view>
#if MP_UNITS_HOSTED
#include <string>
#endif
#endif
namespace mp_units {
@@ -318,9 +320,15 @@ MP_UNITS_EXPORT template<dimension_symbol_formatting fmt = dimension_symbol_form
#endif
{
auto get_size = []() consteval {
#if MP_UNITS_HOSTED
std::basic_string<CharT> buffer;
dimension_symbol_to<CharT>(std::back_inserter(buffer), D{}, fmt);
return buffer.size();
#else
std::array<CharT, 128> buffer; // TODO unsafe
auto end = dimension_symbol_to<CharT>(buffer.begin(), D{}, fmt);
return end - buffer.begin();
#endif
};
#if MP_UNITS_API_STRING_VIEW_RET // Permitting static constexpr variables in constexpr functions
+11 -3
View File
@@ -44,8 +44,10 @@
#include <array>
#include <cstdint>
#include <iterator>
#include <string>
#include <string_view>
#if MP_UNITS_HOSTED
#include <string>
#endif
#endif
namespace mp_units {
@@ -718,8 +720,8 @@ constexpr Out print_separator(Out out, const unit_symbol_formatting& fmt)
{
if (fmt.separator == unit_symbol_separator::half_high_dot) {
if (fmt.encoding != text_encoding::unicode)
throw std::invalid_argument(
"'unit_symbol_separator::half_high_dot' can be only used with 'text_encoding::unicode'");
MP_UNITS_THROW(
std::invalid_argument("'unit_symbol_separator::half_high_dot' can be only used with 'text_encoding::unicode'"));
const std::string_view dot = "⋅";
out = detail::copy(dot.begin(), dot.end(), out);
} else {
@@ -844,9 +846,15 @@ MP_UNITS_EXPORT template<unit_symbol_formatting fmt = unit_symbol_formatting{},
#endif
{
auto get_size = []() consteval {
#if MP_UNITS_HOSTED
std::basic_string<CharT> buffer;
unit_symbol_to<CharT>(std::back_inserter(buffer), U{}, fmt);
return buffer.size();
#else
std::array<CharT, 128> buffer; // TODO unsafe
auto end = unit_symbol_to<CharT>(buffer.begin(), U{}, fmt);
return end - buffer.begin();
#endif
};
#if MP_UNITS_API_STRING_VIEW_RET // Permitting static constexpr variables in constexpr functions
+2
View File
@@ -22,6 +22,8 @@
#pragma once
#include <mp-units/bits/requires_hosted.h>
//
#include <mp-units/bits/module_macros.h>
#include <mp-units/framework/customization_points.h>
#include <mp-units/framework/quantity.h>
+2
View File
@@ -23,6 +23,8 @@
#pragma once
#include <mp-units/bits/requires_hosted.h>
//
#include <mp-units/bits/module_macros.h>
#include <mp-units/framework/quantity.h>
#include <mp-units/framework/unit.h>
+4 -1
View File
@@ -8,8 +8,11 @@ export module mp_units.core;
#include <mp-units/compat_macros.h>
#include <mp-units/concepts.h>
#include <mp-units/format.h>
#include <mp-units/framework.h>
#if MP_UNITS_HOSTED
#include <mp-units/format.h>
#include <mp-units/math.h>
#include <mp-units/ostream.h>
#include <mp-units/random.h>
#endif
+15 -4
View File
@@ -25,8 +25,7 @@ cmake_minimum_required(VERSION 3.23)
add_mp_units_module(
systems mp-units-systems
DEPENDENCIES mp-units::core
HEADERS include/mp-units/systems/angular/math.h
include/mp-units/systems/angular/units.h
HEADERS include/mp-units/systems/angular/units.h
include/mp-units/systems/iec80000/binary_prefixes.h
include/mp-units/systems/iec80000/quantities.h
include/mp-units/systems/iec80000/unit_symbols.h
@@ -39,9 +38,7 @@ add_mp_units_module(
include/mp-units/systems/isq/si_quantities.h
include/mp-units/systems/isq/space_and_time.h
include/mp-units/systems/isq/thermodynamics.h
include/mp-units/systems/si/chrono.h
include/mp-units/systems/si/constants.h
include/mp-units/systems/si/math.h
include/mp-units/systems/si/prefixes.h
include/mp-units/systems/si/unit_symbols.h
include/mp-units/systems/si/units.h
@@ -60,3 +57,17 @@ add_mp_units_module(
include/mp-units/systems/usc.h
MODULE_INTERFACE_UNIT mp-units-systems.cpp
)
if(NOT ${projectPrefix}API_FREESTANDING)
target_sources(
mp-units-systems
PUBLIC FILE_SET
HEADERS
BASE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/include
FILES
include/mp-units/systems/angular/math.h
include/mp-units/systems/si/math.h
include/mp-units/systems/si/chrono.h
)
endif()
@@ -23,7 +23,9 @@
#pragma once
// IWYU pragma: begin_exports
#if MP_UNITS_HOSTED
#include <mp-units/systems/angular/math.h>
#endif
#include <mp-units/systems/angular/units.h>
#ifndef MP_UNITS_IN_MODULE_INTERFACE
@@ -22,6 +22,8 @@
#pragma once
#include <mp-units/bits/requires_hosted.h>
//
#include <mp-units/bits/module_macros.h>
#include <mp-units/systems/angular/units.h>
+3 -1
View File
@@ -23,9 +23,11 @@
#pragma once
// IWYU pragma: begin_exports
#if MP_UNITS_HOSTED
#include <mp-units/systems/si/chrono.h>
#include <mp-units/systems/si/constants.h>
#include <mp-units/systems/si/math.h>
#endif
#include <mp-units/systems/si/constants.h>
#include <mp-units/systems/si/prefixes.h>
#include <mp-units/systems/si/unit_symbols.h>
#include <mp-units/systems/si/units.h>
@@ -22,6 +22,8 @@
#pragma once
#include <mp-units/bits/requires_hosted.h>
//
#include <mp-units/bits/module_macros.h>
#include <mp-units/systems/isq/si_quantities.h>
#include <mp-units/systems/si/prefixes.h>
@@ -22,6 +22,8 @@
#pragma once
#include <mp-units/bits/requires_hosted.h>
//
#include <mp-units/bits/module_macros.h>
#include <mp-units/systems/isq/space_and_time.h>
#include <mp-units/systems/si/units.h>