300 Commits

Author SHA1 Message Date
Mateusz Pusz a17c37b383 fix(core): require the real()/imag() API on a complex vector/tensor representation
numeric_field read the field off a scalar element, so a container storing a
complex element (e.g. a wrapper over std::complex<double>) was classified complex
even when it did not expose real()/imag() on its own surface. Such a type cannot
actually be used as a complex representation, yet it satisfied the complex slot.

A vector or tensor is now complex only when its element is complex AND the
container itself exposes the real()/imag() decomposition API. When the element is
complex but that API is missing, numeric_field is left unspecified rather than
guessed (which would pick a Euclidean instead of a Hermitian magnitude), exactly
as tensor_order is left unspecified for an ambiguous shape: the type is then not a
representation until the author exposes the API or specializes numeric_field.

A real container that merely exposes element-wise real()/imag() (as real Eigen and
Blaze matrices do) stays real, because the field is read off the real element.

The consistency check uses a consteval helper with if constexpr so the element
aliases and the recursive detect_numeric_field call are only instantiated for the
matching order.

Verified on the supported matrix: gcc 12/15/16 and clang 16/21. (clang-22 is
unreleased and fails to build mp-units on master independently of this change.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 16:33:39 +02:00
Mateusz Pusz 98c25194eb docs: give linear algebra integration its own guide and reorganize the integration chapter
The Eigen/GLM/Blaze integration story was spread across the User's Guide
reference, a subsection of the custom-representation how-to, and the linear
algebra example, and the Integration chapter never named it. Meanwhile
"Interoperability with Other Libraries" was actually about quantity_like_traits
and std::chrono, not linear algebra.

- Add "Using a Linear Algebra Library" how-to: the single home for the shipped
  plugin table (header/module/CMake target), the CMake linking recipe for both
  header and module mode, the recipe for adapting a library with no plugin, and
  the expression-template/Armadillo/V2 caveats.
- Rename "Interoperability with Other Libraries" to "Converting to and from
  External Quantity Types" to match its actual content; update all inbound links.
- Trim the duplicated vector-library-adaptation block from the custom-rep guide
  and point it at the new guide.
- Shrink the User's Guide "Third-Party Library Integrations" section to a pointer
  so the new guide is the single source of truth.
- Clarify in Project Structure that an integration target links only core + the
  third-party library, so it must be linked alongside mp-units::mp-units.
- Cross-link the units-meet-linear-algebra blog post to the new guide.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 14:11:58 +02:00
Mateusz Pusz 0763cd79ea refactor: move utility-component headers under mp-units/utility/
The mp_units::utility representation types shipped from flat header paths
(mp-units/cartesian_vector.h, cartesian_tensor.h, random.h) while the
core-side utility headers (safe_int, constrained, representation) already
live under mp-units/utility/. Unify the layout so the include path mirrors
the mp_units::utility namespace:

- move cartesian_vector.h, cartesian_tensor.h, random.h into mp-units/utility/;
- keep deprecated forwarding headers at the old paths for the released
  cartesian_vector and random (a #warning plus an include of the new path);
- cartesian_tensor is new in 2.6.0, so it ships only at the new path;
- repoint all in-tree consumers (tests, example, docs) to the new paths so
  they do not trip the deprecation #warning under -Werror;
- update the Project Structure guide and the prose reference in
  quantity_arithmetics.

Verified full runtime + static suites on gcc-12/gcc-15 (headers) and
clang-16 (headers) / clang-21 (modules): 129906 assertions each.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 14:08:21 +02:00
Mateusz Pusz fdf4b5e59b docs: reconcile representation-types docs with the element-based field and undefined order
numeric_field reads the field off a scalar element (no field adapter for Eigen/Blaze) and follows
tensor_order's availability; tensor_order is undefined for an ambiguous type and must be specialized.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 12:01:07 +02:00
Mateusz Pusz e0cc4eec90 docs(utility): document the utility component, namespace tiers, and the safe_int/constrained move
Add a Namespaces section to the project structure docs describing the three
public tiers (mp_units / mp_units::utility / mp_units::detail), show the
core -> systems -> utility module layering, and list the utility headers.
Update the representation and custom-representation guides to introduce the
built-in cartesian types via mp_units::utility, and update the safe_int /
constrained material (guide, blog posts, tutorials) to the new
<mp-units/utility/...> include paths and mp_units::utility names.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 18:07:49 +02:00
Mateusz Pusz f5a5062f7a docs: mention the 2D cartesian_vector/tensor in the framework guides
Describe `cartesian_vector<T, N>` / `cartesian_tensor<T, N>` as N-dimensional /
NxN with a compile-time dimension N (2 or 3, default 3), and show dimension
deduction plus embed/project converting between the plane and space.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 23:00:55 +02:00
Mateusz Pusz aa2f91346d docs: document the two-axis quantity character
Rework the "Character of a Quantity" chapter for the order x field model and record the change
in the changelog.

- character_of_a_quantity.md: two-axis framing up front; a new "Real and complex quantities"
  section; the `quantity_tensor_order`/`quantity_field` enum and `quantity_character` struct
  definitions shown before use; an expanded ordering example (explicit vector, inherited
  vector, explicit tensor) and a complex declaration; the ISO 80000-2 rank-ordering quote; and
  the experimental warning removed. Deprecated `quantity_character::vector` examples updated to
  the two-axis spelling.
- CHANGELOG.md: 2.6.0 entries for the two-axis split, `cartesian_tensor`, the
  `numeric_field`/`tensor_order` customization points, the flat-enum deprecation and
  customization rework, and the magnitude/decomposition fixes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 17:41:12 +02:00
Mateusz Pusz e1c2b9562b fix(representation): key magnitude and vector decomposition on character order, support complex
`quantity::magnitude()` was constrained to an exact `quantity_character{vector}` (i.e.
`{vector, real}`), which silently excluded tensor quantities and complex vectors even though
both have a well-defined norm. It now requires `order >= vector` (vectors and tensors, any
field) plus `HasMagnitude<rep>` so the storage can actually produce one - the latter cleanly
withholds the member instead of letting the body hard-error when the rep has no magnitude.

The `magnitude` CPO gained the missing complex-scalar branch: a complex scalar is a degenerate
1D complex vector, so its magnitude is the modulus `|z|`, symmetric with the real-scalar
`std::abs` branch (a `double` standing in as a 1D real vector).

Vector decomposition (`vector_components` primary template and `ValidVectorAxes`) dropped the
real-field pin, keying on `order == vector` alone, so complex vector quantities decompose into
their complex 1D components. The order pin stays (a tensor is not a flat vector decomposition).

Adds static tests (magnitude over scalar/vector/tensor and real/complex/degenerate reps;
complex-field decomposition) asserting the intended design, and documents the complex-scalar
magnitude path in the representation-types guide.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 13:47:44 +02:00
Mateusz Pusz e061bf0ef8 refactor(representation): replace disable_real/NotQuantity with disable_representation
Consolidate the representation opt-outs into one character-agnostic customization
point and align the documentation with the two-axis model.

- Add `disable_representation<T>` in `customization_points.h`: a specializable
  opt-out that bars a type from being a quantity representation regardless of
  character. Its default (`is_quantity_abstraction<value_type_t<T>>`) rejects a
  quantity or quantity-like type, and any container of them; `bool` is opted out
  explicitly. This retires both `disable_real` and the `NotQuantity` guard.
- Rename the internal predicate `is_quantity_like` -> `is_quantity_abstraction`
  (it covers `Quantity || QuantityLike`) so it no longer collides with the
  `QuantityLike` customization family.
- The representation tier now leads with one shared `RepresentationBaseline`
  guard (not opted out + `UnitMagnitudeScalable`), which short-circuits a quantity
  before any character concept instantiates its operators (avoiding a
  satisfaction cycle).
- Docs: restructure `representation_types.md` around the two character axes
  (field via `numeric_field`, order via `tensor_order`) with a common baseline,
  the new `disable_representation` section, and consistent unit-magnitude-aware
  scaling terminology; align `concepts.md` and `using_custom_representation_types.md`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 21:36:07 +02:00
Mateusz Pusz bf82b8d28d docs: fix overlong line in representation_types disable_tensor note
Rewrap a 91-column line in the `disable_tensor` paragraph to satisfy markdownlint MD013.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 09:16:59 +02:00
Mateusz Pusz 87257a6c5d refactor: Vector implemented in terms of Tensor 2026-06-24 22:52:24 +02:00
Mateusz Pusz 7ec072cd7b style: markdownlint-cli2 added to pre-commit 2026-06-23 23:03:04 +02:00
Mateusz Pusz d37414ac7b feat: vector quantity decomposition support added 2026-06-23 16:11:47 +02:00
Mateusz Pusz 5c8c4ad5ae feat: external linear algebra libraries integrations added + quantity::magnitude() member function
Resolves #301
2026-06-22 18:51:56 +02:00
Mateusz Pusz c4b30d9b60 Merge branch 'master' of github.com:mpusz/units 2026-06-12 23:09:41 +02:00
Mateusz Pusz 4c7639942e refactor: norm() replaced with magnitude() for vector representation types 2026-06-12 22:25:26 +02:00
Mateusz Pusz 5072c138ee docs: "Two levels of format specification" chapter added 2026-06-12 09:44:28 +02:00
Mateusz Pusz 982fc526c0 feat: 💥 quantity_from_unit_zero() renamed back to quanity_from_zero() and limited to default_point_origin + qp.in(Unit) changes the origin for offset units 2026-05-21 22:46:12 +02:00
Mateusz Pusz 2690296059 feat: quantity_point text output added for default_point_origin 2026-05-21 18:38:09 +02:00
Mateusz Pusz 7899bf4ca8 feat: explicit constructor between point in projected frames added 2026-05-13 18:11:27 +02:00
Mateusz Pusz c93778010f feat: 💥 final is not longer required for definitions and should not be used for quantity_spec 2026-05-13 15:23:47 +02:00
Mateusz Pusz 72ca96ee52 feat: frame projections support added 2026-05-12 23:02:09 +02:00
Mateusz Pusz c1212bf4da docs: "Representation Types" chapter updated 2026-05-12 20:42:15 +02:00
Mateusz Pusz 1ac0fe5336 docs: affine space SVG updated 2026-05-12 20:27:42 +02:00
Mateusz Pusz 4161608a92 docs: point origin inheritance docs added 2026-05-06 22:35:58 +02:00
Mateusz Pusz 1b8b6d222a feat: kind_of applied to more derived SI units + some quantity_spec hierarchies improved 2026-05-06 22:34:40 +02:00
Mateusz Pusz 2978c1963f fix: missing constraints for qp.quantity_from_unit_zero() added + fixed all incorrect usa cases 2026-05-06 22:12:50 +02:00
Mateusz Pusz 0de0438d76 docs: '?' removed from headers with nominal clauses 2026-04-30 15:57:07 +02:00
Mateusz Pusz 477b8eb7f1 docs: marking of subkinds in hierarchies changed to subgraphs
Co-authored-by: Copilot <copilot@github.com>
2026-04-29 19:20:14 +02:00
Mateusz Pusz c3d5fc6dbb docs: non_negative declarations added to quantity_spec in docs
Co-authored-by: Copilot <copilot@github.com>
2026-04-28 21:10:01 +02:00
Mateusz Pusz 810c5a9c41 docs: quantity point bounds documentation updated
Co-authored-by: Copilot <copilot@github.com>
2026-04-28 10:49:24 +02:00
Mateusz Pusz 7b2603a8ba docs: safe_int documentation improved 2026-04-27 23:28:12 +02:00
Mateusz Pusz 9b1734e319 docs: "Representation Types" chapter contents restored
Co-authored-by: Copilot <copilot@github.com>
2026-04-27 14:37:47 +02:00
Mateusz Pusz 659738044a feat: safe_int implicit conversions improved and refactored the operators + widening for scaling now preserves sign
Co-authored-by: Copilot <copilot@github.com>
2026-04-26 16:03:09 +02:00
Mateusz Pusz e3f8cc0dc4 docs: "Representation types" updated with the latest changes 2026-04-25 21:04:40 +02:00
Mateusz Pusz 0a33e0a0e6 refactor: quantity point bounds are now specified directly in origin - quantity_bounds_for customization point removed 2026-04-25 21:00:31 +02:00
Mateusz Pusz b9d801dc34 docs: representation types docs improved
Co-authored-by: Copilot <copilot@github.com>
2026-04-25 19:16:22 +02:00
Mateusz Pusz 08e1645dfe feat: UsesIntegerScaling now properly requires multiplication by a wider type 2026-04-25 12:52:05 +02:00
Mateusz Pusz 6263e2b8c5 feat: representation_underlying_type provided instead of indirectly_readable_traits usage 2026-04-21 22:10:19 +02:00
Mateusz Pusz 1fbb410549 docs: safe_int overflow example simplified 2026-04-12 11:12:45 +02:00
Mateusz Pusz 12300bcd23 feat: safe_int and blog article about it added 2026-04-11 20:30:28 +02:00
Mateusz Pusz e2e490f0cd refactor: scaling algorithm and concepts simplified 2026-04-11 19:00:33 +02:00
Mateusz Pusz 2eb094c0b1 feat: scaling widening changed to always use std::int64_t for smaller types 2026-04-08 17:56:26 +02:00
Mateusz Pusz a1e1e7cb21 feat: non-negative quantities support added
Resolves #468
2026-04-06 22:51:42 +02:00
Mateusz Pusz a89b93bab2 feat: 💥 Celsius_temperature removed from ISQ 2026-04-04 09:11:33 +02:00
Mateusz Pusz 459211fc7a feat: quantity point bounds design finalized 2026-04-03 23:38:47 +02:00
Mateusz Pusz c30a637ae7 refactor: 💥 zeroth-names deprecated; quantity_from_unit_zero(); natural_point_origin 2026-03-31 22:03:03 +02:00
Mateusz Pusz 500046873b feat: two more overflow policies added 2026-03-31 13:52:20 +02:00
Mateusz Pusz e6667e3444 style: pre-commit 2026-03-31 11:40:11 +02:00
Mateusz Pusz 8cde16d7a4 docs: affine space SVG graphs styles improved to be visible in dark mode 2026-03-30 21:40:00 +02:00