build: clang support added

This commit is contained in:
Mateusz Pusz
2021-02-21 00:40:56 +01:00
parent 1250b9618e
commit b18061ab0e
3 changed files with 124 additions and 8 deletions

View File

@@ -86,13 +86,15 @@ class UnitsConan(ConanFile):
if compiler == "gcc":
if version < "10.0":
raise ConanInvalidConfiguration("mp-units requires at least g++-10")
elif compiler == "clang":
if version < "12":
raise ConanInvalidConfiguration("mp-units requires at least clang++-12")
elif compiler == "Visual Studio":
if version < "16":
raise ConanInvalidConfiguration("mp-units requires at least Visual Studio 16.7")
else:
raise ConanInvalidConfiguration("mp-units is supported only by gcc and Visual Studio so far")
if compiler.get_safe("cppstd"):
check_min_cppstd(self, "20")
raise ConanInvalidConfiguration("Unsupported compiler")
check_min_cppstd(self, "20")
# TODO Uncomment this when environment is supported in the Conan toolchain
# def config_options(self):
@@ -100,6 +102,10 @@ class UnitsConan(ConanFile):
# # build_docs has sense only in a development or CI build
# del self.options.build_docs
def requirements(self):
if self.settings.compiler == "clang":
self.requires("range-v3/0.11.0")
def build_requirements(self):
if self._run_tests:
self.build_requires("catch2/2.13.4")

View File

@@ -51,6 +51,7 @@ target_include_directories(mp-units
)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
find_package(range-v3)
target_link_libraries(mp-units
INTERFACE
range-v3::range-v3

View File

@@ -22,8 +22,6 @@
#pragma once
#include <concepts>
#if __clang__
#define COMP_CLANG __clang_major__
#elif __GNUC__
@@ -33,7 +31,18 @@
#define COMP_MSVC _MSC_VER
#endif
#if COMP_MSVC
#if COMP_CLANG
#include <concepts/compare.hpp>
#include <concepts/concepts.hpp>
#include <range/v3/functional/comparisons.hpp>
#endif
#include <concepts>
#include <compare>
#if COMP_MSVC || COMP_CLANG
#define TYPENAME typename
@@ -43,13 +52,113 @@
#endif
#if COMP_GCC
namespace std {
#if COMP_GCC
template<class T>
concept default_constructible = constructible_from<T>;
} // namespace std
#elif COMP_CLANG
// concepts
using concepts::three_way_comparable;
using concepts::three_way_comparable_with;
// using concepts::common_reference_with;
using concepts::common_with;
using concepts::constructible_from;
using concepts::convertible_to;
// using concepts::default_constructible;
using concepts::derived_from;
// using concepts::equality_comparable;
using concepts::equality_comparable_with;
// // using concepts::floating_point;
// using concepts::integral;
using concepts::regular;
// using concepts::same_as;
// using concepts::totally_ordered;
// using concepts::totally_ordered_with;
using ranges::compare_three_way;
// namespace ranges {
// using ::ranges::forward_range;
// using ::ranges::range_value_t;
// }
// // missing in Range-v3
// template<class T>
// concept floating_point = std::is_floating_point_v<T>;
template<class F, class... Args>
concept invocable =
requires(F&& f, Args&&... args) {
std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
};
template<class F, class... Args>
concept regular_invocable = invocable<F, Args...>;
template<class T, class U>
constexpr bool cmp_equal(T t, U u) noexcept
{
using UT = std::make_unsigned_t<T>;
using UU = std::make_unsigned_t<U>;
if constexpr (std::is_signed_v<T> == std::is_signed_v<U>)
return t == u;
else if constexpr (std::is_signed_v<T>)
return t < 0 ? false : UT(t) == u;
else
return u < 0 ? false : t == UU(u);
}
template<class T, class U>
constexpr bool cmp_not_equal(T t, U u) noexcept
{
return !cmp_equal(t, u);
}
template<class T, class U>
constexpr bool cmp_less(T t, U u) noexcept
{
using UT = std::make_unsigned_t<T>;
using UU = std::make_unsigned_t<U>;
if constexpr (std::is_signed_v<T> == std::is_signed_v<U>)
return t < u;
else if constexpr (std::is_signed_v<T>)
return t < 0 ? true : UT(t) < u;
else
return u < 0 ? false : t < UU(u);
}
template<class T, class U>
constexpr bool cmp_greater(T t, U u) noexcept
{
return cmp_less(u, t);
}
template<class T, class U>
constexpr bool cmp_less_equal(T t, U u) noexcept
{
return !cmp_greater(t, u);
}
template<class T, class U>
constexpr bool cmp_greater_equal(T t, U u) noexcept
{
return !cmp_less(t, u);
}
template<class R, class T>
constexpr bool in_range(T t) noexcept
{
return std::cmp_greater_equal(t, std::numeric_limits<R>::min()) &&
std::cmp_less_equal(t, std::numeric_limits<R>::max());
}
#endif
} // namespace std