Last active
August 29, 2015 14:27
-
-
Save ubnt-intrepid/4276d610a9d51b8cfe49 to your computer and use it in GitHub Desktop.
std::chrono::durationを使ったBoost.Unitsもどき
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1.21111 | |
121.111 | |
1.21111 | |
12 | |
12000 | |
0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <chrono> | |
#include <ratio> | |
namespace units { | |
template <typename T, typename Tag> | |
class tagged_value { | |
T value_ = 0; | |
public: | |
tagged_value() = default; | |
tagged_value(T val) | |
: value_(val) | |
{ | |
} | |
template <typename U> | |
tagged_value(tagged_value<U, Tag> const& other) | |
: value_(static_cast<T>(other.value_)) | |
{ | |
} | |
inline T value() const { return value_; } | |
}; | |
// called when converting to higher resulution | |
template <typename T1, typename T2, typename Tag> | |
inline auto operator*(tagged_value<T1, Tag> v1, tagged_value<T2, Tag> v2) | |
-> tagged_value<decltype(v1.value()*v2.value()), Tag> | |
{ | |
return tagged_value<decltype(v1.value()*v2.value()), Tag>(v1.value() * v2.value()); | |
} | |
// called when converting to lower resulution | |
template <typename T1, typename T2, typename Tag> | |
inline auto operator/(tagged_value<T1, Tag> v1, tagged_value<T2, Tag> v2) | |
-> tagged_value<decltype(v1.value()/v2.value()), Tag> | |
{ | |
return tagged_value<decltype(v1.value()/v2.value()), Tag>(v1.value() / v2.value()); | |
} | |
} // namespace units; | |
namespace std { namespace chrono { | |
template <typename T, typename Tag> | |
struct treat_as_floating_point<units::tagged_value<T, Tag>> | |
: std::is_floating_point<T> {}; | |
} } // namespace std::chrono; | |
namespace std { | |
template <typename T, typename Tag> | |
ostream& operator<<(ostream& os, units::tagged_value<T, Tag> val) { | |
return os << val.value(); | |
} | |
} // namespace std; | |
// tags: | |
struct Meter {}; | |
struct Watt {}; | |
int main(int argc, char const* argv[]) | |
{ | |
using namespace std; | |
using namespace std::chrono; | |
{ | |
// unit type definitions: | |
using meter_base_t = units::tagged_value<long double, Meter>; | |
using watt_base_t = units::tagged_value<long double, Watt>; | |
using meter_t = duration<meter_base_t, ratio<1>>; | |
using centimeter_t = duration<meter_base_t, centi>; | |
using watt_t = duration<watt_base_t, ratio<1>>; | |
meter_t meter(1.21111111); | |
cout << meter.count() << endl; | |
centimeter_t centimeter = meter; | |
cout << centimeter.count() << endl; | |
// watt_t watt = meter; // compile error! | |
meter_t meter2 = centimeter; | |
cout << meter2.count() << endl; | |
} | |
{ | |
using meter_base_t = units::tagged_value<long long, Meter>; | |
using kilometer_t = duration<meter_base_t, kilo>; | |
using meter_t = duration<meter_base_t, ratio<1>>; | |
using millimeter_t = duration<meter_base_t, milli>; | |
meter_t meter(12); | |
cout << meter.count() << endl; | |
millimeter_t millimeter = meter; | |
cout << millimeter.count() << endl; | |
kilometer_t kilometer = duration_cast<kilometer_t>(meter); | |
cout << kilometer.count() << endl; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment