Library updated to the latest cmake common tools

This commit is contained in:
Mateusz Pusz
2020-01-31 17:02:27 +01:00
parent f2163aa098
commit 645570ff57
20 changed files with 121 additions and 91 deletions

View File

@ -52,7 +52,7 @@ BreakConstructorInitializersBeforeComma: true
BreakInheritanceList: AfterColon
# BreakStringLiterals: true
ColumnLimit: 120
# CommentPragmas: '^ IWYU pragma:'
CommentPragmas: '^ NOLINT'
# CompactNamespaces: false
# ConstructorInitializerAllOnOneLineOrOnePerLine: true
# ConstructorInitializerIndentWidth: 4

23
.clang-tidy Normal file
View File

@ -0,0 +1,23 @@
---
Checks: '
*,
-llvm-header-guard,
-llvm-include-order,
-bugprone-branch-clone,
-bugprone-reserved-identifier,
-modernize-use-trailing-return-type,
-fuchsia-default-arguments-calls,
-fuchsia-overloaded-operator,
-fuchsia-statically-constructed-objects,
-fuchsia-trailing-return,
-*-special-member-functions,
-cppcoreguidelines-owning-memory,
-cert-err58-cpp,
-cert-dcl37-c,
-cert-dcl51-cpp
'
WarningsAsErrors: '*'
HeaderFilterRegex: '.*'
AnalyzeTemporaryDtors: false
FormatStyle: file
...

View File

@ -27,19 +27,24 @@ project(units)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# include common tools and workarounds
include(common/cmake/tools)
include(common/cmake/scripts)
# use Conan configuration if available
conan_init(cmake)
# compilation options and flags used in a project development process
include(common/cmake/compile_flags)
# enable static analysis
#enable_clang_tidy()
#enable_iwyu()
# set restrictive compilation warnings
set_warnings(TREAT_AS_ERRORS)
# add project code
add_subdirectory(src)
# add unit tests
add_subdirectory(test)
# add usage example
add_subdirectory(example)
# add unit tests
enable_testing()
add_subdirectory(test)

View File

