| Issue |
107602
|
| Summary |
Internal module partitions export content
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
TheRustifyer
|
I have this example code:
```cpp
module math:numbers.detail;
import std;
import math.ops;
import math.symbols;
import :numbers.naturals;
import :numbers.integers;
import :numbers.rationals;
#if defined(__clang__)
export namespace zero::math {
#elif defined(_MSC_VER)
using namespace zero::math;
#endif
template <typename L, typename R>
concept EitherRational =
std::is_same_v<L, Rational> || std::is_same_v<R, Rational>;
// Helper to extract the inner value of a Number type or avoid the method
// call if it's a primitive (std::is_arithmetic_v).
template <typename T> constexpr auto normalize(const T &value) noexcept {
if constexpr (std::is_arithmetic_v<T> || std::is_same_v<T, Rational>)
return value; // Return primitive arithmetic types and Rationals as-is
else
return value.number();
}
// Generalized arithmetic operation helper using lambdas
template <typename L, typename R, typename Op>
constexpr auto arithmetic_op(const L &lhs, const R &rhs, Op op) noexcept {
if constexpr (EitherRational<L, R>)
return op(lhs, rhs);
else
return op(normalize(lhs), normalize(rhs));
}
// Specialized addition and subtraction for Rational types
template <typename L, typename R>
constexpr auto rational_add_or_subtract(const L &lhs, const R &rhs, int sign) noexcept {
if constexpr (std::is_same_v<L, Rational> && std::is_same_v<R, Rational>) {
return sum_or_subtract(lhs, rhs, sign);
} else if constexpr (std::is_same_v<L, Rational>) {
return sum_or_subtract(lhs, Rational(rhs), sign);
} else if constexpr (std::is_same_v<R, Rational>) {
return sum_or_subtract(Rational(lhs), rhs, sign);
}
}
template <typename L, typename R>
constexpr auto rational_mult(const L &lhs, const R &rhs) noexcept {
if constexpr (std::is_same_v<std::decay_t<decltype(lhs)>, Rational> &&
std::is_same_v<std::decay_t<decltype(rhs)>, Rational>) {
return Rational(lhs.numerator() * rhs.numerator(),
lhs.denominator() * rhs.denominator());
} else if constexpr (std::is_same_v<std::decay_t<decltype(lhs)>, Rational>) {
return Rational(lhs.numerator() * normalize(rhs), lhs.denominator());
} else if constexpr (std::is_same_v<std::decay_t<decltype(rhs)>, Rational>) {
return Rational(normalize(lhs) * rhs.numerator(), rhs.denominator());
}
}
// Helper function to sum or subtract two Rationals
[[nodiscard]] constexpr Rational
sum_or_subtract(const Rational &lhs, const Rational &rhs, int sign) noexcept {
const int lhs_numerator = lhs.numerator().number();
const int rhs_numerator = sign * rhs.numerator().number();
const int lhs_denominator = lhs.denominator().number();
const int rhs_denominator = rhs.denominator().number();
if (lhs_denominator == rhs_denominator) { // Like fractions
return {lhs_numerator + rhs_numerator, lhs_denominator};
} else { // Unlike fractions
// Get their LCD by finding their LCM
const auto lcd = zero::math::lcm(lhs_denominator, rhs_denominator);
// Scale numerators to have the common denominator (LCM)
const int numerator = (lhs_numerator * (lcd / lhs_denominator)) +
(rhs_numerator * (lcd / rhs_denominator));
return {numerator, lcd};
}
}
#if defined(__clang__)
}
#endif
```
- `Clang` is letting export content from an **internal module partition**. `MSVC` is *not*
- Also, for having visibility of those declared templates at call site, I need to have the `export namespace...`, or it won't be visible.
In `MSVC`, they don't have such trouble (as shown in the code).
Am I doing anything wrong off the `standard` or is this an issue of the frontend?
This is tested with `Clang 18.1.8` via `Msys2` on `Windows` and with `Clang 19.0.0` on `Linux`.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs