Line data Source code
1 : // SPDX-License-Identifier: BSD-3-Clause 2 : // Copyright (c) 2023 Scipp contributors (https://github.com/scipp) 3 : /// @file 4 : /// @author Jan-Lukas Wynen 5 : #include <array> 6 : #include <cmath> 7 : #include <type_traits> 8 : 9 : #include "scipp/common/overloaded.h" 10 : #include "scipp/core/element/arg_list.h" 11 : #include "scipp/core/tag_util.h" 12 : #include "scipp/core/transform_common.h" 13 : #include "scipp/variable/astype.h" 14 : #include "scipp/variable/transform.h" 15 : #include "scipp/variable/variable.h" 16 : #include "scipp/variable/variable_factory.h" 17 : 18 : namespace scipp::variable { 19 : 20 : struct MakeVariableWithType { 21 : using AllSourceTypes = std::tuple<double, float, int64_t, int32_t, bool>; 22 : 23 : template <class T> struct Maker { 24 29904 : template <size_t I, class... Types> constexpr static auto source_types() { 25 : if constexpr (I == std::tuple_size_v<AllSourceTypes>) { 26 4984 : return std::tuple<Types...>{}; 27 : } else { 28 : using Next = typename std::tuple_element<I, AllSourceTypes>::type; 29 : if constexpr (std::is_same_v<Next, T>) { 30 4984 : return source_types<I + 1, Types...>(); 31 : } else { 32 19936 : return source_types<I + 1, Types..., Next>(); 33 : } 34 : } 35 : } 36 : 37 : template <class... SourceTypes> 38 4984 : static Variable apply_impl(const Variable &parent, 39 : std::tuple<SourceTypes...>) { 40 : using namespace core::transform_flags; 41 : constexpr auto expect_input_variances = 42 : conditional_flag<!core::canHaveVariances<T>()>( 43 : expect_no_variance_arg<0>); 44 : return transform<SourceTypes...>( 45 : parent, 46 : overloaded{ 47 4984 : expect_input_variances, [](const units::Unit &x) { return x; }, 48 2128576 : [](const auto &x) { 49 : if constexpr (is_ValueAndVariance_v<std::decay_t<decltype(x)>>) 50 42 : return ValueAndVariance<T>{static_cast<T>(x.value), 51 42 : static_cast<T>(x.variance)}; 52 : else 53 2128534 : return static_cast<T>(x); 54 : }}, 55 4984 : "astype"); 56 : } 57 : 58 4984 : static Variable apply(const Variable &parent) { 59 4984 : return apply_impl(parent, source_types<0>()); 60 : } 61 : }; 62 : 63 4988 : static Variable make(const Variable &var, DType type) { 64 : return core::CallDType<double, float, int64_t, int32_t, bool>::apply<Maker>( 65 4988 : type, var); 66 : } 67 : }; 68 : 69 673105 : Variable astype(const Variable &var, DType type, const CopyPolicy copy) { 70 1346206 : return type == variableFactory().elem_dtype(var) 71 : ? (copy == CopyPolicy::TryAvoid ? var : variable::copy(var)) 72 1346206 : : MakeVariableWithType::make(var, type); 73 : } 74 : 75 47604 : DType common_type(const Variable &a, const Variable &b) { 76 47604 : return common_type(variableFactory().elem_dtype(a), 77 95208 : variableFactory().elem_dtype(b)); 78 : } 79 : 80 : } // namespace scipp::variable