24#include <unordered_map>
52 return (value * R::num) /
static_cast<double>(R::den);
65 return value * 0.3048;
78 return value * 3.28084;
130 using Key = std::pair<Unit, Unit>;
131 using Conversion = std::function<
double(
double)>;
138 std::size_t operator()(
const Key& key)
const noexcept
140 static_assert(
sizeof(
Unit) <
sizeof(std::size_t),
141 "sizeof(Length::Unit) changed, it must be less than "
142 "sizeof(std::size_t)");
144 int shift =
sizeof(
Unit) * 8;
145 return static_cast<std::size_t
>(key.first) << shift |
146 static_cast<std::size_t
>(key.second);
150 using ConversionTable = std::unordered_map<Key, Conversion, KeyHash>;
152 static ConversionTable CONVERSIONS{
153 {{Unit::Nanometer, Unit::Meter}, ScaleValue<std::nano>},
154 {{Unit::Meter, Unit::Nanometer}, ScaleValue<std::giga>},
155 {{Unit::Micrometer, Unit::Meter}, ScaleValue<std::micro>},
156 {{Unit::Meter, Unit::Micrometer}, ScaleValue<std::mega>},
157 {{Unit::Millimeter, Unit::Meter}, ScaleValue<std::milli>},
158 {{Unit::Meter, Unit::Millimeter}, ScaleValue<std::kilo>},
159 {{Unit::Centimeter, Unit::Meter}, ScaleValue<std::centi>},
160 {{Unit::Meter, Unit::Centimeter}, ScaleValue<std::hecto>},
161 {{Unit::Meter, Unit::Meter}, ScaleValue<std::ratio<1, 1>>},
162 {{Unit::Kilometer, Unit::Meter}, ScaleValue<std::kilo>},
163 {{Unit::Meter, Unit::Kilometer}, ScaleValue<std::milli>},
164 {{Unit::NauticalMile, Unit::Meter}, ScaleValue<std::ratio<1852, 1>>},
165 {{Unit::Meter, Unit::NauticalMile}, ScaleValue<std::ratio<1, 1852>>},
166 {{Unit::Inch, Unit::Meter}, USToMeter<std::ratio<1, 12>>},
167 {{Unit::Meter, Unit::Inch}, MeterToUS<std::ratio<12, 1>>},
170 {{Unit::Yard, Unit::Meter}, USToMeter<std::ratio<3, 1>>},
171 {{Unit::Meter, Unit::Yard}, MeterToUS<std::ratio<1, 3>>},
172 {{Unit::Mile, Unit::Meter}, USToMeter<std::ratio<5280, 1>>},
173 {{Unit::Meter, Unit::Mile}, MeterToUS<std::ratio<1, 5280>>},
176 auto iter = CONVERSIONS.find(Key{fromUnit, toUnit});
178 if (iter == CONVERSIONS.end())
180 NS_FATAL_ERROR(
"No conversion defined for " << fromUnit <<
" -> " << toUnit);
183 return iter->second(value);
218 return static_cast<std::size_t
>(u);
239 if (unit.has_value())
258 std::istringstream stream(
input);
270 if (!unit.has_value())
272 NS_FATAL_ERROR(
"A Length object could not be constructed from the unit "
275 <<
"', because the string is not associated "
276 "with a Length::Unit entry");
301 m_value = Convert(q, Length::Unit::Meter);
380 double value = Convert(
m_value, Length::Unit::Meter, unit);
388 return left.GetDouble() ==
right.GetDouble();
394 return left.GetDouble() !=
right.GetDouble();
400 return left.GetDouble() <
right.GetDouble();
406 return left.GetDouble() <=
right.GetDouble();
412 return left.GetDouble() >
right.GetDouble();
418 return left.GetDouble() >=
right.GetDouble();
464 return std::numeric_limits<double>::quiet_NaN();
475 if (std::isnan(
value))
486 return static_cast<int64_t
>(std::trunc(
value));
499 return Length(rem, Length::Unit::Meter);
505 using StringTable = std::unordered_map<Length::Unit, std::string, EnumHash>;
508 {Length::Unit::Nanometer,
"nm"},
509 {Length::Unit::Micrometer,
"um"},
510 {Length::Unit::Millimeter,
"mm"},
511 {Length::Unit::Centimeter,
"cm"},
512 {Length::Unit::Meter,
"m"},
513 {Length::Unit::Kilometer,
"km"},
514 {Length::Unit::NauticalMile,
"nmi"},
515 {Length::Unit::Inch,
"in"},
516 {Length::Unit::Foot,
"ft"},
517 {Length::Unit::Yard,
"yd"},
518 {Length::Unit::Mile,
"mi"},
525 NS_FATAL_ERROR(
"A symbol could not be found for Length::Unit with value "
526 << EnumHash()(unit));
535 using Entry = std::tuple<std::string, std::string>;
536 using StringTable = std::unordered_map<Length::Unit, Entry, EnumHash>;
539 {Length::Unit::Nanometer, Entry{
"nanometer",
"nanometers"}},
540 {Length::Unit::Micrometer, Entry{
"micrometer",
"micrometer"}},
541 {Length::Unit::Millimeter, Entry{
"millimeter",
"millimeters"}},
542 {Length::Unit::Centimeter, Entry{
"centimeter",
"centimeters"}},
543 {Length::Unit::Meter, Entry{
"meter",
"meters"}},
544 {Length::Unit::Kilometer, Entry{
"kilometer",
"kilometers"}},
545 {Length::Unit::NauticalMile, Entry{
"nautical mile",
"nautical miles"}},
546 {Length::Unit::Inch, Entry{
"inch",
"inches"}},
547 {Length::Unit::Foot, Entry{
"foot",
"feet"}},
548 {Length::Unit::Yard, Entry{
"yard",
"yards"}},
549 {Length::Unit::Mile, Entry{
"mile",
"miles"}},
556 NS_FATAL_ERROR(
"A symbol could not be found for Length::Unit with value "
557 << EnumHash()(unit));
562 return std::get<1>(
iter->second);
565 return std::get<0>(
iter->second);
568std::optional<Length::Unit>
571 using UnitTable = std::unordered_map<std::string, Length::Unit>;
574 {
"nm", Length::Unit::Nanometer},
575 {
"nanometer", Length::Unit::Nanometer},
576 {
"nanometers", Length::Unit::Nanometer},
577 {
"nanometre", Length::Unit::Nanometer},
578 {
"nanometres", Length::Unit::Nanometer},
579 {
"um", Length::Unit::Micrometer},
580 {
"micrometer", Length::Unit::Micrometer},
581 {
"micrometers", Length::Unit::Micrometer},
582 {
"micrometre", Length::Unit::Micrometer},
583 {
"micrometres", Length::Unit::Micrometer},
584 {
"mm", Length::Unit::Millimeter},
585 {
"millimeter", Length::Unit::Millimeter},
586 {
"millimeters", Length::Unit::Millimeter},
587 {
"millimetre", Length::Unit::Millimeter},
588 {
"millimetres", Length::Unit::Millimeter},
589 {
"cm", Length::Unit::Centimeter},
590 {
"centimeter", Length::Unit::Centimeter},
591 {
"centimeters", Length::Unit::Centimeter},
592 {
"centimetre", Length::Unit::Centimeter},
593 {
"centimetres", Length::Unit::Centimeter},
594 {
"m", Length::Unit::Meter},
595 {
"meter", Length::Unit::Meter},
596 {
"metre", Length::Unit::Meter},
597 {
"meters", Length::Unit::Meter},
598 {
"metres", Length::Unit::Meter},
599 {
"km", Length::Unit::Kilometer},
600 {
"kilometer", Length::Unit::Kilometer},
601 {
"kilometers", Length::Unit::Kilometer},
602 {
"kilometre", Length::Unit::Kilometer},
603 {
"kilometres", Length::Unit::Kilometer},
604 {
"nmi", Length::Unit::NauticalMile},
605 {
"nauticalmile", Length::Unit::NauticalMile},
606 {
"nauticalmiles", Length::Unit::NauticalMile},
607 {
"in", Length::Unit::Inch},
608 {
"inch", Length::Unit::Inch},
609 {
"inches", Length::Unit::Inch},
610 {
"ft", Length::Unit::Foot},
611 {
"foot", Length::Unit::Foot},
612 {
"feet", Length::Unit::Foot},
613 {
"yd", Length::Unit::Yard},
614 {
"yard", Length::Unit::Yard},
615 {
"yards", Length::Unit::Yard},
616 {
"mi", Length::Unit::Mile},
617 {
"mile", Length::Unit::Mile},
618 {
"miles", Length::Unit::Mile},
622 static auto Normalize = [](
const std::string& str) {
624 output.reserve(str.size());
626 for (
unsigned char c : str)
634 output.push_back(std::tolower(
c));
655 stream <<
l.As(Length::Unit::Meter);
692std::tuple<bool, double, std::string>
705 catch (
const std::exception& e)
707 NS_LOG_ERROR(
"Caught exception while parsing double: " << e.what());
709 return std::make_tuple(
false, 0,
"");
713 while (pos <
input.size() && std::isspace(
input[pos]))
718 if (pos <
input.size())
720 NS_LOG_LOGIC(
"String has value and symbol, extracting symbol");
732 bool success =
false;
746 if (success &&
symbol.empty())
748 NS_LOG_LOGIC(
"Temp string only contained value, extracting unit symbol from stream");
Functor for hashing Length::Unit values.
std::size_t operator()(ns3::Length::Unit u) const noexcept
Produce a hash value for a Length::Unit.
An immutable class which represents a value in a specific length unit.
double Value() const
The value of the quantity.
Length::Unit Unit() const
The unit of the quantity.
Represents a length in meters.
void swap(Length &other)
Swap values with another object.
bool IsGreaterOrEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is equal or less in value than this instance.
double GetDouble() const
Current length value.
Length & operator=(const Length &other)=default
Copy Assignment operator.
bool IsGreater(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is less in value than this instance.
double m_value
Length in meters.
bool IsEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is equal in value to this instance.
Quantity As(Unit unit) const
Create a Quantity in a specific unit from a Length.
bool IsLessOrEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is greater or equal in value than this instance.
static std::optional< Length > TryParse(double value, const std::string &unit)
Attempt to construct a Length object from a value and a unit string.
Unit
Units of length in various measurement systems that are supported by the Length class.
Length()
Default Constructor.
bool IsLess(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is greater in value than this instance.
bool IsNotEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is not equal in value to this instance.
double GetDouble() const
Get this value as a double.
#define ATTRIBUTE_HELPER_CPP(type)
Define the attribute value, accessor and checkers for class type
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
int64x64_t operator/(const int64x64_t &lhs, const int64x64_t &rhs)
Division operator.
bool operator>=(const int64x64_t &lhs, const int64x64_t &rhs)
Greater or equal operator.
bool operator<=(const int64x64_t &lhs, const int64x64_t &rhs)
Less or equal operator.
int64x64_t operator-(const int64x64_t &lhs, const int64x64_t &rhs)
Subtraction operator.
int64x64_t operator+(const int64x64_t &lhs, const int64x64_t &rhs)
Addition operator.
int64x64_t operator*(const int64x64_t &lhs, const int64x64_t &rhs)
Multiplication operator.
Length KiloMeters(double value)
Construct a length from a value in the indicated unit.
Length MilliMeters(double value)
Construct a length from a value in the indicated unit.
Length NauticalMiles(double value)
Construct a length from a value in the indicated unit.
std::string ToName(Length::Unit unit, bool plural)
Return the name of the supplied unit.
bool operator>(const Length &left, const Length &right)
Check if left has a value greater than right.
Length Yards(double value)
Construct a length from a value in the indicated unit.
Length Feet(double value)
Construct a length from a value in the indicated unit.
Length Mod(const Length &numerator, const Length &denominator)
Calculate the amount remaining after dividing two lengths.
Length MicroMeters(double value)
Construct a length from a value in the indicated unit.
Length Miles(double value)
Construct a length from a value in the indicated unit.
Length Meters(double value)
Construct a length from a value in the indicated unit.
std::string ToSymbol(Length::Unit unit)
Return the symbol of the supplied unit.
Length CentiMeters(double value)
Construct a length from a value in the indicated unit.
int64_t Div(const Length &numerator, const Length &denominator, Length *remainder)
Calculate how many times numerator can be split into denominator sized pieces.
Length NanoMeters(double value)
Construct a length from a value in the indicated unit.
Length Inches(double value)
Construct a length from a value in the indicated unit.
std::optional< Length::Unit > FromString(std::string unitString)
Find the equivalent Length::Unit for a unit string.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Length::Unit Unit
Save some typing by defining a short alias for Length::Unit.
Declaration of ns3::Length class.
double USToMeter(double value)
Convert a value from a US Customary unit (inches, feet, yards etc.) to meters.
double MeterToFoot(double value)
Convert a value in meters to the equivalent value in feet.
double Convert(double value, ns3::Length::Unit fromUnit, ns3::Length::Unit toUnit)
Convert a value in one unit to the equivalent value in another unit.
double MeterToUS(double value)
Convert a value from meters to a US Customary unit (inches, feet, yards etc.)
double FootToMeter(double value)
Convert a value in feet to the equivalent value in meters.
double ScaleValue(double value)
Helper function to scale an input value by a given ratio.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool operator!=(Callback< R, Args... > a, Callback< R, Args... > b)
Inequality test.
bool operator==(const EventId &a, const EventId &b)
std::ostream & operator<<(std::ostream &os, const Angles &a)
static unsigned int value(char c)
std::istream & operator>>(std::istream &is, Angles &a)
bool operator<(const EventId &a, const EventId &b)
std::tuple< bool, double, std::string > ParseLengthString(const std::string &input)
This function provides a string parsing method that does not rely on istream, which has been found to...
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression, cppcoreguidelines-noexcept-swap, performance-noexcept-swap) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects