Skip to content

Commit a8b5c30

Browse files
authored
Merge pull request #208 from njoy/feature/map-to-list
Feature/map to list
2 parents d8182cc + 7de0507 commit a8b5c30

36 files changed

+481
-246
lines changed

python/src/ENDFtk.python.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ PYBIND11_MODULE( ENDFtk, module ) {
7272

7373
// wrap some basic recurring views
7474
// none of these are supposed to be created directly by the user
75+
wrapBasicBidirectionalAnyViewOf< int >(
76+
viewmodule,
77+
"any_view< int, bidirectional >" );
7578
wrapBasicRandomAccessAnyViewOf< double >(
7679
viewmodule,
7780
"any_view< double, random_access >" );

python/src/tree/File.python.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
// local includes
66
#include "ENDFtk/tree/Tape.hpp"
7-
#include "range/v3/range/operations.hpp"
87
#include "views.hpp"
98
#include "variants.hpp"
109

@@ -98,8 +97,8 @@ void wrapTreeFile( python::module& module, python::module& viewmodule ) {
9897
.def_property_readonly(
9998

10099
"section_numbers",
101-
[] ( const File& self ) -> std::vector< int >
102-
{ return ranges::to< std::vector< int > >( self.sectionNumbers() ); },
100+
[] ( const File& self ) -> IntList
101+
{ return self.sectionNumbers(); },
103102
"All section numbers in the file"
104103
)
105104
.def_property_readonly(

python/src/tree/Material.python.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ void wrapTreeMaterial( python::module& module, python::module& viewmodule ) {
111111
.def_property_readonly(
112112

113113
"file_numbers",
114-
[] ( const Material& self ) -> std::vector< int >
115-
{ return ranges::to< std::vector< int > >( self.fileNumbers() ); },
114+
[] ( const Material& self ) -> IntList
115+
{ return self.fileNumbers(); },
116116
"All file numbers in the material"
117117
)
118118
.def_property_readonly(

python/src/views.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ using RandomAccessAnyView = BasicRandomAccessAnyView< RefWrapper< Element > >;
5151
/**
5252
* @brief Some recurring basic views
5353
*/
54+
using IntList = BasicBidirectionalAnyView< int >;
5455
using DoubleRange = BasicRandomAccessAnyView< double >;
5556
using LongRange = BasicRandomAccessAnyView< long >;
5657
using IntRange = BasicRandomAccessAnyView< int >;

python/test/tree/Test_ENDFtk_Tree_Tape.py

+29-29
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def verify_file1( self, file ) :
3737
self.assertEqual( 1, file.MF )
3838
self.assertEqual( 1, file.file_number )
3939

40-
self.assertEqual( [ 451 ], file.section_numbers )
40+
self.assertEqual( [ 451 ], file.section_numbers.to_list() )
4141
self.assertEqual( [ 451 ],
4242
[ section.MT for section in file.sections ] )
4343

@@ -61,7 +61,7 @@ def verify_file2( self, file ) :
6161
self.assertEqual( 2, file.MF )
6262
self.assertEqual( 2, file.file_number )
6363

64-
self.assertEqual( [ 151 ], file.section_numbers )
64+
self.assertEqual( [ 151 ], file.section_numbers.to_list() )
6565
self.assertEqual( [ 151 ],
6666
[ section.MT for section in file.sections ] )
6767

@@ -85,7 +85,7 @@ def verify_file3( self, file ) :
8585
self.assertEqual( 3, file.MF )
8686
self.assertEqual( 3, file.file_number )
8787

88-
self.assertEqual( [ 1, 2, 102 ], file.section_numbers )
88+
self.assertEqual( [ 1, 2, 102 ], file.section_numbers.to_list() )
8989
self.assertEqual( [ 1, 2, 102 ],
9090
[ section.MT for section in file.sections ] )
9191

@@ -109,7 +109,7 @@ def verify_file4( self, file ) :
109109
self.assertEqual( 4, file.MF )
110110
self.assertEqual( 4, file.file_number )
111111

112-
self.assertEqual( [ 2 ], file.section_numbers )
112+
self.assertEqual( [ 2 ], file.section_numbers.to_list() )
113113
self.assertEqual( [ 2 ],
114114
[ section.MT for section in file.sections ] )
115115

@@ -133,7 +133,7 @@ def verify_file6( self, file ) :
133133
self.assertEqual( 6, file.MF )
134134
self.assertEqual( 6, file.file_number )
135135

136-
self.assertEqual( [ 102 ], file.section_numbers )
136+
self.assertEqual( [ 102 ], file.section_numbers.to_list() )
137137
self.assertEqual( [ 102 ],
138138
[ section.MT for section in file.sections ] )
139139

@@ -157,7 +157,7 @@ def verify_file33( self, file ) :
157157
self.assertEqual( 33, file.MF )
158158
self.assertEqual( 33, file.file_number )
159159

160-
self.assertEqual( [ 1, 2, 102 ], file.section_numbers )
160+
self.assertEqual( [ 1, 2, 102 ], file.section_numbers.to_list() )
161161
self.assertEqual( [ 1, 2, 102 ],
162162
[ section.MT for section in file.sections ] )
163163

@@ -179,7 +179,7 @@ def verify_material( self, material ) :
179179
self.assertEqual( 125, material.MAT )
180180
self.assertEqual( 125, material.material_number )
181181

182-
self.assertEqual( [ 1, 2, 3, 4, 6, 33 ], material.file_numbers )
182+
self.assertEqual( [ 1, 2, 3, 4, 6, 33 ], material.file_numbers.to_list() )
183183
self.assertEqual( [ 1, 2, 3, 4, 6, 33 ],
184184
[ file.MF for file in material.files ] )
185185

@@ -289,44 +289,44 @@ def test_insert_replace_remove( self ) :
289289

290290
# remove a file from a material
291291
material.remove( 2 )
292-
self.assertEqual( [ 1, 3, 4, 6, 33 ], material.file_numbers )
293-
self.assertEqual( [ 1, 3, 4, 6, 33 ], tape.materials.front().file_numbers )
292+
self.assertEqual( [ 1, 3, 4, 6, 33 ], material.file_numbers.to_list() )
293+
self.assertEqual( [ 1, 3, 4, 6, 33 ], tape.materials.front().file_numbers.to_list() )
294294

295295
# remove a section from a material
296296
material.remove( 3, 2 )
297-
self.assertEqual( [ 1, 3, 4, 6, 33 ], material.file_numbers )
298-
self.assertEqual( [ 1, 102 ], file.section_numbers )
299-
self.assertEqual( [ 1, 3, 4, 6, 33 ], tape.materials.front().file_numbers )
300-
self.assertEqual( [ 1, 102 ], tape.materials.front().file(3).section_numbers )
297+
self.assertEqual( [ 1, 3, 4, 6, 33 ], material.file_numbers.to_list() )
298+
self.assertEqual( [ 1, 102 ], file.section_numbers.to_list() )
299+
self.assertEqual( [ 1, 3, 4, 6, 33 ], tape.materials.front().file_numbers.to_list() )
300+
self.assertEqual( [ 1, 102 ], tape.materials.front().file(3).section_numbers.to_list() )
301301

302302
# remove a section from a file
303303
file.remove( 102 )
304-
self.assertEqual( [ 1, 3, 4, 6, 33 ], material.file_numbers )
305-
self.assertEqual( [ 1 ], file.section_numbers )
306-
self.assertEqual( [ 1, 3, 4, 6, 33 ], tape.materials.front().file_numbers )
307-
self.assertEqual( [ 1 ], tape.materials.front().file(3).section_numbers )
304+
self.assertEqual( [ 1, 3, 4, 6, 33 ], material.file_numbers.to_list() )
305+
self.assertEqual( [ 1 ], file.section_numbers.to_list() )
306+
self.assertEqual( [ 1, 3, 4, 6, 33 ], tape.materials.front().file_numbers.to_list() )
307+
self.assertEqual( [ 1 ], tape.materials.front().file(3).section_numbers.to_list() )
308308

309309
# insert a section into a file
310310
data = copy.materials.front().file( 3 ).section( 102 )
311311
file.insert( data )
312-
self.assertEqual( [ 1, 3, 4, 6, 33 ], material.file_numbers )
313-
self.assertEqual( [ 1, 102 ], file.section_numbers )
314-
self.assertEqual( [ 1, 3, 4, 6, 33 ], tape.materials.front().file_numbers )
315-
self.assertEqual( [ 1, 102 ], tape.materials.front().file(3).section_numbers )
312+
self.assertEqual( [ 1, 3, 4, 6, 33 ], material.file_numbers.to_list() )
313+
self.assertEqual( [ 1, 102 ], file.section_numbers.to_list() )
314+
self.assertEqual( [ 1, 3, 4, 6, 33 ], tape.materials.front().file_numbers.to_list() )
315+
self.assertEqual( [ 1, 102 ], tape.materials.front().file(3).section_numbers.to_list() )
316316

317317
# insert a section into a material
318318
data = copy.materials.front().file( 3 ).section( 2 )
319319
file.insert( data )
320-
self.assertEqual( [ 1, 3, 4, 6, 33 ], material.file_numbers )
321-
self.assertEqual( [ 1, 2, 102 ], file.section_numbers )
322-
self.assertEqual( [ 1, 3, 4, 6, 33 ], tape.materials.front().file_numbers )
323-
self.assertEqual( [ 1, 2, 102 ], tape.materials.front().file(3).section_numbers )
320+
self.assertEqual( [ 1, 3, 4, 6, 33 ], material.file_numbers.to_list() )
321+
self.assertEqual( [ 1, 2, 102 ], file.section_numbers.to_list() )
322+
self.assertEqual( [ 1, 3, 4, 6, 33 ], tape.materials.front().file_numbers.to_list() )
323+
self.assertEqual( [ 1, 2, 102 ], tape.materials.front().file(3).section_numbers.to_list() )
324324

325325
# insert a file into a material
326326
data = copy.materials.front().file( 2 )
327327
material.insert( data )
328-
self.assertEqual( [ 1, 2, 3, 4, 6, 33 ], material.file_numbers )
329-
self.assertEqual( [ 1, 2, 3, 4, 6, 33 ], tape.materials.front().file_numbers )
328+
self.assertEqual( [ 1, 2, 3, 4, 6, 33 ], material.file_numbers.to_list() )
329+
self.assertEqual( [ 1, 2, 3, 4, 6, 33 ], tape.materials.front().file_numbers.to_list() )
330330

331331
def test_insert_replace_parsed_section( self ) :
332332

@@ -346,7 +346,7 @@ def test_insert_replace_parsed_section( self ) :
346346

347347
# insert a parsed section into a file
348348
file.insert( data )
349-
self.assertEqual( [ 1, 2, 102, 103 ], file.section_numbers )
349+
self.assertEqual( [ 1, 2, 102, 103 ], file.section_numbers.to_list() )
350350

351351
# the section was replaced correctly (testing some data)
352352
section = file.section( 103 ).parse()
@@ -366,7 +366,7 @@ def test_insert_replace_parsed_section( self ) :
366366

367367
# replacing a parsed section into a file
368368
file.insert_or_replace( data )
369-
self.assertEqual( [ 1, 2, 102, 103 ], file.section_numbers )
369+
self.assertEqual( [ 1, 2, 102, 103 ], file.section_numbers.to_list() )
370370

371371
# the section was replaced correctly (testing some data)
372372
section = file.section( 103 ).parse()

src/ENDFtk/Material.hpp

+18-31
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
#define NJOY_ENDFTK_MATERIAL
33

44
// system includes
5+
#include <list>
56
#include <variant>
67

78
// other includes
9+
#include "range/v3/view/all.hpp"
810
#include "ENDFtk/file/1.hpp"
911
#include "ENDFtk/file/2.hpp"
1012
#include "ENDFtk/file/3.hpp"
@@ -90,9 +92,10 @@ namespace ENDFtk {
9092

9193
/* fields */
9294
int mat_;
93-
std::map< int, FileVariant > files_;
95+
std::list< FileVariant > files_;
9496

9597
/* auxiliary functions */
98+
#include "ENDFtk/Material/src/find.hpp"
9699
#include "ENDFtk/Material/src/fill.hpp"
97100
#include "ENDFtk/Material/src/read.hpp"
98101
#include "ENDFtk/Material/src/verifyMEND.hpp"
@@ -117,34 +120,22 @@ namespace ENDFtk {
117120
/**
118121
* @brief Return the files stored in this material
119122
*/
120-
auto MFs() {
121-
122-
return this->files_ | ranges::cpp20::views::values;
123-
}
123+
auto MFs() { return this->files_ | ranges::cpp20::views::all; }
124124

125125
/**
126126
* @brief Return the files stored in this material
127127
*/
128-
auto files() {
129-
130-
return this->MFs();
131-
}
128+
auto files() { return this->MFs(); }
132129

133130
/**
134131
* @brief Return the files stored in this material
135132
*/
136-
auto MFs() const {
137-
138-
return this->files_ | ranges::cpp20::views::values;
139-
}
133+
auto MFs() const { return this->files_ | ranges::cpp20::views::all; }
140134

141135
/**
142136
* @brief Return the files stored in this material
143137
*/
144-
auto files() const {
145-
146-
return this->MFs();
147-
}
138+
auto files() const { return this->MFs(); }
148139

149140
/**
150141
* @brief Return an iterator to the start of the files
@@ -173,18 +164,15 @@ namespace ENDFtk {
173164
*/
174165
bool hasMF( int mf ) const {
175166

176-
return this->files_.count( mf );
167+
return this->find( mf ) != this->files_.end();
177168
}
178169

179170
/**
180171
* @brief Verify if a given file (defined by the MF number) is defined
181172
*
182173
* @param mf the MF number of the file to be verified
183174
*/
184-
bool hasFile( int mf ) const {
185-
186-
return this->hasMF( mf );
187-
}
175+
bool hasFile( int mf ) const { return this->hasMF( mf ); }
188176

189177
/**
190178
* @brief Return whether or not the material has a section with the given
@@ -218,18 +206,17 @@ namespace ENDFtk {
218206
*/
219207
const FileVariant& file( int mf ) const {
220208

221-
try {
209+
auto iter = this->find( mf );
210+
if ( iter != this->files_.end() ) {
222211

223-
return this->files_.at( mf );
212+
return *iter;
224213
}
225-
catch( std::out_of_range& o ) {
226214

227-
Log::error( "Requested file number (MF) does not"
228-
" correspond to a stored file" );
229-
Log::info( "Requested file number: {}", mf );
230-
Log::info( "Material queried: ", this->MAT() );
231-
throw o;
232-
}
215+
Log::error( "Requested file number (MF) does not"
216+
" correspond to a stored file" );
217+
Log::info( "Requested file number: {}", mf );
218+
Log::info( "Material queried: ", this->MAT() );
219+
throw std::exception();
233220
}
234221

235222
/**

src/ENDFtk/Material/src/fill.hpp

+16-8
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
11
static auto
22
fill( std::vector< FileVariant >&& files ) {
33

4-
std::map< int, FileVariant > map;
4+
std::list< FileVariant > list;
55
for ( auto&& file : files ) {
66

7-
int MF = std::visit( [] ( auto&& value ) { return value.MF(); }, file );
8-
if ( not map.emplace( MF, std::move( file ) ).second ) {
7+
auto getMF = [] ( auto&& value ) { return value.MF(); };
8+
int MF = std::visit( getMF, file );
9+
auto iter = std::lower_bound( list.begin(), list.end(), MF,
10+
[&getMF] ( auto&& left, auto&& right )
11+
{ return std::visit( getMF, left ) < right; } );
12+
if ( iter != list.end() ) {
913

10-
Log::error( "File with duplicate file number found" );
11-
Log::info( "Files are required to specify a unique MF or file number" );
12-
Log::info( "Encountered duplicate MF: {}", MF );
13-
throw std::exception();
14+
if ( std::visit( getMF, *iter ) == MF ) {
15+
16+
Log::error( "File with duplicate file number found" );
17+
Log::info( "Files are required to specify a unique MF or file number" );
18+
Log::info( "Encountered duplicate MF: {}", MF );
19+
throw std::exception();
20+
}
1421
}
22+
list.insert( iter, std::move( file ) );
1523
}
16-
return map;
24+
return list;
1725
}

src/ENDFtk/Material/src/find.hpp

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* @brief Return iterator to the file with the given mf number
3+
*
4+
* @param[in] mt the mf number
5+
*/
6+
auto find( int mf ) {
7+
8+
auto getMF = [] ( auto&& value ) { return value.MF(); };
9+
auto iter = std::lower_bound( this->files_.begin(), this->files_.end(), mf,
10+
[&getMF] ( auto&& left, auto&& right )
11+
{ return std::visit( getMF, left ) < right; } );
12+
13+
if ( iter != this->files_.end() ) {
14+
15+
if ( std::visit( getMF, *iter ) == mf ) {
16+
17+
return iter;
18+
}
19+
}
20+
return this->files_.end();
21+
}
22+
23+
/**
24+
* @brief Return iterator to the section with the given mf number
25+
*
26+
* @param[in] mf the mf number
27+
*/
28+
auto find( int mf ) const {
29+
30+
auto getMF = [] ( auto&& value ) { return value.MF(); };
31+
auto iter = std::lower_bound( this->files_.begin(), this->files_.end(), mf,
32+
[&getMF] ( auto&& left, auto&& right )
33+
{ return std::visit( getMF, left ) < right; } );
34+
35+
if ( iter != this->files_.end() ) {
36+
37+
if ( std::visit( getMF, *iter ) == mf ) {
38+
39+
return iter;
40+
}
41+
}
42+
return this->files_.end();
43+
}

src/ENDFtk/Material/src/print.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ void print( OutputIterator& it ) const {
1111
int MAT = this->MAT();
1212
for ( const auto& entry : this->files_ ) {
1313

14-
std::visit( [&] ( auto&& file ) { file.print( it, MAT ); }, entry.second );
14+
std::visit( [&] ( auto&& file ) { file.print( it, MAT ); }, entry );
1515
}
1616
MEND().print( it );
1717
}

0 commit comments

Comments
 (0)