Terse conversion from double seconds to std::chrono::steady_clock::duration? - c++

I can do this:
double period_in_seconds = 3.4;
auto as_duration = std::chrono::duration_cast<std::chrono::steady_clock::duration>(std::chrono::duration<double>(period_in_seconds));
But I'm sure you'll agree that is quite ridiculous. Is there a terser way?
Edit: Beside the obvious using namespace std::chrono.

There is good reason to be fanatic about discouraging use of using namespaces at file scope, especially in headers. However at function scope, especially with the <chrono> lib, using namespace std::chrono is your friend.
Just this step gets you from:
double period_in_seconds = 3.4;
auto as_duration = std::chrono::duration_cast<std::chrono::steady_clock::duration>(std::chrono::duration<double>(period_in_seconds));
to:
double period_in_seconds = 3.4;
using namespace std::chrono;
auto as_duration = duration_cast<steady_clock::duration>(duration<double>(period_in_seconds));
I recommend the use of round when casting from a floating point duration to an integral duration. Not only will this give the "expected" answer more often, but it is slightly less verbose than duration_cast. std::chrono::round is new with C++17. But you can grab it from various places like here or here and start using it today. Also if you use {} for constructors it helps distinguish object construction from function calls, making the code a little easier to read:
double period_in_seconds = 3.4;
using namespace std::chrono;
auto as_duration = round<steady_clock::duration>(duration<double>{period_in_seconds});
Finally, don't hesitate to create a custom duration, even if in a local scope to improve readability:
double period_in_seconds = 3.4;
using namespace std::chrono;
using dsec = duration<double>;
auto as_duration = round<steady_clock::duration>(dsec{period_in_seconds});
Edit: And if for some reason (say a misplaced style guide) you can't using a function-local using namespace std::chrono, then you can make up for that with more specific type aliases and using declarations:
double period_in_seconds = 3.4;
using dsec = std::chrono::duration<double>;
using duration = std::chrono::steady_clock::duration;
using std::chrono::round;
auto as_duration = round<duration>(dsec{period_in_seconds});
If this code is intended to be at file scope and you don't want these usings at file scope (which is perfectly understandable), just create a function to encapsulate them:
constexpr
std::chrono::steady_clock::duration
get_period(double period_in_seconds)
{
using dsec = std::chrono::duration<double>;
using duration = std::chrono::steady_clock::duration;
using std::chrono::round;
return round<duration>(dsec{period_in_seconds});
}
auto constexpr as_duration = get_period(3.4);
Above I've even demonstrated that this particular example can all be done at compile time. clang -O3 -S reduces the above down to the following assembly:
.globl _as_duration ## #as_duration
.p2align 3
_as_duration:
.quad 3400000000 ## 0xcaa7e200

Related

Idiomatic way to check std::chrono duration is less than 0

