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 Simon Heybrock 5 : #include "scipp/core/except.h" 6 : #include "scipp/common/index.h" 7 : #include "scipp/core/dimensions.h" 8 : #include "scipp/core/slice.h" 9 : 10 : namespace scipp::except { 11 : 12 68 : TypeError::TypeError(const std::string &msg) : Error{msg} {} 13 : 14 : template <> 15 1 : void throw_mismatch_error(const core::DType &expected, 16 : const core::DType &actual, 17 : const std::string &optional_message) { 18 3 : throw TypeError("Expected dtype " + to_string(expected) + ", got " + 19 4 : to_string(actual) + '.' + optional_message); 20 : } 21 : 22 251 : DimensionError::DimensionError(const std::string &msg) 23 251 : : Error<core::Dimensions>(msg) {} 24 : 25 0 : DimensionError::DimensionError(scipp::index expectedDim, scipp::index userDim) 26 0 : : DimensionError("Length mismatch on insertion. Expected size: " + 27 0 : std::to_string(std::abs(expectedDim)) + 28 0 : " Requested size: " + std::to_string(userDim)) {} 29 : 30 : namespace { 31 64 : template <class T> std::string format_dims(const T &dims) { 32 64 : if (dims.empty()) { 33 29 : return "a scalar"; 34 : } 35 35 : return "dimensions " + to_string(dims); 36 : } 37 : } // namespace 38 : 39 : template <> 40 1 : void throw_mismatch_error(const core::Sizes &expected, 41 : const core::Sizes &actual, 42 : const std::string &optional_message) { 43 3 : throw DimensionError("Expected " + format_dims(expected) + ", got " + 44 4 : format_dims(actual) + '.' + optional_message); 45 : } 46 : 47 : template <> 48 31 : void throw_mismatch_error(const core::Dimensions &expected, 49 : const core::Dimensions &actual, 50 : const std::string &optional_message) { 51 93 : throw DimensionError("Expected " + format_dims(expected) + ", got " + 52 124 : format_dims(actual) + '.' + optional_message); 53 : } 54 : 55 0 : void throw_dimension_length_error(const core::Dimensions &expected, Dim actual, 56 : index length) { 57 0 : throw DimensionError{"Expected dimension to be in " + to_string(expected) + 58 0 : ", got " + to_string(actual) + 59 0 : " with mismatching length " + std::to_string(length) + 60 0 : '.'}; 61 : } 62 : 63 6 : void throw_cannot_have_variances(const DType type) { 64 6 : throw except::VariancesError("Variances for dtype=" + to_string(type) + 65 12 : " not supported."); 66 : } 67 : 68 : } // namespace scipp::except 69 : 70 : namespace scipp::expect { 71 : namespace { 72 694267 : template <class A, class B> void includes_impl(const A &a, const B &b) { 73 694267 : if (!a.includes(b)) 74 19 : throw except::DimensionError("Expected " + to_string(a) + " to include " + 75 : to_string(b) + "."); 76 694248 : } 77 : } // namespace 78 : 79 58990 : void includes(const core::Sizes &a, const core::Sizes &b) { 80 58990 : includes_impl(a, b); 81 58986 : } 82 : 83 635277 : void includes(const core::Dimensions &a, const core::Dimensions &b) { 84 635277 : includes_impl(a, b); 85 635262 : } 86 : } // namespace scipp::expect 87 : 88 : namespace scipp::core::expect { 89 87601 : void ndim_is(const Sizes &dims, const scipp::index expected) { 90 : using std::to_string; 91 87601 : if (dims.size() != expected) { 92 51 : throw except::DimensionError("Expected " + to_string(expected) + 93 68 : " dimensions, got " + to_string(dims.size())); 94 : } 95 87584 : } 96 : 97 1527411 : void validSlice(const Sizes &dims, const Slice &slice) { 98 1527411 : if (slice == Slice{}) 99 7504 : return; 100 1519907 : const auto end = slice.end() < 0 ? slice.begin() + 1 : slice.end(); 101 1519907 : if (!dims.contains(slice.dim()) || end > dims[slice.dim()]) 102 312 : throw except::SliceError("Expected " + to_string(slice) + " to be in " + 103 416 : to_string(dims) + "."); 104 : } 105 : 106 1501056 : void validDim(const Dim dim) { 107 1501056 : if (dim == Dim::Invalid) 108 0 : throw except::DimensionError("Dim::Invalid is not a valid dimension."); 109 1501056 : } 110 : 111 2378069 : void validExtent(const scipp::index size) { 112 2378069 : if (size < 0) 113 0 : throw except::DimensionError("Dimension size cannot be negative."); 114 2378069 : } 115 : 116 : } // namespace scipp::core::expect