@@ -20,34 +20,33 @@ namespace Mantid {
20
20
namespace NeXus {
21
21
namespace NeXusIOHelper {
22
22
23
- struct AllowNarrowing {};
24
- struct PreventNarrowing {};
23
+ enum class Narrowing : bool { Allow = true , Prevent = false };
25
24
26
25
namespace {
27
26
28
27
// / Macro to run a function depending on the type of data in the Nexus file
29
- #define RUN_NEXUSIOHELPER_FUNCTION (Narrow , type, func_name, ...) \
28
+ #define RUN_NEXUSIOHELPER_FUNCTION (narrow , type, func_name, ...) \
30
29
switch (type) { \
31
30
case NXnumtype::FLOAT32: \
32
- return func_name<T, float , Narrow >(__VA_ARGS__); \
31
+ return func_name<T, float , narrow >(__VA_ARGS__); \
33
32
case NXnumtype::FLOAT64: \
34
- return func_name<T, double , Narrow >(__VA_ARGS__); \
33
+ return func_name<T, double , narrow >(__VA_ARGS__); \
35
34
case NXnumtype::INT8: \
36
- return func_name<T, int8_t , Narrow >(__VA_ARGS__); \
35
+ return func_name<T, int8_t , narrow >(__VA_ARGS__); \
37
36
case NXnumtype::UINT8: \
38
- return func_name<T, uint8_t , Narrow >(__VA_ARGS__); \
37
+ return func_name<T, uint8_t , narrow >(__VA_ARGS__); \
39
38
case NXnumtype::INT16: \
40
- return func_name<T, int16_t , Narrow >(__VA_ARGS__); \
39
+ return func_name<T, int16_t , narrow >(__VA_ARGS__); \
41
40
case NXnumtype::UINT16: \
42
- return func_name<T, uint16_t , Narrow >(__VA_ARGS__); \
41
+ return func_name<T, uint16_t , narrow >(__VA_ARGS__); \
43
42
case NXnumtype::INT32: \
44
- return func_name<T, int32_t , Narrow >(__VA_ARGS__); \
43
+ return func_name<T, int32_t , narrow >(__VA_ARGS__); \
45
44
case NXnumtype::UINT32: \
46
- return func_name<T, uint32_t , Narrow >(__VA_ARGS__); \
45
+ return func_name<T, uint32_t , narrow >(__VA_ARGS__); \
47
46
case NXnumtype::INT64: \
48
- return func_name<T, int64_t , Narrow >(__VA_ARGS__); \
47
+ return func_name<T, int64_t , narrow >(__VA_ARGS__); \
49
48
case NXnumtype::UINT64: \
50
- return func_name<T, uint64_t , Narrow >(__VA_ARGS__); \
49
+ return func_name<T, uint64_t , narrow >(__VA_ARGS__); \
51
50
default : \
52
51
throw std::runtime_error (" NeXusIOHelper: Unknown type in Nexus file" ); \
53
52
}
@@ -67,135 +66,113 @@ std::pair<::NeXus::Info, bool> checkIfOpenAndGetInfo(::NeXus::File &file, const
67
66
return info_and_close;
68
67
}
69
68
70
- // / Use the getData function to read the buffer into vector and close file if
71
- // / needed
72
- template <typename T> void callGetData (::NeXus::File &file, std::vector<T> &buf, const bool close_file) {
73
- file.getData (buf);
74
- if (close_file)
75
- file.closeData ();
76
- }
77
-
78
- // / Use the getData function to read the buffer and close file if needed
79
- template <typename T> void callGetData (::NeXus::File &file, T &buf, const bool close_file) {
80
- file.getData (&buf);
81
- if (close_file)
82
- file.closeData ();
83
- }
84
-
85
- // / Use the getSlab function to read the buffer and close file if needed
86
- template <typename T>
87
- void callGetSlab (::NeXus::File &file, std::vector<T> &buf, const std::vector<int64_t > &start,
88
- const std::vector<int64_t > &size, const bool close_file) {
89
- file.getSlab (buf.data (), start, size);
90
- if (close_file)
91
- file.closeData ();
92
- }
93
-
94
69
/* * Templated function to read any type of vector and (potentially) convert it
95
70
* to another type. If the two types are the same, the conversion is skipped.
96
71
*/
97
- template <typename T, typename U, typename Narrow >
98
- void doReadNexusAnyVector (std::vector<T> &out, ::NeXus::File &file, const size_t size, const bool close_file ) {
99
- if constexpr (sizeof (T) < sizeof (U) && !std::is_same_v<Narrow, AllowNarrowing> ) {
100
- if (close_file )
72
+ template <typename T, typename U, Narrowing narrow >
73
+ void doReadNexusAnyVector (std::vector<T> &out, ::NeXus::File &file, const size_t size, const bool close_data ) {
74
+ if constexpr (sizeof (T) < sizeof (U) && narrow == Narrowing::Prevent ) {
75
+ if (close_data )
101
76
file.closeData ();
102
77
throw std::runtime_error (" Narrowing is forbidden in NeXusIOHelper::readNexusAnyVector" );
103
78
} else if constexpr (std::is_same_v<T, U>) {
104
- if (size > 0 )
105
- callGetData (file, out, close_file);
106
- else {
107
- if (close_file) {
108
- file.closeData ();
109
- }
79
+ if (size > 0 ) {
80
+ file.getData (out);
110
81
}
111
82
} else {
112
83
if (size > 0 ) {
113
84
std::vector<U> buf (size);
114
- callGetData ( file, buf, close_file );
85
+ file. getData ( buf);
115
86
std::transform (buf.cbegin (), buf.cend (), out.begin (), [](U a) -> T { return static_cast <T>(a); });
116
- } else {
117
- if (close_file) {
118
- file.closeData ();
119
- }
120
87
}
121
88
}
89
+ if (close_data) {
90
+ file.closeData ();
91
+ }
122
92
}
123
93
124
94
// / Read any type of vector and return it as a new vector.
125
- template <typename T, typename U, typename Narrow >
126
- std::vector<T> readNexusAnyVector (::NeXus::File &file, const size_t size, const bool close_file ) {
95
+ template <typename T, typename U, Narrowing narrow >
96
+ std::vector<T> readNexusAnyVector (::NeXus::File &file, const size_t size, const bool close_data ) {
127
97
std::vector<T> vec (size);
128
- doReadNexusAnyVector<T, U, Narrow >(vec, file, size, close_file );
98
+ doReadNexusAnyVector<T, U, narrow >(vec, file, size, close_data );
129
99
return vec;
130
100
}
131
101
132
102
// / Read any type of vector and store it into the provided buffer vector.
133
- template <typename T, typename U, typename Narrow >
134
- void readNexusAnyVector (std::vector<T> &out, ::NeXus::File &file, const size_t size, const bool close_file ) {
103
+ template <typename T, typename U, Narrowing narrow >
104
+ void readNexusAnyVector (std::vector<T> &out, ::NeXus::File &file, const size_t size, const bool close_data ) {
135
105
if (out.size () < size)
136
106
throw std::runtime_error (" The output buffer is too small in NeXusIOHelper::readNexusAnyVector" );
137
- doReadNexusAnyVector<T, U, Narrow >(out, file, size, close_file );
107
+ doReadNexusAnyVector<T, U, narrow >(out, file, size, close_data );
138
108
}
139
109
140
110
/* * Templated function to read any type of slab and (potentially) convert it to
141
111
* another type. If the two types are the same, the conversion is skipped.
142
112
*/
143
- template <typename T, typename U, typename Narrow >
113
+ template <typename T, typename U, Narrowing narrow >
144
114
void doReadNexusAnySlab (std::vector<T> &out, ::NeXus::File &file, const std::vector<int64_t > &start,
145
- const std::vector<int64_t > &size, const int64_t volume, const bool close_file ) {
146
- if constexpr (sizeof (T) < sizeof (U) && !std::is_same_v<Narrow, AllowNarrowing> ) {
147
- if (close_file )
115
+ const std::vector<int64_t > &size, const int64_t volume, const bool close_data ) {
116
+ if constexpr (sizeof (T) < sizeof (U) && narrow == Narrowing::Prevent ) {
117
+ if (close_data )
148
118
file.closeData ();
149
119
throw std::runtime_error (" Narrowing is forbidden in NeXusIOHelper::readNexusAnySlab" );
150
120
} else if constexpr (std::is_same_v<T, U>) {
151
- if (volume > 0 )
152
- callGetSlab (file, out, start, size, close_file);
121
+ if (volume > 0 ) {
122
+ file.getSlab (out.data (), start, size);
123
+ }
153
124
} else {
154
125
if (volume > 0 ) {
155
126
std::vector<U> buf (volume);
156
- callGetSlab ( file, buf, start, size, close_file );
127
+ file. getSlab ( buf. data () , start, size);
157
128
std::transform (buf.cbegin (), buf.cend (), out.begin (), [](U a) -> T { return static_cast <T>(a); });
158
129
}
159
130
}
131
+ if (volume > 0 && close_data) {
132
+ file.closeData ();
133
+ }
160
134
}
161
135
162
136
// / Read any type of slab and return it as a new vector.
163
- template <typename T, typename U, typename Narrow >
137
+ template <typename T, typename U, Narrowing narrow >
164
138
std::vector<T> readNexusAnySlab (::NeXus::File &file, const std::vector<int64_t > &start,
165
- const std::vector<int64_t > &size, const bool close_file ) {
139
+ const std::vector<int64_t > &size, const bool close_data ) {
166
140
const auto volume = vectorVolume (size);
167
141
std::vector<T> vec (volume);
168
- doReadNexusAnySlab<T, U, Narrow >(vec, file, start, size, volume, close_file );
142
+ doReadNexusAnySlab<T, U, narrow >(vec, file, start, size, volume, close_data );
169
143
return vec;
170
144
}
171
145
172
146
// / Read any type of slab and store it into the provided buffer vector.
173
- template <typename T, typename U, typename Narrow >
147
+ template <typename T, typename U, Narrowing narrow >
174
148
void readNexusAnySlab (std::vector<T> &out, ::NeXus::File &file, const std::vector<int64_t > &start,
175
- const std::vector<int64_t > &size, const bool close_file ) {
149
+ const std::vector<int64_t > &size, const bool close_data ) {
176
150
const auto volume = vectorVolume (size);
177
151
if (out.size () < static_cast <size_t >(volume))
178
152
throw std::runtime_error (" The output buffer is too small in NeXusIOHelper::readNexusAnySlab" );
179
- doReadNexusAnySlab<T, U, Narrow >(out, file, start, size, volume, close_file );
153
+ doReadNexusAnySlab<T, U, narrow >(out, file, start, size, volume, close_data );
180
154
}
181
155
182
156
/* * Templated function to read any type of variable and (potentially) convert it
183
157
* to another type. If the two types are the same, the conversion is skipped.
184
158
*/
185
- template <typename T, typename U, typename Narrow> T readNexusAnyVariable (::NeXus::File &file, const bool close_file) {
186
- if constexpr (sizeof (T) < sizeof (U) && !std::is_same_v<Narrow, AllowNarrowing>) {
187
- if (close_file)
159
+ template <typename T, typename U, Narrowing narrow> T readNexusAnyVariable (::NeXus::File &file, const bool close_data) {
160
+ T buf;
161
+ if constexpr (sizeof (T) < sizeof (U) && narrow == Narrowing::Prevent) {
162
+ if (close_data)
188
163
file.closeData ();
189
164
throw std::runtime_error (" Narrowing is forbidden in NeXusIOHelper::readAnyVariable" );
190
165
} else if constexpr (std::is_same_v<T, U>) {
191
- T buf;
192
- callGetData (file, buf, close_file);
193
- return buf;
166
+ file.getData (&buf);
194
167
} else {
195
- U buf;
196
- callGetData (file, buf, close_file);
197
- return static_cast <T>(buf);
168
+ U bufu;
169
+ file.getData (&bufu);
170
+ buf = std::move (static_cast <T>(bufu));
171
+ }
172
+ if (close_data) {
173
+ file.closeData ();
198
174
}
175
+ return buf;
199
176
}
200
177
201
178
} // end of anonymous namespace
@@ -204,51 +181,51 @@ template <typename T, typename U, typename Narrow> T readNexusAnyVariable(::NeXu
204
181
* and calls readNexusAnyVector via the RUN_NEXUSIOHELPER_FUNCTION macro.
205
182
* Version that allows Narrowing.
206
183
*/
207
- template <typename T, typename Narrow = PreventNarrowing >
184
+ template <typename T, Narrowing narrow = Narrowing::Prevent >
208
185
std::vector<T> readNexusVector (::NeXus::File &file, const std::string &entry = " " ) {
209
186
const auto info_and_close = checkIfOpenAndGetInfo (file, std::move (std::move (entry)));
210
- RUN_NEXUSIOHELPER_FUNCTION (Narrow , (info_and_close.first ).type , readNexusAnyVector, file,
187
+ RUN_NEXUSIOHELPER_FUNCTION (narrow , (info_and_close.first ).type , readNexusAnyVector, file,
211
188
vectorVolume ((info_and_close.first ).dims ), info_and_close.second );
212
189
}
213
190
214
191
/* * Opens the data group if needed, finds the data type, computes the data size,
215
192
* and calls readNexusAnyVector via the RUN_NEXUSIOHELPER_FUNCTION macro.
216
193
* The provided output buffer is filled.
217
194
*/
218
- template <typename T, typename Narrow = PreventNarrowing >
195
+ template <typename T, Narrowing narrow = Narrowing::Prevent >
219
196
void readNexusVector (std::vector<T> &out, ::NeXus::File &file, const std::string &entry = " " ) {
220
197
const auto info_and_close = checkIfOpenAndGetInfo (file, std::move (std::move (entry)));
221
- RUN_NEXUSIOHELPER_FUNCTION (Narrow , (info_and_close.first ).type , readNexusAnyVector, out, file,
198
+ RUN_NEXUSIOHELPER_FUNCTION (narrow , (info_and_close.first ).type , readNexusAnyVector, out, file,
222
199
vectorVolume ((info_and_close.first ).dims ), info_and_close.second );
223
200
}
224
201
225
202
/* * Opens the data group if needed, finds the data type, and calls
226
203
* readNexusAnySlab via the RUN_NEXUSIOHELPER_FUNCTION macro.
227
204
*/
228
- template <typename T, typename Narrow = PreventNarrowing >
205
+ template <typename T, Narrowing narrow = Narrowing::Prevent >
229
206
std::vector<T> readNexusSlab (::NeXus::File &file, const std::string &entry, const std::vector<int64_t > &start,
230
207
const std::vector<int64_t > &size) {
231
208
const auto info_and_close = checkIfOpenAndGetInfo (file, std::move (std::move (entry)));
232
- RUN_NEXUSIOHELPER_FUNCTION (Narrow , (info_and_close.first ).type , readNexusAnySlab, file, start, size,
209
+ RUN_NEXUSIOHELPER_FUNCTION (narrow , (info_and_close.first ).type , readNexusAnySlab, file, start, size,
233
210
info_and_close.second );
234
211
}
235
212
236
213
/* * Opens the data group if needed, finds the data type, and calls
237
214
* readNexusAnySlab via the RUN_NEXUSIOHELPER_FUNCTION macro.
238
215
* The provided output buffer is filled.
239
216
*/
240
- template <typename T, typename Narrow = PreventNarrowing >
217
+ template <typename T, Narrowing narrow = Narrowing::Prevent >
241
218
void readNexusSlab (std::vector<T> &out, ::NeXus::File &file, const std::string &entry,
242
219
const std::vector<int64_t > &start, const std::vector<int64_t > &size) {
243
220
const auto info_and_close = checkIfOpenAndGetInfo (file, std::move (std::move (entry)));
244
- RUN_NEXUSIOHELPER_FUNCTION (Narrow , (info_and_close.first ).type , readNexusAnySlab, out, file, start, size,
221
+ RUN_NEXUSIOHELPER_FUNCTION (narrow , (info_and_close.first ).type , readNexusAnySlab, out, file, start, size,
245
222
info_and_close.second );
246
223
}
247
224
248
- template <typename T, typename Narrow = PreventNarrowing >
225
+ template <typename T, Narrowing narrow = Narrowing::Prevent >
249
226
T readNexusValue (::NeXus::File &file, const std::string &entry = " " ) {
250
227
const auto info_and_close = checkIfOpenAndGetInfo (file, std::move (std::move (entry)));
251
- RUN_NEXUSIOHELPER_FUNCTION (Narrow , (info_and_close.first ).type , readNexusAnyVariable, file, info_and_close.second );
228
+ RUN_NEXUSIOHELPER_FUNCTION (narrow , (info_and_close.first ).type , readNexusAnyVariable, file, info_and_close.second );
252
229
}
253
230
254
231
} // namespace NeXusIOHelper
0 commit comments