I know I can do this
if (timeLeft.count() < 0)
But I wonder what is the best way since I could also do:
if (timeLeft<std::chrono::seconds(0)) // or milliseconds or nanonseconds...
note: I assume both checks are the same, but I am not a chrono expert.
edit:full example:
#include<chrono>
int main(){
const std::chrono::nanoseconds timeLeft(-5);
if(timeLeft<std::chrono::seconds(0)){
return 47;
}
}
edit2: potential problem with std::chrono::seconds(0) is that novice programmer might assume it involves rounding although it does not.
One of the ways to express this is by using std::chrono::duration literals (https://en.cppreference.com/w/cpp/chrono/duration). It's short and clean:
#include<chrono>
int main(){
using namespace std::chrono_literals;
const auto timeLeft = -5ns;
if(timeLeft<0s){
return 47;
}
}

using constexpr double in namespaces

I'm currently getting into more C++11 stuff and jumped about constexpr. In one of my books it's said that you should use it for constants like π for example in this way:
#include <cmath>
// (...)
constexpr double PI = atan(1) * 4;
Now I wanted to put that in an own namespace, eg. MathC:
// config.h
#include <cmath>
namespace MathC {
constexpr double PI = atan(1) * 4;
// further declarations here
}
...but here IntelliSense says function call must have a constant value in a constant expression.
When I declare PI the following way, it works:
static const double PI = atan(1) * 4;
What is the actual reason the compiler doesn't seem to like constexpr but static const here? Shouldn't constexpr be eligible here, too, or is it all about the context here and constexprshouldn't be declared outside of functions?
Thank you.
What is the actual reason the compiler doesn't seem to like constexpr but static const here?
A constexpr must be evaluatable at compile time while static const does not need to be.
static const double PI = atan(1) * 4;
simply tells the compiler that PI may not be modified once it is initialized but it may be initialized at run time.

How to Make Generic Precision ISO Timestamp Generator

I am writing a utility function that returns the current time in ISO format. However, I would like to be able to specify the precision:
2017-04-28T15:07:37Z //s
2017-04-28T15:07:37.035Z //ms
2017-04-28T15:07:37.035332Z //us
I have working code to do this, however, I can't seem to find a way to make it generic:
string getISOCurrentTimestamp_us()
{
char iso_buf[30];
auto now = chrono::high_resolution_clock::now();
auto s = chrono::duration_cast<chrono::seconds>(now.time_since_epoch());
time_t seconds = (time_t) s.count();
strftime(iso_buf, sizeof(iso_buf), "%FT%T", gmtime(&seconds));
string iso_timestamp(iso_buf);
auto us = chrono::duration_cast<chrono::microseconds>(now.time_since_epoch());
auto us_diff = us - chrono::duration_cast<chrono::microseconds>(s);
char buffer[8];
std::snprintf(buffer, sizeof(buffer), ".%06d", (int) us_diff.count());
iso_timestamp += string(buffer);
iso_timestamp += "Z";
return iso_timestamp;
}
As you can see, this one only returns the microsecond version. I have a separate function using chrono:milliseconds for the millisecond version. Seems like a DRY violation to have so much similar code when the only difference is the duration template parameter and the zero-padding.
Yet being able to specify the duration is tricky. I think I'm not quite understanding function templates, because I tried something like getISOCurrentTimestamp<chrono::microseconds>(), to no avail:
template <class T>
string getISOCurrentTimestamp() {
...
auto t = chrono::duration_cast<T>(now.time_since_epoch());
auto t_diff = t - chrono::duration_cast<T>(s);
}
Another problem is deducing the amount of zero padding based on T which doesn't seem trivial either (i.e. microseconds should be zero-padded up to 6, milliseconds up to 3, etc.
How can I make this ISO String function generic? Am I approaching this the wrong way?
Edit: Using #HowardHinnant's library, I was able to write a generic wrapper:
template <class Precision>
string getISOCurrentTimestamp()
{
auto now = chrono::system_clock::now();
return date::format("%FT%TZ", date::floor<Precision>(now));
}
Invoked using:
string timestamp = getISOCurrentTimestamp<chrono::seconds>()
This free, open-source, header-only library does this by adjusting the precision of the chrono::time_point that is input into the format function. Feel free to inspect the code to see how this is done. I think you'll be especially interested in decimal_format_seconds which is responsible for computing how many fractional decimal digits to output (if any). Or feel free to just use this code.
Here is what using it looks like:
#include "date.h"
#include <iostream>
int
main()
{
using namespace std;
using namespace std::chrono;
using namespace date;
system_clock::time_point now = sys_days{2017_y/04/28} + 15h + 7min + 37s + 35332us;
cout << format("%FT%TZ\n", floor<seconds>(now));
cout << format("%FT%TZ\n", floor<milliseconds>(now));
cout << format("%FT%TZ\n", floor<microseconds>(now));
}
with the output:
2017-04-28T15:07:37Z
2017-04-28T15:07:37.035Z
2017-04-28T15:07:37.035332Z

What is the best way to define a double constant in a namespace?

What is the best way to define a double constant in a namespace? For example
// constant.h
namespace constant {
static const double PI = 3.1415926535;
}
// No need in constant.cpp
Is this the best way?
I'd say:
-- In c++14:
namespace constant
{
template <typename T = double>
constexpr T PI = T(3.1415926535897932385);
}
-- In c++11:
namespace constant
{
constexpr double PI = 3.1415926535897932385;
}
-- In c++03 :
namespace constant
{
static const double PI = 3.1415926535897932385;
}
Note that if your constant does not have a trivial type and you are within a shared library, i would advise to avoid giving it internal linkage at global/namespace scope, i don't know the theory about this but in practice it does tend to randomly mess things up :)

Physical Boost.Units User Defined Literals

Now that we soon have user defined literals (UDL), in GCC 4.7 for example, I'm eagerly waiting for (physical) unit libraries (such as Boost.Units) using them to ease expression of literals such as 1+3i, 3m, 3meter or 13_meter. Has anybody written an extension to Boost.Units using UDL supporting this behaviour?
No one has come out with such an extension. Only gcc (and possibly IBM?) has UDL so it might be a while. I'm hoping some kind of units makes it into tr2 which is starting about now. If that happens I'm sure UDL for units will come up.
This works:
// ./bin/bin/g++ -std=c++0x -o units4 units4.cpp
#include <boost/units/unit.hpp>
#include <boost/units/quantity.hpp>
#include <boost/units/systems/si.hpp>
using namespace boost::units;
using namespace boost::units::si;
quantity<length, long double>
operator"" _m(long double x)
{ return x * meters; }
quantity<si::time, long double>
operator"" _s(long double x)
{ return x * seconds; }
int
main()
{
auto l = 66.6_m;
auto v = 2.5_m / 6.6_s;
std::cout << "l = " << l << std::endl;
std::cout << "v = " << v << std::endl;
}
I think it wouldn't be too hard to go through you favorite units and do this.
Concerning putting these in a library:
The literal operators are namespace scope functions. The competition for suffixes is going to get ugly. I would (if I were boost) have
namespace literals
{
...
}
Then Boost users can do
using boost::units::literals;
along with all the other using decls you typically use. Then you won't get clobbered by std::tr2::units for example. Similarly if you roll your own.
In my opinion there is not much gain in using literals for Boost.Units, because a more powerful syntax can still be achieved with existing capabilities.
In simple cases, looks like literals is the way to go, but soon you see that it is not very powerful.
For example, you still have to define literals for combined units, for example, how do you express 1 m/s (one meter per second)?
Currently:
auto v = 1*si::meter/si::second; // yes, it is long
but with literals?
// fake code
using namespace boost::units::literals;
auto v = 1._m_over_s; // or 1._m/si::second; or 1._m/1_s // even worst
A better solution can be achieved with existing features. And this is what I do:
namespace boost{namespace units{namespace si{ //excuse me!
namespace abbreviations{
static const length m = si::meter;
static const time s = si::second;
// ...
}
}}} // thank you!
using namespace si::abbreviations;
auto v = 1.*m/s;
In the same way you can do: auto a = 1.*m/pow<2>(s); or extend the abbreviations more if you want (e.g. static const area m2 = pow<2>(si::meter);)
What else beyond this do you want?
Maybe a combined solution could be the way
auto v = 1._m/s; // _m is literal, /s is from si::abbreviation combined with operator/
but there will be so much redundant code and the gain is minimal (replace * by _ after the number.)
One drawback of my solution is that it polutes the namespace with common one letter names. But I don't see a way around that except to add an underscore (to the beginning or the end of the abbreviation), as in 1.*m_/s_ but at least I can build real units expressions.