KleidiAI Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 76.6% 36 / 0 / 47
Functions: 77.8% 119 / 0 / 153
Branches: 41.7% 5 / 0 / 12

test/nextgen/common/poly.hpp
Line Branch Exec Source
1 //
2 // SPDX-FileCopyrightText: Copyright 2025-2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
3 //
4 // SPDX-License-Identifier: Apache-2.0
5 //
6
7 #pragma once
8
9 #include <algorithm>
10 #include <cstddef>
11 #include <memory>
12 #include <type_traits>
13 #include <utility>
14
15 namespace kai::test {
16
17 namespace internal {
18
19 class PolyControl {
20 public:
21 2112 virtual ~PolyControl() = default;
22
23 template <typename Derived>
24 explicit PolyControl(std::in_place_type_t<Derived> type);
25
26 template <typename Base>
27 [[nodiscard]] const Base& data() const;
28
29 template <typename Base>
30 [[nodiscard]] Base& data();
31
32 [[nodiscard]] std::unique_ptr<PolyControl> clone() const;
33
34 private:
35 std::unique_ptr<PolyControl> (*m_clone_fn)(const PolyControl& inner);
36 const void* (*m_get_constant_fn)(const PolyControl& inner) = nullptr;
37 void* (*m_get_mutable_fn)(PolyControl& inner) = nullptr;
38 };
39
40 template <typename Derived>
41 struct PolyInner : public PolyControl {
42 template <typename... Args>
43 explicit PolyInner(Args&&... args);
44
45 Derived data;
46 };
47
48 template <typename Derived>
49 5712 inline PolyControl::PolyControl([[maybe_unused]] std::in_place_type_t<Derived> type) :
50 9360 m_clone_fn([](const PolyControl& inner) -> std::unique_ptr<PolyControl> {
51 3648 auto& self = static_cast<const PolyInner<Derived>&>(inner);
52 3648 return std::make_unique<PolyInner<Derived>>(self.data);
53 3648 }),
54 5712 m_get_constant_fn(+[](const PolyControl& inner) -> const void* {
55 auto& self = static_cast<const PolyInner<Derived>&>(inner);
56 return &self.data;
57 }),
58 25069 m_get_mutable_fn(+[](PolyControl& inner) -> void* {
59 19357 auto& self = static_cast<PolyInner<Derived>&>(inner);
60 38714 return &self.data;
61 25069 }) {
62 5712 }
63
64 template <typename Base>
65 inline const Base& PolyControl::data() const {
66 return *static_cast<const Base*>(m_get_constant_fn(*this));
67 }
68
69 template <typename Base>
70 19357 [[nodiscard]] inline Base& PolyControl::data() {
71 19357 return *static_cast<Base*>(m_get_mutable_fn(*this));
72 }
73
74 3648 [[nodiscard]] inline std::unique_ptr<PolyControl> PolyControl::clone() const {
75 3648 return m_clone_fn(*this);
76 }
77
78 template <typename Derived>
79 template <typename... Args>
80 11350 inline PolyInner<Derived>::PolyInner(Args&&... args) :
81
5/10
✓ Branch 0 taken 2039 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 818 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
11350 PolyControl(std::in_place_type<Derived>), data(std::forward<Args>(args)...) {
82 11350 }
83
84 } // namespace internal
85
86 /// Copyable unique pointer.
87 ///
88 /// This class is similar to @ref std::polymorphic from C++23.
89 template <typename Base>
90 class Poly {
91 template <typename Derived>
92 friend class Poly;
93
94 public:
95 Poly() = default;
96
97 template <typename Derived, typename... Args>
98 4086 explicit Poly([[maybe_unused]] std::in_place_type_t<Derived> type, Args&&... args) :
99 4086 m_wrapper(std::make_unique<internal::PolyInner<Derived>>(std::forward<Args>(args)...)) {
100 4086 }
101
102 7264 Poly(const Poly& other) : m_wrapper(other.m_wrapper->clone()) {
103 7264 }
104
105 Poly& operator=(const Poly& other) {
106 if (this != &other) {
107 m_wrapper = other.m_wrapper->clone();
108 }
109
110 return *this;
111 }
112
113 template <
114 typename Derived,
115 std::enable_if_t<std::is_base_of_v<Base, Derived> && std::is_convertible_v<const Derived*, const Base*>, bool> =
116 true>
117 9302 Poly(Poly<Derived>&& other) : m_wrapper(std::move(other.m_wrapper)) {
118 9302 }
119
120 template <
121 typename Derived,
122 std::enable_if_t<std::is_base_of_v<Base, Derived> && std::is_convertible_v<const Derived*, const Base*>, bool> =
123 true>
124 Poly& operator=(Poly<Derived>&& other) {
125 m_wrapper = std::move(other.m_wrapper);
126 return *this;
127 }
128
129 14455 [[nodiscard]] const Base* operator->() const {
130 14455 return &m_wrapper->template data<Base>();
131 }
132
133 8 [[nodiscard]] Base* operator->() {
134 8 return &m_wrapper->template data<Base>();
135 }
136
137 3745 [[nodiscard]] const Base& operator*() const {
138 3745 return m_wrapper->template data<Base>();
139 }
140
141 1149 [[nodiscard]] Base& operator*() {
142 1149 return m_wrapper->template data<Base>();
143 }
144
145 private:
146 std::unique_ptr<internal::PolyControl> m_wrapper;
147 };
148
149 template <typename T, typename... Args>
150 1264 [[nodiscard]] Poly<T> make_poly(Args&&... args) {
151 1264 return Poly<T>(std::in_place_type<T>, std::forward<Args>(args)...);
152 }
153
154 } // namespace kai::test
155