@ -21,15 +21,14 @@
# SOFTWARE.
from conans import ConanFile, CMake, tools
from conans.tools import load, Version
from conans.tools import Version
from conans.errors import ConanInvalidConfiguration
import re
import os
def get_version():
try:
content = load("src/CMakeLists.txt")
content = tools.load("src/CMakeLists.txt")
version = re.search(r"project\([^\)]+VERSION (\d+\.\d+\.\d+)[^\)]*\)", content).group(1)
return version.strip()
except Exception:
@ -44,20 +43,32 @@ class UnitsConan(ConanFile):
url = "https://github.com/mpusz/units"
description = "Physical Units library for C++"
exports = ["LICENSE.md"]
exports_sources = ["src/*", "test/*", "cmake/*", "example/*","CMakeLists.txt"]
settings = "os", "compiler", "build_type", "arch"
requires = (
"fmt/6.1.0"
)
build_requires = (
"Catch2/2.11.0@catchorg/stable"
)
scm = {
"type": "git",
"url": "auto",
"revision": "auto",
"submodule": "recursive"
}
generators = "cmake"
@property
def _run_tests(self):
return tools.get_env("CONAN_RUN_TESTS", False)
def _configure_cmake(self, folder="src"):
cmake = CMake(self)
if self._run_tests:
# developer's mode (unit tests, examples, restrictive compilation warnings, ...)
cmake.configure()
else:
# consumer's mode (library sources only)
cmake.configure(source_folder=folder, build_folder=folder)
return cmake
def configure(self):
if self.settings.compiler != "gcc": # and self.settings.compiler != "clang":
raise ConanInvalidConfiguration("Library works only with gcc") # and clang")
@ -68,23 +79,20 @@ class UnitsConan(ConanFile):
if self.settings.compiler.cppstd not in ["20", "gnu20"]:
raise ConanInvalidConfiguration("Library requires at least C++20 support")
def _configure_cmake(self, folder="src"):
cmake = CMake(self)
if self._run_tests:
cmake.configure()
else:
cmake.configure(source_folder="src", build_folder="src")
return cmake
def requirements(self):
if self.settings.compiler == "clang" or Version(self.settings.compiler.version) < "10":
self.requires("range-v3/0.10.0@ericniebler/stable")
def build_requirements(self):
if self._run_tests:
self.build_requires("Catch2/2.11.0@catchorg/stable")
self.build_requires("linear_algebra/0.0.1@public-conan/testing")
def build(self):
cmake = self._configure_cmake()
cmake.build()
if self._run_tests:
self.run(os.path.join("bin", "unit_tests_runtime"), run_environment=True)
self.run("ctest -VV -C %s" % cmake.build_type, run_environment=True)
def package(self):
self.copy(pattern="LICENSE.md", dst="licenses")
@ -92,7 +100,6 @@ class UnitsConan(ConanFile):
cmake.install()
def package_info(self):
self.cpp_info.includedirs = ['include']
if self.settings.compiler == "gcc":
self.cpp_info.cxxflags = [
"-Wno-literal-suffix",

View File

@ -73,15 +73,17 @@ steps may be done:
## Full build and unit testing
In case you would like to build all the code in that repository (with unit tests and examples)
you should use the `CMakeLists.txt` from the parent directory.
In case you would like to build all the code in this repository (with unit tests and examples)
you should use the `CMakeLists.txt` from the parent directory and run Conan with
`CONAN_RUN_TESTS=True`.
```shell
git clone --recurse-submodules https://github.com/mpusz/units.git
mkdir units/build && cd units/build
conan install .. <your_profile_and_settings> -s compiler.cppstd=20
cmake .. <your_cmake_configuration>
conan install .. -pr <your_conan_profile> -s compiler.cppstd=20 -e CONAN_RUN_TESTS=True -b outdated
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .
ctest -VV
```
@ -90,7 +92,7 @@ cmake --build .
To create a `conan` package and test `cmake` installation and `conan` packaging run:
```shell
conan create . <username>/<channel> -s cppstd=20 -b=outdated <your_profile_and_settings>
conan create . <username>/<channel> -pr <your_conan_profile> -s compiler.cppstd=20 -e CONAN_RUN_TESTS=True -b outdated
```

View File

@ -21,7 +21,6 @@
# SOFTWARE.
cmake_minimum_required(VERSION 3.8)
#cmake_policy(SET CMP0076 NEW)
project(units
VERSION 0.5.0
@ -32,7 +31,7 @@ project(units
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
# include common tools and workarounds
include(common/cmake/tools)
include(common/cmake/scripts)
# library definition
add_library(units INTERFACE)
@ -83,25 +82,14 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
)
endif()
endif()
add_library(mp::units ALIAS units)
# installation info
install(TARGETS units
EXPORT ${CMAKE_PROJECT_NAME}Targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} # TODO Remove when CMAKE 3.14
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} # TODO Remove when CMAKE 3.14
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} # TODO Remove when CMAKE 3.14
INCLUDES DESTINATION include
)
install_targets(units)
install(DIRECTORY include/units
DESTINATION include
COMPONENT Devel
)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/units
DESTINATION include
COMPONENT Devel
)
# generate configuration files and install the package
configure_and_install(../cmake/common/cmake/simple_package-config.cmake.in mp SameMajorVersion)
configure_and_install(../cmake/common/cmake/simple-config.cmake.in mp SameMajorVersion)

View File

@ -33,7 +33,7 @@ template<Exponent E>
struct exp_ratio {
using base_ratio = E::dimension::base_unit::ratio;
using positive_ratio = conditional<E::num * E::den < 0, ratio<base_ratio::den, base_ratio::num, -base_ratio::exp>, base_ratio>;
static constexpr std::int64_t N = E::num * E::den < 0 ? -E::num : E::num;
static constexpr std::intmax_t N = E::num * E::den < 0 ? -E::num : E::num;
using pow = ratio_pow<positive_ratio, N>;
using type = conditional<E::den == 2, ratio_sqrt<pow>, pow>;
};

View File

@ -54,7 +54,7 @@ struct dim_consolidate<exp_list<E1, ERest...>> {
using type = type_list_push_front<typename dim_consolidate<exp_list<ERest...>>::type, E1>;
};
template<BaseDimension Dim, int Num1, int Den1, int Num2, int Den2, typename... ERest>
template<BaseDimension Dim, std::intmax_t Num1, std::intmax_t Den1, std::intmax_t Num2, std::intmax_t Den2, typename... ERest>
struct dim_consolidate<exp_list<exp<Dim, Num1, Den1>, exp<Dim, Num2, Den2>, ERest...>> {
// TODO: provide custom implementation for ratio_add
using r1 = std::ratio<Num1, Den1>;

View File

@ -41,17 +41,17 @@ struct dim_unpack<> {
using type = exp_list<>;
};
template<BaseDimension Dim, int Num, int Den, Exponent... ERest>
template<BaseDimension Dim, std::intmax_t Num, std::intmax_t Den, Exponent... ERest>
struct dim_unpack<exp<Dim, Num, Den>, ERest...> {
using type = type_list_push_front<typename dim_unpack<ERest...>::type, exp<Dim, Num, Den>>;
};
template<DerivedDimension Dim, int Num, int Den, Exponent... ERest>
template<DerivedDimension Dim, std::intmax_t Num, std::intmax_t Den, Exponent... ERest>
struct dim_unpack<exp<Dim, Num, Den>, ERest...> {
using type = dim_unpack<exp<downcast_base_t<Dim>, Num, Den>, ERest...>::type;
};
template<Exponent... Es, int Num, int Den, Exponent... ERest>
template<Exponent... Es, std::intmax_t Num, std::intmax_t Den, Exponent... ERest>
struct dim_unpack<exp<derived_dimension_base<Es...>, Num, Den>, ERest...> {
using type = type_list_push_front<typename dim_unpack<ERest...>::type, exp_multiply<Es, Num, Den>...>;
};

View File

@ -43,7 +43,7 @@ struct equivalent_dim_impl<D1, D2> : std::disjunction<std::is_same<D1, D2>, equi
template<Exponent E1, Exponent E2>
struct equivalent_exp : std::false_type {};
template<BaseDimension Dim1, int Num, int Den, BaseDimension Dim2>
template<BaseDimension Dim1, std::intmax_t Num, std::intmax_t Den, BaseDimension Dim2>
struct equivalent_exp<exp<Dim1, Num, Den>, exp<Dim2, Num, Den>> : equivalent_dim_impl<Dim1, Dim2> {};
template<DerivedDimension D1, DerivedDimension D2>
@ -230,10 +230,10 @@ using dimension_sqrt = detail::dimension_sqrt_impl<D>::type;
// dimension_pow
namespace detail {
template<Dimension D, std::size_t N>
template<Dimension D, std::intmax_t N>
struct dimension_pow_impl;
template<BaseDimension D, std::size_t N>
template<BaseDimension D, std::intmax_t N>
struct dimension_pow_impl<D, N> {
using type = downcast_dimension<derived_dimension_base<exp<D, N>>>;
};
@ -243,24 +243,24 @@ struct dimension_pow_impl<D, 1> {
using type = D;
};
template<BaseDimension D, std::size_t N>
template<BaseDimension D, std::intmax_t N>
struct dimension_pow_impl<derived_dimension_base<exp<D, 1, N>>, N> {
using type = D;
};
template<DerivedDimension D, std::size_t N>
template<DerivedDimension D, std::intmax_t N>
struct dimension_pow_impl<D, N> {
using type = dimension_pow_impl<downcast_base_t<D>, N>::type;
};
template<typename... Es, std::size_t N>
template<typename... Es, std::intmax_t N>
struct dimension_pow_impl<derived_dimension_base<Es...>, N> {
using type = downcast_dimension<derived_dimension_base<exp_multiply<Es, N, 1>...>>;
};
} // namespace detail
template<Dimension D, std::size_t N>
template<Dimension D, std::intmax_t N>
using dimension_pow = detail::dimension_pow_impl<D, N>::type;
} // namespace units

View File

