Skip to content

Commit

Permalink
Defer regex construction to avoid static initialization
Browse files Browse the repository at this point in the history
Signed-off-by: Jeremy Nimmer <[email protected]>
  • Loading branch information
jwnimmer-tri committed Nov 24, 2021
1 parent 797f67f commit d0f8632
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 27 deletions.
3 changes: 3 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
1. Evict large function definitions from the Helpers.hh header file.
* [Pull request 288](https://github.com/ignitionrobotics/ign-math/pull/288)

1. Defer regex construction to avoid static initialization.
* [Pull request 289](https://github.com/ignitionrobotics/ign-math/pull/289)

## Ignition Math 6.x

### Ignition Math 6.x.x
Expand Down
55 changes: 28 additions & 27 deletions src/Helpers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,39 +76,40 @@ namespace ignition
return outputString.str();
}

// The following regex takes a time string in the general format of
// "dd hh:mm:ss.nnn" where n is milliseconds, if just one number is
// provided, it is assumed to be seconds
static const std::regex time_regex(
"^([0-9]+ ){0,1}" // day:
// Any positive integer

"(?:([1-9]:|[0-1][0-9]:|2[0-3]:){0,1}" // hour:
// 1 - 9:
// 01 - 19:
// 20 - 23:

"([0-9]:|[0-5][0-9]:)){0,1}" // minute:
// 0 - 9:
// 00 - 59:

"(?:([0-9]|[0-5][0-9]){0,1}" // second:
// 0 - 9
// 00 - 59

"(\\.[0-9]{1,3}){0,1})$"); // millisecond:
// .0 - .9
// .00 - .99
// .000 - 0.999


/////////////////////////////////////////////
bool splitTimeBasedOnTimeRegex(
const std::string &_timeString,
uint64_t & numberDays, uint64_t & numberHours,
uint64_t & numberMinutes, uint64_t & numberSeconds,
uint64_t & numberMilliseconds)
{
// The following regex takes a time string in the general format of
// "dd hh:mm:ss.nnn" where n is milliseconds, if just one number is
// provided, it is assumed to be seconds. We construct upon first use
// and never destroy it, in order to avoid the [Static Initialization
// Order Fiasco](https://en.cppreference.com/w/cpp/language/siof).
static const std::regex * const kTimeRegex = new std::regex(
"^([0-9]+ ){0,1}" // day:
// Any positive integer

"(?:([1-9]:|[0-1][0-9]:|2[0-3]:){0,1}" // hour:
// 1 - 9:
// 01 - 19:
// 20 - 23:

"([0-9]:|[0-5][0-9]:)){0,1}" // minute:
// 0 - 9:
// 00 - 59:

"(?:([0-9]|[0-5][0-9]){0,1}" // second:
// 0 - 9
// 00 - 59

"(\\.[0-9]{1,3}){0,1})$"); // millisecond:
// .0 - .9
// .00 - .99
// .000 - 0.999

std::smatch matches;

// `matches` should always be a size of 6 as there are 6 matching
Expand All @@ -123,7 +124,7 @@ namespace ignition
// Note that the space will remain in the day match, the colon
// will remain in the hour and minute matches, and the period will
// remain in the millisecond match
if (!std::regex_search(_timeString, matches, time_regex) ||
if (!std::regex_search(_timeString, matches, *kTimeRegex) ||
matches.size() != 6)
return false;

Expand Down

0 comments on commit d0f8632

Please sign in to comment.