commit 36f6562cbff550d18d823a9499e4638ba7f36969
parent e96e4ecfbd02ad6bb84f648fe627b3138fa8faa0
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date: Thu, 8 Sep 2016 18:24:52 +0300
Expressions refactoring
Diffstat:
8 files changed, 115 insertions(+), 173 deletions(-)
diff --git a/include/kfr/base.hpp b/include/kfr/base.hpp
@@ -30,7 +30,6 @@
#include "base/compiletime.hpp"
#include "base/complex.hpp"
#include "base/constants.hpp"
-#include "base/conversion.hpp"
#include "base/cpuid.hpp"
#include "base/cpuid_auto.hpp"
#include "base/digitreverse.hpp"
diff --git a/include/kfr/base/basic_expressions.hpp b/include/kfr/base/basic_expressions.hpp
@@ -34,6 +34,20 @@ namespace kfr
namespace internal
{
+
+template <typename To, typename E>
+struct expression_convert : expression<E>
+{
+ using value_type = To;
+ CMT_INLINE expression_convert(E&& expr) noexcept : expression<E>(std::forward<E>(expr)) {}
+
+ template <size_t N>
+ CMT_INLINE vec<To, N> operator()(cinput_t, size_t index, vec_t<To, N>) const
+ {
+ return this->argument_first(index, vec_t<To, N>());
+ }
+};
+
template <typename T, typename E1>
struct expression_iterator
{
@@ -63,6 +77,12 @@ struct expression_iterator
};
}
+template <typename To, typename E>
+CMT_INLINE internal::expression_convert<To, E> convert(E&& expr)
+{
+ return internal::expression_convert<To, E>(std::forward<E>(expr));
+}
+
template <typename E1, typename T = value_type_of<E1>>
CMT_INLINE internal::expression_iterator<T, E1> to_iterator(E1&& e1)
{
@@ -408,5 +428,67 @@ struct multioutput : output_expression
private:
};
+
+template <typename... E>
+struct expression_pack : expression<E...>, output_expression
+{
+ constexpr static size_t count = sizeof...(E);
+
+ expression_pack(E&&... e) : expression<E...>(std::forward<E>(e)...) {}
+ using value_type = vec<common_type<value_type_of<E>...>, count>;
+ using T = value_type;
+
+ using expression<E...>::size;
+
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
+ {
+ return this->call(fn::packtranspose(), index, y);
+ }
+};
+
+template <typename... E>
+struct expression_unpack : private expression<E...>, output_expression
+{
+ constexpr static size_t count = sizeof...(E);
+
+ expression_unpack(E&&... e) : expression<E...>(std::forward<E>(e)...) {}
+
+ using expression<E...>::size;
+
+ template <typename U, size_t N>
+ CMT_INLINE void operator()(coutput_t, size_t index, const vec<vec<U, count>, N>& x)
+ {
+ output(index, x, csizeseq<count>);
+ }
+
+ template <typename Input, KFR_ENABLE_IF(is_input_expression<Input>::value)>
+ CMT_INLINE expression_unpack& operator=(Input&& input)
+ {
+ using value_type = vec<common_type<value_type_of<E>...>, count>;
+ process<value_type>(*this, std::forward<Input>(input));
+ return *this;
+ }
+
+private:
+ template <typename U, size_t N, size_t... indices>
+ void output(size_t index, const vec<vec<U, count>, N>& x, csizes_t<indices...>)
+ {
+ const vec<vec<U, N>, count> xx = compcast<vec<U, N>>(transpose<count>(flatten(x)));
+ swallow{ (std::get<indices>(this->args)(coutput, index, xx[indices]), void(), 0)... };
+ }
+};
+}
+
+template <typename... E, KFR_ENABLE_IF(is_output_expressions<E...>::value)>
+internal::expression_unpack<internal::arg<E>...> unpack(E&&... e)
+{
+ return internal::expression_unpack<internal::arg<E>...>(std::forward<E>(e)...);
+}
+
+template <typename... E, KFR_ENABLE_IF(is_input_expressions<E...>::value)>
+internal::expression_pack<internal::arg<E>...> pack(E&&... e)
+{
+ return internal::expression_pack<internal::arg<E>...>(std::forward<E>(e)...);
}
}
diff --git a/include/kfr/base/conversion.hpp b/include/kfr/base/conversion.hpp
@@ -1,57 +0,0 @@
-/** @addtogroup expressions
- * @{
- */
-/*
- Copyright (C) 2016 D Levin (https://www.kfrlib.com)
- This file is part of KFR
-
- KFR is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- KFR is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with KFR.
-
- If GPL is not suitable for your project, you must purchase a commercial license to use KFR.
- Buying a commercial license is mandatory as soon as you develop commercial activities without
- disclosing the source code of your own applications.
- See https://www.kfrlib.com for details.
- */
-
-#pragma once
-
-#include "basic_expressions.hpp"
-#include "function.hpp"
-#include "operators.hpp"
-#include "vec.hpp"
-
-namespace kfr
-{
-namespace internal
-{
-template <typename To, typename E>
-struct expression_convert : expression<E>
-{
- using value_type = To;
- CMT_INLINE expression_convert(E&& expr) noexcept : expression<E>(std::forward<E>(expr)) {}
-
- template <size_t N>
- CMT_INLINE vec<To, N> operator()(cinput_t, size_t index, vec_t<To, N>) const
- {
- return this->argument_first(index, vec_t<To, N>());
- }
-};
-}
-
-template <typename To, typename E>
-CMT_INLINE internal::expression_convert<To, E> convert(E&& expr)
-{
- return internal::expression_convert<To, E>(std::forward<E>(expr));
-}
-}
diff --git a/include/kfr/base/function.hpp b/include/kfr/base/function.hpp
@@ -53,46 +53,6 @@ namespace kfr
return to_scalar(::kfr::intrinsics::fn(vecout(a), vecout(b)...)); \
}
-namespace internal
-{
-template <typename T>
-struct flt_type_impl
-{
- using type = fbase;
-};
-
-template <typename T, size_t N>
-struct flt_type_impl<vec<T, N>>
-{
- using type = vec<fbase, N>;
-};
-
-template <>
-struct flt_type_impl<float>
-{
- using type = float;
-};
-template <>
-struct flt_type_impl<double>
-{
- using type = double;
-};
-
-template <size_t N>
-struct flt_type_impl<vec<float, N>>
-{
- using type = vec<float, N>;
-};
-template <size_t N>
-struct flt_type_impl<vec<double, N>>
-{
- using type = vec<double, N>;
-};
-}
-
-template <typename T>
-using flt_type = typename internal::flt_type_impl<T>::type;
-
namespace intrinsics
{
#ifdef CMT_ARCH_X86
diff --git a/include/kfr/base/operators.hpp b/include/kfr/base/operators.hpp
@@ -132,15 +132,10 @@ KFR_FN(mul)
/**
* @brief Returns template expression that returns product of all the arguments passed to a function.
*/
-template <typename E1, typename E2, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)>
-CMT_INLINE internal::expression_function<fn::mul, E1, E2> mul(E1&& x, E2&& y)
-{
- return { fn::mul(), std::forward<E1>(x), std::forward<E2>(y) };
-}
-template <typename E1, typename E2, typename E3, KFR_ENABLE_IF(is_input_expressions<E1, E2>::value)>
-CMT_INLINE internal::expression_function<fn::mul, E1> mul(E1&& x, E2&& y, E3&& z)
+template <typename... E, KFR_ENABLE_IF(is_input_expressions<E...>::value)>
+CMT_INLINE internal::expression_function<fn::mul, E...> mul(E&&... x)
{
- return { fn::mul(), std::forward<E1>(x), std::forward<E2>(y), std::forward<E3>(z) };
+ return { fn::mul(), std::forward<E>(x)... };
}
/**
@@ -695,69 +690,4 @@ vec<vec<T, sizeof...(Ns) + 1>, N1> packtranspose(const vec<T, N1>& x, const vec<
}
KFR_FN(packtranspose)
-
-namespace internal
-{
-template <typename... E>
-struct expression_pack : expression<E...>, output_expression
-{
- constexpr static size_t count = sizeof...(E);
-
- expression_pack(E&&... e) : expression<E...>(std::forward<E>(e)...) {}
- using value_type = vec<common_type<value_type_of<E>...>, count>;
- using T = value_type;
-
- using expression<E...>::size;
-
- template <size_t N>
- CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
- {
- return this->call(fn::packtranspose(), index, y);
- }
-};
-
-template <typename... E>
-struct expression_unpack : private expression<E...>, output_expression
-{
- constexpr static size_t count = sizeof...(E);
-
- expression_unpack(E&&... e) : expression<E...>(std::forward<E>(e)...) {}
-
- using expression<E...>::size;
-
- template <typename U, size_t N>
- CMT_INLINE void operator()(coutput_t, size_t index, const vec<vec<U, count>, N>& x)
- {
- output(index, x, csizeseq<count>);
- }
-
- template <typename Input, KFR_ENABLE_IF(is_input_expression<Input>::value)>
- CMT_INLINE expression_unpack& operator=(Input&& input)
- {
- using value_type = vec<common_type<value_type_of<E>...>, count>;
- process<value_type>(*this, std::forward<Input>(input));
- return *this;
- }
-
-private:
- template <typename U, size_t N, size_t... indices>
- void output(size_t index, const vec<vec<U, count>, N>& x, csizes_t<indices...>)
- {
- const vec<vec<U, N>, count> xx = compcast<vec<U, N>>(transpose<count>(flatten(x)));
- swallow{ (std::get<indices>(this->args)(coutput, index, xx[indices]), void(), 0)... };
- }
-};
-}
-
-template <typename... E, KFR_ENABLE_IF(is_output_expressions<E...>::value)>
-internal::expression_unpack<internal::arg<E>...> unpack(E&&... e)
-{
- return internal::expression_unpack<internal::arg<E>...>(std::forward<E>(e)...);
-}
-
-template <typename... E, KFR_ENABLE_IF(is_input_expressions<E...>::value)>
-internal::expression_pack<internal::arg<E>...> pack(E&&... e)
-{
- return internal::expression_pack<internal::arg<E>...>(std::forward<E>(e)...);
-}
}
diff --git a/include/kfr/base/types.hpp b/include/kfr/base/types.hpp
@@ -261,6 +261,29 @@ using enable_if_not_f = enable_if<typeclass<T> != datatype::f, R>;
namespace internal
{
+template <typename T>
+struct flt_type_impl
+{
+ using type = fbase;
+};
+
+template <>
+struct flt_type_impl<float>
+{
+ using type = float;
+};
+template <>
+struct flt_type_impl<double>
+{
+ using type = double;
+};
+}
+
+template <typename T>
+using flt_type = typename internal::flt_type_impl<T>::type;
+
+namespace internal
+{
#ifdef CMT_COMPILER_CLANG
#define builtin_addressof(x) __builtin_addressof(x)
#else
diff --git a/include/kfr/base/vec.hpp b/include/kfr/base/vec.hpp
@@ -59,6 +59,13 @@ struct mask;
namespace internal
{
+
+template <typename T, size_t N>
+struct flt_type_impl<vec<T, N>>
+{
+ using type = vec<typename flt_type_impl<T>::type, N>;
+};
+
template <typename T>
struct is_vec_impl : std::false_type
{
@@ -1332,7 +1339,6 @@ CMT_INLINE vec_t<T, Nout> high(vec_t<T, N>)
}
KFR_FN(low)
KFR_FN(high)
-
}
#pragma clang diagnostic pop
diff --git a/sources.cmake b/sources.cmake
@@ -21,7 +21,6 @@ set(
${PROJECT_SOURCE_DIR}/include/kfr/base/compiletime.hpp
${PROJECT_SOURCE_DIR}/include/kfr/base/complex.hpp
${PROJECT_SOURCE_DIR}/include/kfr/base/constants.hpp
- ${PROJECT_SOURCE_DIR}/include/kfr/base/conversion.hpp
${PROJECT_SOURCE_DIR}/include/kfr/base/cpuid.hpp
${PROJECT_SOURCE_DIR}/include/kfr/base/cpuid_auto.hpp
${PROJECT_SOURCE_DIR}/include/kfr/base/digitreverse.hpp