commit c6cf5bbf7d16472dace59b0cddaffd88964ed33f
parent 51111bd019c87aade9a268a0a3ef4975c737c875
Author: [email protected] <[email protected]>
Date: Thu, 10 Nov 2022 16:10:37 +0000
Fixes for older compilers: counter and memory_finalizer
Diffstat:
4 files changed, 56 insertions(+), 25 deletions(-)
diff --git a/include/kfr/base/basic_expressions.hpp b/include/kfr/base/basic_expressions.hpp
@@ -102,8 +102,14 @@ struct expression_traits<expression_counter<T, Dims>> : expression_traits_defaul
template <typename T = int, typename Arg = T, typename... Args,
typename Tout = std::common_type_t<T, Arg, Args...>>
-KFR_INTRINSIC expression_counter<Tout, 1 + sizeof...(Args)> counter(T start = T(0), Arg step = 1,
- Args... steps)
+KFR_INTRINSIC expression_counter<Tout, 1> counter(T start = 0)
+{
+ return { static_cast<Tout>(std::move(start)), { static_cast<Tout>(1) } };
+}
+
+template <typename T = int, typename Arg = T, typename... Args,
+ typename Tout = std::common_type_t<T, Arg, Args...>>
+KFR_INTRINSIC expression_counter<Tout, 1 + sizeof...(Args)> counter(T start, Arg step, Args... steps)
{
return { static_cast<Tout>(std::move(start)),
{ static_cast<Tout>(std::move(step)), static_cast<Tout>(std::move(steps))... } };
diff --git a/include/kfr/base/simd_expressions.hpp b/include/kfr/base/simd_expressions.hpp
@@ -425,70 +425,70 @@ KFR_INTRINSIC expression_function<fn::satsub, E1, E2> satsub(E1&& x, E2&& y)
template <typename E1, typename E2, enable_if_input_output_expression<E1>* = nullptr,
enable_if_input_expression<E2>* = nullptr>
-KFR_INTRINSIC E1& operator+=(E1& e1, E2&& e2)
+KFR_INTRINSIC E1& operator+=(E1&& e1, E2&& e2)
{
process(e1, operator+(e1, e2));
return e1;
}
template <typename E1, typename E2, enable_if_input_output_expression<E1>* = nullptr,
enable_if_input_expression<E2>* = nullptr>
-KFR_INTRINSIC E1& operator-=(E1& e1, E2&& e2)
+KFR_INTRINSIC E1& operator-=(E1&& e1, E2&& e2)
{
process(e1, operator-(e1, e2));
return e1;
}
template <typename E1, typename E2, enable_if_input_output_expression<E1>* = nullptr,
enable_if_input_expression<E2>* = nullptr>
-KFR_INTRINSIC E1& operator*=(E1& e1, E2&& e2)
+KFR_INTRINSIC E1& operator*=(E1&& e1, E2&& e2)
{
process(e1, operator*(e1, e2));
return e1;
}
template <typename E1, typename E2, enable_if_input_output_expression<E1>* = nullptr,
enable_if_input_expression<E2>* = nullptr>
-KFR_INTRINSIC E1& operator/=(E1& e1, E2&& e2)
+KFR_INTRINSIC E1& operator/=(E1&& e1, E2&& e2)
{
process(e1, operator/(e1, e2));
return e1;
}
template <typename E1, typename E2, enable_if_input_output_expression<E1>* = nullptr,
enable_if_input_expression<E2>* = nullptr>
-KFR_INTRINSIC E1& operator%=(E1& e1, E2&& e2)
+KFR_INTRINSIC E1& operator%=(E1&& e1, E2&& e2)
{
process(e1, operator%(e1, e2));
return e1;
}
template <typename E1, typename E2, enable_if_input_output_expression<E1>* = nullptr,
enable_if_input_expression<E2>* = nullptr>
-KFR_INTRINSIC E1& operator|=(E1& e1, E2&& e2)
+KFR_INTRINSIC E1& operator|=(E1&& e1, E2&& e2)
{
process(e1, operator|(e1, e2));
return e1;
}
template <typename E1, typename E2, enable_if_input_output_expression<E1>* = nullptr,
enable_if_input_expression<E2>* = nullptr>
-KFR_INTRINSIC E1& operator&=(E1& e1, E2&& e2)
+KFR_INTRINSIC E1& operator&=(E1&& e1, E2&& e2)
{
process(e1, operator&(e1, e2));
return e1;
}
template <typename E1, typename E2, enable_if_input_output_expression<E1>* = nullptr,
enable_if_input_expression<E2>* = nullptr>
-KFR_INTRINSIC E1& operator^=(E1& e1, E2&& e2)
+KFR_INTRINSIC E1& operator^=(E1&& e1, E2&& e2)
{
process(e1, operator^(e1, e2));
return e1;
}
template <typename E1, typename E2, enable_if_input_output_expression<E1>* = nullptr,
enable_if_input_expression<E2>* = nullptr>
-KFR_INTRINSIC E1& operator<<=(E1& e1, E2&& e2)
+KFR_INTRINSIC E1& operator<<=(E1&& e1, E2&& e2)
{
process(e1, operator<<(e1, e2));
return e1;
}
template <typename E1, typename E2, enable_if_input_output_expression<E1>* = nullptr,
enable_if_input_expression<E2>* = nullptr>
-KFR_INTRINSIC E1& operator>>=(E1& e1, E2&& e2)
+KFR_INTRINSIC E1& operator>>=(E1&& e1, E2&& e2)
{
process(e1, operator>>(e1, e2));
return e1;
diff --git a/include/kfr/base/tensor.hpp b/include/kfr/base/tensor.hpp
@@ -45,12 +45,32 @@ CMT_PRAGMA_MSVC(warning(disable : 4324))
namespace kfr
{
-using memory_finalizer = std::shared_ptr<void>;
+namespace internal_generic
+{
+struct memory_finalizer_base
+{
+ virtual ~memory_finalizer_base() {}
+};
+template <typename Data>
+struct memory_finalizer_data : public memory_finalizer_base
+{
+ constexpr KFR_INTRINSIC memory_finalizer_data(Data&& data) : data(std::move(data)) {}
+ Data data;
+};
+template <typename Func>
+struct memory_finalizer_func : public memory_finalizer_data<Func>
+{
+ using memory_finalizer_data<Func>::memory_finalizer_data;
+ KFR_INTRINSIC ~memory_finalizer_func() { this->data(); }
+};
+} // namespace internal_generic
+
+using memory_finalizer = std::shared_ptr<internal_generic::memory_finalizer_base>;
template <typename Fn>
memory_finalizer KFR_INTRINSIC make_memory_finalizer(Fn&& fn)
{
- return std::shared_ptr<void>(nullptr, [fn = std::move(fn)](void*) { fn(); });
+ return memory_finalizer(new internal_generic::memory_finalizer_func<Fn>{ std::move(fn) });
}
template <typename T, typename Derived, typename Dims>
@@ -842,20 +862,14 @@ private:
template <typename Container, CMT_ENABLE_IF(kfr::has_data_size<Container>),
typename T = typename Container::value_type>
-KFR_INTRINSIC tensor<T, 1> tensor_from_container(Container vector)
+KFR_INTRINSIC tensor<T, 1> tensor_from_container(Container container)
{
- struct vector_finalizer
- {
- mutable std::optional<Container> vector;
- void operator()(void*) const { vector.reset(); }
- };
-
- vector_finalizer finalizer{ std::move(vector) };
+ using container_finalizer = internal_generic::memory_finalizer_data<Container>;
+ memory_finalizer mem = memory_finalizer(new container_finalizer{ std::move(container) });
- memory_finalizer mem = std::shared_ptr<void>(nullptr, std::move(finalizer));
- vector_finalizer* fin = std::get_deleter<vector_finalizer>(mem);
+ Container* ptr = &static_cast<container_finalizer*>(mem.get())->data;
- return tensor<T, 1>(fin->vector->data(), make_vector<index_t>(fin->vector->size()), std::move(mem));
+ return tensor<T, 1>(ptr->data(), shape{ ptr->size() }, std::move(mem));
}
template <typename T, index_t Dims>
diff --git a/tests/unit/base/tensor.cpp b/tests/unit/base/tensor.cpp
@@ -785,6 +785,17 @@ TEST(from_ilist)
CHECK(t4 == tensor<float, 3>(shape{ 2, 2, 2 }, { 10, 20, 30, 40, 50, 60, 70, 80 }));
}
+TEST(tensor_from_container)
+{
+ std::vector<int> a{ 1, 2, 3 };
+ auto t = tensor_from_container(a);
+ CHECK(t.shape() == shape{ 3 });
+ CHECK(t == tensor<int, 1>{ 1, 2, 3 });
+ auto t2 = t; // share data
+ t(0) = 100;
+ CHECK(t2 == tensor<int, 1>{ 100, 2, 3 });
+}
+
} // namespace CMT_ARCH_NAME
} // namespace kfr