Skip to content

Commit af4f1cb

Browse files
committed
Merge branch 'fix/compile-with-msvc' into 'develop'
Fixes for Windows compilation See merge request njoy/tools!22
2 parents 07c6d7a + a62879a commit af4f1cb

File tree

8 files changed

+59
-8
lines changed

8 files changed

+59
-8
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,7 @@ dependencies
4141
# python
4242
__pycache__
4343
*.pyc
44+
45+
# visual studio
46+
.vs/
47+
.vscode/

CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,13 @@ if(tools.installation)
137137
include(CPack)
138138
endif()
139139
endif()
140+
141+
########################################################################
142+
# Windows-specific setup
143+
########################################################################
144+
145+
# enable Edit and Continue in Visual Studio (for debugging)
146+
if(MSVC)
147+
target_compile_options(${PROJECT_NAME} INTERFACE "/ZI")
148+
target_link_options(${PROJECT_NAME} INTERFACE "/INCREMENTAL")
149+
endif()

src/tools/disco/FreeFormatInteger.hpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,29 @@ class FreeFormatInteger : public BaseField {
3838

3939
Representation value = 0;
4040

41+
// copy the start before find_if modifies iter
42+
auto start = iter;
43+
4144
iter = std::find_if( iter, end,
4245
[] ( auto&& value )
4346
{ return ! std::isspace( value ); } );
4447

48+
// if the value is not in the string, find_if returns the end of the range, in
49+
// which case msvc will not allow dereferencing iter. So, throw a runtime
50+
// error here in that case:
51+
if ( iter == end ) {
52+
53+
std::string message( &*start, &*std::prev( end ) + 1 );
54+
message.insert( 0, "Could not read valid integer: \"" );
55+
message += '\"';
56+
throw std::runtime_error( message );
57+
}
58+
4559
// we are using fast_float::from_chars instead of std::from_chars since
4660
// not all standard c++ libraries implement the floating point version of
4761
// std::from_chars
4862
if ( *iter == '+' ) { ++iter; }
49-
auto result = fast_float::from_chars( &*iter, &*end, value );
63+
auto result = fast_float::from_chars( &*iter, &*std::prev( end ) + 1, value );
5064
if ( result.ec == std::errc() ) {
5165

5266
auto advance = result.ptr - &*iter;

src/tools/disco/FreeFormatReal.hpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,31 @@ class FreeFormatReal : public BaseField {
3838

3939
Representation value = 0;
4040

41+
// copy the start before find_if modifies iter
42+
auto start = iter;
43+
4144
iter = std::find_if( iter, end,
4245
[] ( auto&& value )
4346
{ return ! std::isspace( value ); } );
4447

48+
// if the value is not in the string, find_if returns the end of the range, in
49+
// which case msvc will not allow dereferencing iter. So, throw a runtime
50+
// error here in that case:
51+
if ( iter == end ) {
52+
53+
std::string message( &*start, &*std::prev( end ) + 1 );
54+
message.insert( 0, "Could not read valid real value: " );
55+
message += '\"';
56+
throw std::runtime_error( message );
57+
}
58+
4559
// we are using fast_float::from_chars_advanced instead of std::from_chars
4660
// since not all standard c++ libraries implement the floating point version
4761
// of std::from_chars and because this allows us to read fortran formatted
4862
// floats
4963
if ( *iter == '+' ) { ++iter; }
5064
fast_float::parse_options options{ fast_float::chars_format::fortran };
51-
auto result = fast_float::from_chars_advanced( &*iter, &*end, value, options );
65+
auto result = fast_float::from_chars_advanced( &*iter, &*std::prev( end ) + 1, value, options );
5266
if ( result.ec == std::errc() ) {
5367

5468
auto advance = result.ptr - &*iter;

src/tools/disco/Integer.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,16 @@ class Integer : public BaseFixedWidthField< Width > {
4444
static Representation read( Iterator& iter, const Iterator& end ) {
4545

4646
unsigned int position = 0;
47+
48+
// this will fail for msvc if the string length is
49+
// less than the stated width
4750
const auto final = iter + Width;
51+
4852
Representation value = 0;
4953

5054
skipSpaces( iter, position );
51-
if ( isNewLine( iter ) || Width == position || iter >= end ) {
55+
56+
if ( iter >= end || isNewLine( iter ) || Width == position ) {
5257

5358
return value;
5459
}
@@ -62,7 +67,7 @@ class Integer : public BaseFixedWidthField< Width > {
6267
// we are using fast_float::from_chars instead of std::from_chars since
6368
// not all standard c++ libraries implement the floating point version of
6469
// std::from_chars
65-
auto result = fast_float::from_chars( &*iter, &*final, value );
70+
auto result = fast_float::from_chars( &*iter, &*std::prev( final ) + 1, value );
6671
if ( result.ec == std::errc() ) {
6772

6873
auto advance = result.ptr - &*iter;

src/tools/disco/Integer/test/Integer.test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ SCENARIO( "Integer" ) {
7979
CHECK( -123 == Integer< 10 >::read< int >( begin, end ) );
8080
CHECK( begin == end );
8181

82-
string = " +123\n";
82+
string = " +123\n";
8383
begin = string.begin();
8484
end = string.end();
8585
CHECK( 123 == Integer< 10 >::read< int >( begin, end ) );

src/tools/disco/Real.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,15 @@ class Real : public BaseFixedWidthField< Width > {
3636
static Representation read( Iterator& iter, const Iterator& end ) {
3737

3838
unsigned int position = 0;
39+
40+
// this will fail for msvc if the string length is
41+
// less than the stated width
3942
const auto final = iter + Width;
43+
4044
Representation value = 0.0;
4145

4246
skipSpaces( iter, position );
43-
if ( isNewLine( iter ) || Width == position || iter >= end ) {
47+
if ( iter >= end || isNewLine( iter ) || Width == position ) {
4448

4549
return value;
4650
}
@@ -56,7 +60,7 @@ class Real : public BaseFixedWidthField< Width > {
5660
// of std::from_chars and because this allows us to read fortran formatted
5761
// floats
5862
fast_float::parse_options options{ fast_float::chars_format::fortran };
59-
auto result = fast_float::from_chars_advanced( &*iter, &*final, value, options );
63+
auto result = fast_float::from_chars_advanced( &*iter, &*std::prev( final ) + 1, value, options );
6064
if ( result.ec == std::errc() ) {
6165

6266
auto advance = result.ptr - &*iter;

src/tools/disco/Real/test/Real.test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ SCENARIO( "Real" ) {
213213
CHECK_THAT( 100, WithinRel( Real< 10 >::read< double >( begin, end ) ) );
214214
CHECK( begin == end );
215215

216-
string = " +123\n";
216+
string = " +123\n";
217217
begin = string.begin();
218218
end = string.end();
219219
CHECK_THAT( 123, WithinRel( Real< 10 >::read< double >( begin, end ) ) );

0 commit comments

Comments
 (0)