@ -34,7 +34,7 @@ namespace units {
* @tparam Num numinator of the factor
* @tparam Den denominator of the factor
*/
template<Dimension Dim, int Num, int Den = 1>
template<Dimension Dim, std::intmax_t Num, std::intmax_t Den = 1>
struct exp {
using dimension = Dim;
static constexpr int num = Num;
@ -44,7 +44,7 @@ struct exp {
// is_exp
namespace detail {
template<typename Dim, int Num, int Den>
template<typename Dim, std::intmax_t Num, std::intmax_t Den>
inline constexpr bool is_exp<exp<Dim, Num, Den>> = true;
} // namespace detail
@ -57,7 +57,7 @@ struct exp_less : base_dimension_less<typename E1::dimension, typename E2::dimen
// exp_invert
namespace detail {
template<typename Dim, int Num, int Den>
template<typename Dim, std::intmax_t Num, std::intmax_t Den>
constexpr exp<Dim, -Num, Den> exp_invert_impl(exp<Dim, Num, Den>);
} // namespace detail
@ -68,7 +68,7 @@ using exp_invert = decltype(detail::exp_invert_impl(E()));
// exp_multiply
namespace detail {
template<Exponent E, int Num, int Den>
template<Exponent E, std::intmax_t Num, std::intmax_t Den>
struct exp_multiply_impl {
using r1 = ratio<E::num, E::den>;
using r2 = ratio<Num, Den>;
@ -78,7 +78,7 @@ struct exp_multiply_impl {
} // namespace detail
template<Exponent E, int Num, int Den>
template<Exponent E, std::intmax_t Num, std::intmax_t Den>
using exp_multiply = detail::exp_multiply_impl<E, Num, Den>::type;
template<Exponent... Es>

View File

@ -199,8 +199,8 @@ private:
constexpr void on_minus() { f.specs.sign = fmt::sign::minus; }
constexpr void on_space() { f.specs.sign = fmt::sign::space; }
constexpr void on_align(align_t align) { f.specs.align = align; }
constexpr void on_width(unsigned width) { f.specs.width = width; }
constexpr void on_precision(unsigned precision) { f.precision = precision; }
constexpr void on_width(int width) { f.specs.width = width; }
constexpr void on_precision(int precision) { f.precision = precision; }
constexpr void end_precision() {}
template<typename Id>

View File

@ -27,14 +27,14 @@
namespace units {
template<std::size_t N, typename D, typename U, typename Rep>
template<std::intmax_t N, typename D, typename U, typename Rep>
requires (N == 0)
inline Rep pow(const quantity<D, U, Rep>&) noexcept
{
return 1;
}
template<std::size_t N, typename D, typename U, typename Rep>
template<std::intmax_t N, typename D, typename U, typename Rep>
inline Quantity AUTO pow(const quantity<D, U, Rep>& q) noexcept
{
using dim = dimension_pow<D, N>;

View File

@ -27,7 +27,8 @@
namespace units {
constexpr std::intmax_t ipow10(std::intmax_t exp) {
constexpr std::intmax_t ipow10(std::intmax_t exp)
{
// how to assert here?
// static_assert(exp >= 0, "Use fpow10() for negative exponents");
if (exp == 0) return 1;
@ -40,7 +41,8 @@ constexpr std::intmax_t ipow10(std::intmax_t exp) {
}
constexpr long double fpow10(std::intmax_t exp) {
constexpr long double fpow10(std::intmax_t exp)
{
if (exp == 0) return 1.0L;
long double result = 1.0L;
if (exp < 0) {

View File

@ -40,7 +40,7 @@ template<typename T>
return v < 0 ? -v : v;
}
constexpr std::tuple<std::intmax_t, std::intmax_t, std::intmax_t> normalize(std::intmax_t num, std::intmax_t den, std::intmax_t exp)
constexpr std::tuple<std::intmax_t, std::intmax_t, std::intmax_t> normalize(std::intmax_t num, std::intmax_t den, std::intmax_t exp)
{
std::intmax_t gcd = std::gcd(num, den);
num = num * (den < 0 ? -1 : 1) / gcd;
@ -100,12 +100,12 @@ namespace detail {
static constexpr std::intmax_t safe_multiply(std::intmax_t lhs, std::intmax_t rhs)
{
constexpr std::uintmax_t c = std::uintmax_t(1) << (sizeof(std::intmax_t) * 4);
constexpr std::intmax_t c = std::uintmax_t(1) << (sizeof(std::intmax_t) * 4);
const std::uintmax_t a0 = detail::abs(lhs) % c;
const std::uintmax_t a1 = detail::abs(lhs) / c;
const std::uintmax_t b0 = detail::abs(rhs) % c;
const std::uintmax_t b1 = detail::abs(rhs) / c;
const std::intmax_t a0 = detail::abs(lhs) % c;
const std::intmax_t a1 = detail::abs(lhs) / c;
const std::intmax_t b0 = detail::abs(rhs) % c;
const std::intmax_t b1 = detail::abs(rhs) / c;
Expects(a1 == 0 || b1 == 0); // overflow in multiplication
Expects(a0 * b1 + b0 * a1 < (c >> 1)); // overflow in multiplication
@ -163,7 +163,7 @@ using ratio_divide = detail::ratio_divide_impl<R1, R2>::type;
namespace detail {
template<typename R, std::size_t N>
template<typename R, std::intmax_t N>
struct ratio_pow_impl {
using type = ratio_multiply<typename ratio_pow_impl<R, N - 1>::type, R>;
};
@ -180,7 +180,7 @@ struct ratio_pow_impl<R, 0> {
} // namespace detail
template<Ratio R, std::size_t N>
template<Ratio R, std::intmax_t N>
using ratio_pow = detail::ratio_pow_impl<R, N>::type;
// ratio_sqrt

View File

@ -62,11 +62,11 @@ namespace units {
// exp
template<const base_dimension& BaseDimension, int Num, int Den = 1>
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den = 1>
struct exp {
static constexpr const base_dimension& dimension = BaseDimension;
static constexpr int num = Num;
static constexpr int den = Den;
static constexpr std::intmax_t num = Num;
static constexpr std::intmax_t den = Den;
};
// is_exp
@ -74,7 +74,7 @@ namespace units {
template<typename T>
inline constexpr bool is_exp = false;
template<const base_dimension& BaseDimension, int Num, int Den>
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den>
inline constexpr bool is_exp<exp<BaseDimension, Num, Den>> = true;
} // namespace detail
@ -92,7 +92,7 @@ namespace units {
template<Exponent E>
struct exp_invert;
template<const base_dimension& BaseDimension, int Num, int Den>
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den>
struct exp_invert<exp<BaseDimension, Num, Den>> {
using type = exp<BaseDimension, -Num, Den>;
};
@ -160,7 +160,7 @@ namespace units {
using type = conditional<std::is_same_v<rest, dimension<>>, dimension<E1>, type_list_push_front<rest, E1>>;
};
template<const base_dimension& D, int Num1, int Den1, int Num2, int Den2, Exponent... ERest>
template<const base_dimension& D, std::intmax_t Num1, std::intmax_t Den1, std::intmax_t Num2, std::intmax_t Den2, Exponent... ERest>
struct dim_consolidate<dimension<exp<D, Num1, Den1>, exp<D, Num2, Den2>, ERest...>> {
using r1 = std::ratio<Num1, Den1>;
using r2 = std::ratio<Num2, Den2>;

View File

@ -62,7 +62,7 @@ namespace units {
// exp
template<const base_dimension& BaseDimension, int Num, int Den = 1>
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den = 1>
struct exp {
static constexpr const base_dimension& dimension = BaseDimension;
static constexpr int num = Num;
@ -74,7 +74,7 @@ namespace units {
template<typename T>
inline constexpr bool is_exp = false;
template<const base_dimension& BaseDimension, int Num, int Den>
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den>
inline constexpr bool is_exp<exp<BaseDimension, Num, Den>> = true;
} // namespace detail
@ -92,7 +92,7 @@ namespace units {
template<Exponent E>
struct exp_invert;
template<const base_dimension& BaseDimension, int Num, int Den>
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den>
struct exp_invert<exp<BaseDimension, Num, Den>> {
using type = exp<BaseDimension, -Num, Den>;
};
@ -160,7 +160,7 @@ namespace units {
using type = conditional<std::is_same_v<rest, dimension<>>, dimension<E1>, type_list_push_front<rest, E1>>;
};
template<const base_dimension& D, int Num1, int Den1, int Num2, int Den2, typename... ERest>
template<const base_dimension& D, std::intmax_t Num1, std::intmax_t Den1, std::intmax_t Num2, std::intmax_t Den2, typename... ERest>
struct dim_consolidate<dimension<exp<D, Num1, Den1>, exp<D, Num2, Den2>, ERest...>> {
using r1 = std::ratio<Num1, Den1>;
using r2 = std::ratio<Num2, Den2>;

View File

@ -62,11 +62,11 @@ namespace units {
// exp
template<const base_dimension& BaseDimension, int Num, int Den = 1>
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den = 1>
struct exp {
static constexpr const base_dimension& dimension = BaseDimension;
static constexpr int num = Num;
static constexpr int den = Den;
static constexpr std::intmax_t num = Num;
static constexpr std::intmax_t den = Den;
};
// exp_dim_id_less
@ -80,7 +80,7 @@ namespace units {
template<typename E>
struct exp_invert;
template<const base_dimension& BaseDimension, int Num, int Den>
template<const base_dimension& BaseDimension, std::intmax_t Num, std::intmax_t Den>
struct exp_invert<exp<BaseDimension, Num, Den>> {
using type = exp<BaseDimension, -Num, Den>;
};
@ -131,7 +131,7 @@ namespace units {
using type = conditional<std::is_same_v<rest, dimension<>>, dimension<E1>, type_list_push_front<rest, E1>>;
};
template<const base_dimension& D, int Num1, int Den1, int Num2, int Den2, typename... ERest>
template<const base_dimension& D, std::intmax_t Num1, std::intmax_t Den1, std::intmax_t Num2, std::intmax_t Den2, typename... ERest>
struct dim_consolidate<dimension<exp<D, Num1, Den1>, exp<D, Num2, Den2>, ERest...>> {
using r1 = std::ratio<Num1, Den1>;
using r2 = std::ratio<Num2, Den2>;

View File

@ -20,6 +20,9 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# check if conan installed a test framework
conan_check_testing(Catch2)
add_executable(unit_tests_runtime
catch_main.cpp
digital_info_test.cpp