A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
length.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019 Lawrence Livermore National Laboratory
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathew Bielejeski <bielejeski1@llnl.gov>
7 */
8
9#include "length.h"
10
11#include "log.h"
12
13#include <algorithm>
14#include <cctype>
15#include <cmath>
16#include <functional>
17#include <limits>
18#include <ratio>
19#include <sstream>
20#include <string>
21#include <unordered_map>
22
23/**
24 * @file
25 * @ingroup length
26 * ns3::Length implementation
27 */
28
29/**
30 * @ingroup length
31 * Unnamed namespace
32 */
33namespace
34{
35/**
36 * Helper function to scale an input value by a given ratio
37 *
38 * @tparam R a std::ratio
39 *
40 * @param value Input value to scale by R
41 *
42 * @return The result of value * R::num / R::den
43 */
44template <class R>
45double
46ScaleValue(double value)
47{
48 return (value * R::num) / static_cast<double>(R::den);
49}
50
51/**
52 * Convert a value in feet to the equivalent value in meters
53 *
54 * @param value Input value in feet
55 *
56 * @return Equivalent value in meters
57 */
58double
59FootToMeter(double value)
60{
61 return value * 0.3048;
62}
63
64/**
65 * Convert a value in meters to the equivalent value in feet
66 *
67 * @param value Input value in meters
68 *
69 * @return Equivalent value in feet
70 */
71double
72MeterToFoot(double value)
73{
74 return value * 3.28084;
75}
76
77/**
78 * Convert a value from a US Customary unit (inches, feet, yards etc.) to meters
79 *
80 * Value is scaled to feet then converted to meters
81 *
82 * @tparam R std::ratio needed to convert value to feet
83 *
84 * @param value Input value in some US Customary unit
85 *
86 * @return Equivalent value in meters
87 */
88template <class R>
89double
90USToMeter(double value)
91{
92 return FootToMeter(ScaleValue<R>(value));
93}
94
95/**
96 * Convert a value from meters to a US Customary unit (inches, feet, yards etc.)
97 *
98 * Value is converted to feet then scaled to the desired US Customary unit
99 *
100 * @tparam R std::ratio needed to convert feet to desired US customary unit
101 *
102 * @param value Input value in meters
103 *
104 * @return Equivalent value in a US customary unit
105 */
106template <class R>
107double
108MeterToUS(double value)
109{
110 return ScaleValue<R>(MeterToFoot(value));
111}
112
113/**
114 * Convert a value in one unit to the equivalent value in another unit
115 *
116 * @param value Length value in \p fromUnit units
117 * @param fromUnit Unit of \p value
118 * @param toUnit Target unit
119 *
120 * @return Result of converting value from \p fromUnit to \p toUnit
121 */
122double
123Convert(double value, ns3::Length::Unit fromUnit, ns3::Length::Unit toUnit)
124{
125 using Unit = ns3::Length::Unit;
126 using Key = std::pair<Unit, Unit>;
127 using Conversion = std::function<double(double)>;
128
129 /**
130 * Helper to generate hash values from pairs of Length::Units
131 */
132 struct KeyHash
133 {
134 std::size_t operator()(const Key& key) const noexcept
135 {
136 static_assert(sizeof(Unit) < sizeof(std::size_t),
137 "sizeof(Length::Unit) changed, it must be less than "
138 "sizeof(std::size_t)");
139
140 int shift = sizeof(Unit) * 8;
141 return static_cast<std::size_t>(key.first) << shift |
142 static_cast<std::size_t>(key.second);
143 }
144 };
145
146 using ConversionTable = std::unordered_map<Key, Conversion, KeyHash>;
147
148 static ConversionTable CONVERSIONS{
149 {{Unit::Nanometer, Unit::Meter}, ScaleValue<std::nano>},
150 {{Unit::Meter, Unit::Nanometer}, ScaleValue<std::giga>},
151 {{Unit::Micrometer, Unit::Meter}, ScaleValue<std::micro>},
152 {{Unit::Meter, Unit::Micrometer}, ScaleValue<std::mega>},
153 {{Unit::Millimeter, Unit::Meter}, ScaleValue<std::milli>},
154 {{Unit::Meter, Unit::Millimeter}, ScaleValue<std::kilo>},
155 {{Unit::Centimeter, Unit::Meter}, ScaleValue<std::centi>},
156 {{Unit::Meter, Unit::Centimeter}, ScaleValue<std::hecto>},
157 {{Unit::Meter, Unit::Meter}, ScaleValue<std::ratio<1, 1>>},
158 {{Unit::Kilometer, Unit::Meter}, ScaleValue<std::kilo>},
159 {{Unit::Meter, Unit::Kilometer}, ScaleValue<std::milli>},
160 {{Unit::NauticalMile, Unit::Meter}, ScaleValue<std::ratio<1852, 1>>},
161 {{Unit::Meter, Unit::NauticalMile}, ScaleValue<std::ratio<1, 1852>>},
162 {{Unit::Inch, Unit::Meter}, USToMeter<std::ratio<1, 12>>},
163 {{Unit::Meter, Unit::Inch}, MeterToUS<std::ratio<12, 1>>},
164 {{Unit::Foot, Unit::Meter}, FootToMeter},
165 {{Unit::Meter, Unit::Foot}, MeterToFoot},
166 {{Unit::Yard, Unit::Meter}, USToMeter<std::ratio<3, 1>>},
167 {{Unit::Meter, Unit::Yard}, MeterToUS<std::ratio<1, 3>>},
168 {{Unit::Mile, Unit::Meter}, USToMeter<std::ratio<5280, 1>>},
169 {{Unit::Meter, Unit::Mile}, MeterToUS<std::ratio<1, 5280>>},
170 };
171
172 auto iter = CONVERSIONS.find(Key{fromUnit, toUnit});
173
174 if (iter == CONVERSIONS.end())
175 {
176 NS_FATAL_ERROR("No conversion defined for " << fromUnit << " -> " << toUnit);
177 }
178
179 return iter->second(value);
180}
181
182/**
183 * Convert a Length::Quantity to the equivalent value in another unit
184 *
185 * @param from Quantity with the current value and unit
186 * @param toUnit Target unit
187 *
188 * @return Result of converting the quantity value to the requested units
189 */
190double
192{
193 return Convert(from.Value(), from.Unit(), toUnit);
194}
195
196/**
197 * Functor for hashing Length::Unit values
198 *
199 * This classes exists as a work around for a C++11 defect. c++11 doesn't provide
200 * a std::hash implementation for enums
201 */
203{
204 public:
205 /**
206 * Produce a hash value for a Length::Unit
207 *
208 * @param u Length::Unit to hash
209 *
210 * @return Hash value for the Length::Unit
211 */
212 std::size_t operator()(ns3::Length::Unit u) const noexcept
213 {
214 return static_cast<std::size_t>(u);
215 }
216};
217
218} // unnamed namespace
219
220namespace ns3
221{
222
224
225// Implement the attribute helper
227
228std::optional<Length>
229Length::TryParse(double value, const std::string& unitString)
230{
231 NS_LOG_FUNCTION(value << unitString);
232
233 auto unit = FromString(unitString);
234
235 if (unit.has_value())
236 {
237 return Length(value, *unit);
238 }
239
240 return std::nullopt;
241}
242
244 : m_value(0)
245{
246 NS_LOG_FUNCTION(this);
247}
248
249Length::Length(const std::string& input)
250 : m_value(0)
251{
252 NS_LOG_FUNCTION(this << input);
253
254 std::istringstream stream(input);
255
256 stream >> *this;
257}
258
259Length::Length(double value, const std::string& unitString)
260 : m_value(0)
261{
262 NS_LOG_FUNCTION(this << value << unitString);
263
264 auto unit = FromString(unitString);
265
266 if (!unit.has_value())
267 {
268 NS_FATAL_ERROR("A Length object could not be constructed from the unit "
269 "string '"
270 << unitString
271 << "', because the string is not associated "
272 "with a Length::Unit entry");
273 }
274
275 m_value = Convert(value, *unit, Length::Unit::Meter);
276}
277
278Length::Length(double value, Length::Unit unit)
279 : m_value(0)
280{
281 NS_LOG_FUNCTION(this << value << unit);
282
283 m_value = Convert(value, unit, Length::Unit::Meter);
284}
285
287 : Length(quantity.Value(), quantity.Unit())
288{
289 NS_LOG_FUNCTION(this << quantity);
290}
291
292Length&
294{
295 NS_LOG_FUNCTION(this << q);
296
297 m_value = Convert(q, Length::Unit::Meter);
298
299 return *this;
300}
301
302bool
303Length::IsEqual(const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
304{
305 NS_LOG_FUNCTION(this << m_value << other.m_value << tolerance);
306
307 if (m_value == other.m_value)
308 {
309 return true;
310 }
311
312 auto diff = std::abs(m_value - other.m_value);
313
314 return diff <= tolerance;
315}
316
317bool
318Length::IsNotEqual(const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
319{
320 NS_LOG_FUNCTION(this << m_value << other.m_value << tolerance);
321
322 return !IsEqual(other, tolerance);
323}
324
325bool
326Length::IsLess(const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
327{
328 NS_LOG_FUNCTION(this << m_value << other.m_value << tolerance);
329
330 return m_value < other.m_value && IsNotEqual(other, tolerance);
331}
332
333bool
334Length::IsLessOrEqual(const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
335{
336 NS_LOG_FUNCTION(this << m_value << other.m_value << tolerance);
337
338 return m_value < other.m_value || IsEqual(other, tolerance);
339}
340
341bool
342Length::IsGreater(const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
343{
344 NS_LOG_FUNCTION(this << m_value << other.m_value << tolerance);
345
346 return !IsLessOrEqual(other, tolerance);
347}
348
349bool
350Length::IsGreaterOrEqual(const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
351{
352 NS_LOG_FUNCTION(this << m_value << other.m_value << tolerance);
353
354 return !IsLess(other, tolerance);
355}
356
357void
359{
360 using std::swap;
361
362 swap(m_value, other.m_value);
363}
364
365double
367{
368 return m_value;
369}
370
373{
374 NS_LOG_FUNCTION(this << unit);
375
376 double value = Convert(m_value, Length::Unit::Meter, unit);
377
378 return Quantity(value, unit);
379}
380
381bool
382operator==(const Length& left, const Length& right)
383{
384 return left.GetDouble() == right.GetDouble();
385}
386
387bool
388operator!=(const Length& left, const Length& right)
389{
390 return left.GetDouble() != right.GetDouble();
391}
392
393bool
394operator<(const Length& left, const Length& right)
395{
396 return left.GetDouble() < right.GetDouble();
397}
398
399bool
400operator<=(const Length& left, const Length& right)
401{
402 return left.GetDouble() <= right.GetDouble();
403}
404
405bool
406operator>(const Length& left, const Length& right)
407{
408 return left.GetDouble() > right.GetDouble();
409}
410
411bool
412operator>=(const Length& left, const Length& right)
413{
414 return left.GetDouble() >= right.GetDouble();
415}
416
417Length
418operator+(const Length& left, const Length& right)
419{
420 double value = left.GetDouble() + right.GetDouble();
421 return Length(value, Length::Unit::Meter);
422}
423
424Length
425operator-(const Length& left, const Length& right)
426{
427 double value = left.GetDouble() - right.GetDouble();
428 return Length(value, Length::Unit::Meter);
429}
430
431Length
432operator*(const Length& left, double scalar)
433{
434 double value = left.GetDouble() * scalar;
435 return Length(value, Length::Unit::Meter);
436}
437
438Length
439operator*(double scalar, const Length& right)
440{
441 return right * scalar;
442}
443
444Length
445operator/(const Length& left, double scalar)
446{
447 if (scalar == 0)
448 {
449 NS_FATAL_ERROR("Attempted to divide Length by 0");
450 }
451
452 return left * (1.0 / scalar);
453}
454
455double
456operator/(const Length& numerator, const Length& denominator)
457{
458 if (denominator.GetDouble() == 0)
459 {
460 return std::numeric_limits<double>::quiet_NaN();
461 }
462
463 return numerator.GetDouble() / denominator.GetDouble();
464}
465
466int64_t
467Div(const Length& numerator, const Length& denominator, Length* remainder)
468{
469 double value = numerator / denominator;
470
471 if (std::isnan(value))
472 {
473 NS_FATAL_ERROR("numerator / denominator return NaN");
474 }
475
476 if (remainder)
477 {
478 double rem = std::fmod(numerator.GetDouble(), denominator.GetDouble());
479 *remainder = Length(rem, Length::Unit::Meter);
480 }
481
482 return static_cast<int64_t>(std::trunc(value));
483}
484
485Length
486Mod(const Length& numerator, const Length& denominator)
487{
488 double rem = std::fmod(numerator.GetDouble(), denominator.GetDouble());
489
490 if (std::isnan(rem))
491 {
492 NS_FATAL_ERROR("numerator / denominator return NaN");
493 }
494
495 return Length(rem, Length::Unit::Meter);
496}
497
498std::string
500{
501 using StringTable = std::unordered_map<Length::Unit, std::string, EnumHash>;
502
503 static const StringTable STRINGS{
504 {Length::Unit::Nanometer, "nm"},
505 {Length::Unit::Micrometer, "um"},
506 {Length::Unit::Millimeter, "mm"},
507 {Length::Unit::Centimeter, "cm"},
508 {Length::Unit::Meter, "m"},
509 {Length::Unit::Kilometer, "km"},
510 {Length::Unit::NauticalMile, "nmi"},
511 {Length::Unit::Inch, "in"},
512 {Length::Unit::Foot, "ft"},
513 {Length::Unit::Yard, "yd"},
514 {Length::Unit::Mile, "mi"},
515 };
516
517 auto iter = STRINGS.find(unit);
518
519 if (iter == STRINGS.end())
520 {
521 NS_FATAL_ERROR("A symbol could not be found for Length::Unit with value "
522 << EnumHash()(unit));
523 }
524
525 return iter->second;
526}
527
528std::string
529ToName(Length::Unit unit, bool plural /*=false*/)
530{
531 using Entry = std::tuple<std::string, std::string>;
532 using StringTable = std::unordered_map<Length::Unit, Entry, EnumHash>;
533
534 static const StringTable STRINGS{
535 {Length::Unit::Nanometer, Entry{"nanometer", "nanometers"}},
536 {Length::Unit::Micrometer, Entry{"micrometer", "micrometer"}},
537 {Length::Unit::Millimeter, Entry{"millimeter", "millimeters"}},
538 {Length::Unit::Centimeter, Entry{"centimeter", "centimeters"}},
539 {Length::Unit::Meter, Entry{"meter", "meters"}},
540 {Length::Unit::Kilometer, Entry{"kilometer", "kilometers"}},
541 {Length::Unit::NauticalMile, Entry{"nautical mile", "nautical miles"}},
542 {Length::Unit::Inch, Entry{"inch", "inches"}},
543 {Length::Unit::Foot, Entry{"foot", "feet"}},
544 {Length::Unit::Yard, Entry{"yard", "yards"}},
545 {Length::Unit::Mile, Entry{"mile", "miles"}},
546 };
547
548 auto iter = STRINGS.find(unit);
549
550 if (iter == STRINGS.end())
551 {
552 NS_FATAL_ERROR("A symbol could not be found for Length::Unit with value "
553 << EnumHash()(unit));
554 }
555
556 if (plural)
557 {
558 return std::get<1>(iter->second);
559 }
560
561 return std::get<0>(iter->second);
562}
563
564std::optional<Length::Unit>
565FromString(std::string unitString)
566{
567 using UnitTable = std::unordered_map<std::string, Length::Unit>;
568
569 static const UnitTable UNITS{
570 {"nm", Length::Unit::Nanometer},
571 {"nanometer", Length::Unit::Nanometer},
572 {"nanometers", Length::Unit::Nanometer},
573 {"nanometre", Length::Unit::Nanometer},
574 {"nanometres", Length::Unit::Nanometer},
575 {"um", Length::Unit::Micrometer},
576 {"micrometer", Length::Unit::Micrometer},
577 {"micrometers", Length::Unit::Micrometer},
578 {"micrometre", Length::Unit::Micrometer},
579 {"micrometres", Length::Unit::Micrometer},
580 {"mm", Length::Unit::Millimeter},
581 {"millimeter", Length::Unit::Millimeter},
582 {"millimeters", Length::Unit::Millimeter},
583 {"millimetre", Length::Unit::Millimeter},
584 {"millimetres", Length::Unit::Millimeter},
585 {"cm", Length::Unit::Centimeter},
586 {"centimeter", Length::Unit::Centimeter},
587 {"centimeters", Length::Unit::Centimeter},
588 {"centimetre", Length::Unit::Centimeter},
589 {"centimetres", Length::Unit::Centimeter},
590 {"m", Length::Unit::Meter},
591 {"meter", Length::Unit::Meter},
592 {"metre", Length::Unit::Meter},
593 {"meters", Length::Unit::Meter},
594 {"metres", Length::Unit::Meter},
595 {"km", Length::Unit::Kilometer},
596 {"kilometer", Length::Unit::Kilometer},
597 {"kilometers", Length::Unit::Kilometer},
598 {"kilometre", Length::Unit::Kilometer},
599 {"kilometres", Length::Unit::Kilometer},
600 {"nmi", Length::Unit::NauticalMile},
601 {"nauticalmile", Length::Unit::NauticalMile},
602 {"nauticalmiles", Length::Unit::NauticalMile},
603 {"in", Length::Unit::Inch},
604 {"inch", Length::Unit::Inch},
605 {"inches", Length::Unit::Inch},
606 {"ft", Length::Unit::Foot},
607 {"foot", Length::Unit::Foot},
608 {"feet", Length::Unit::Foot},
609 {"yd", Length::Unit::Yard},
610 {"yard", Length::Unit::Yard},
611 {"yards", Length::Unit::Yard},
612 {"mi", Length::Unit::Mile},
613 {"mile", Length::Unit::Mile},
614 {"miles", Length::Unit::Mile},
615 };
616
617 // function to trim whitespace and convert to lowercase in one pass
618 static auto Normalize = [](const std::string& str) {
619 std::string output;
620 output.reserve(str.size());
621
622 for (unsigned char c : str)
623 {
624 // this strips all spaces not just beg/end but is fine for our purposes
625 if (std::isspace(c))
626 {
627 continue;
628 }
629
630 output.push_back(std::tolower(c));
631 }
632
633 return output;
634 };
635
636 unitString = Normalize(unitString);
637
638 auto iter = UNITS.find(unitString);
639
640 if (iter != UNITS.end())
641 {
642 return iter->second;
643 }
644
645 return std::nullopt;
646}
647
648std::ostream&
649operator<<(std::ostream& stream, const Length& l)
650{
651 stream << l.As(Length::Unit::Meter);
652
653 return stream;
654}
655
656std::ostream&
657operator<<(std::ostream& stream, const Length::Quantity& q)
658{
659 stream << q.Value() << ' ' << ToSymbol(q.Unit());
660
661 return stream;
662}
663
664std::ostream&
665operator<<(std::ostream& stream, Length::Unit unit)
666{
667 stream << ToName(unit);
668
669 return stream;
670}
671
672/**
673 * This function provides a string parsing method that does not rely
674 * on istream, which has been found to have different behaviors in different
675 * implementations.
676 *
677 * The input string can either contain a double (for example, "5.5") or
678 * a double and a string with no space between them (for example, "5.5m")
679 *
680 * @param input The input string
681 * @return A three element tuple containing the result of parsing the string.
682 * The first tuple element is a boolean indicating whether the parsing succeeded
683 * or failed. The second element contains the value of the double that was
684 * extracted from the string. The third element was the unit symbol that was
685 * extracted from the string. If the input string did not have a unit symbol,
686 * the third element will contain an empty string.
687 */
688std::tuple<bool, double, std::string>
689ParseLengthString(const std::string& input)
690{
691 NS_LOG_FUNCTION(input);
692
693 double value = 0;
694 std::size_t pos = 0;
695 std::string symbol;
696
697 try
698 {
699 value = std::stod(input, &pos);
700 }
701 catch (const std::exception& e)
702 {
703 NS_LOG_ERROR("Caught exception while parsing double: " << e.what());
704
705 return std::make_tuple(false, 0, "");
706 }
707
708 // skip any whitespace between value and symbol
709 while (pos < input.size() && std::isspace(input[pos]))
710 {
711 ++pos;
712 }
713
714 if (pos < input.size())
715 {
716 NS_LOG_LOGIC("String has value and symbol, extracting symbol");
717
718 // input has a double followed by a string
719 symbol = input.substr(pos);
720 }
721
722 return std::make_tuple(true, value, symbol);
723}
724
725std::istream&
726operator>>(std::istream& stream, Length& l)
727{
728 bool success = false;
729 double value = 0;
730 std::string symbol;
731 std::string temp;
732
733 // configure stream to skip whitespace in case it was disabled
734 auto origFlags = stream.flags();
735 std::skipws(stream);
736
737 // Read the contents into a temporary string and parse it manually
738 stream >> temp;
739
740 std::tie(success, value, symbol) = ParseLengthString(temp);
741
742 if (success && symbol.empty())
743 {
744 NS_LOG_LOGIC("Temp string only contained value, extracting unit symbol from stream");
745
746 // temp only contained the double
747 // still need to read the symbol from the stream
748 stream >> symbol;
749 }
750
751 // special handling for nautical mile which is two words
752 if (symbol == "nautical")
753 {
754 stream >> temp;
755
756 if (!temp.empty())
757 {
758 symbol.push_back(' ');
759 symbol.append(temp);
760 }
761 }
762
763 Length(value, symbol).swap(l);
764
765 // restore original flags
766 stream.flags(origFlags);
767
768 return stream;
769}
770
771Length
772NanoMeters(double value)
773{
774 return Length(value, Length::Unit::Nanometer);
775}
776
777Length
778MicroMeters(double value)
779{
780 return Length(value, Length::Unit::Micrometer);
781}
782
783Length
784MilliMeters(double value)
785{
786 return Length(value, Length::Unit::Millimeter);
787}
788
789Length
790CentiMeters(double value)
791{
792 return Length(value, Length::Unit::Centimeter);
793}
794
795Length
796Meters(double value)
797{
798 return Length(value, Length::Unit::Meter);
799}
800
801Length
802KiloMeters(double value)
803{
804 return Length(value, Length::Unit::Kilometer);
805}
806
807Length
808NauticalMiles(double value)
809{
810 return Length(value, Length::Unit::NauticalMile);
811}
812
813Length
814Inches(double value)
815{
816 return Length(value, Length::Unit::Inch);
817}
818
819Length
820Feet(double value)
821{
822 return Length(value, Length::Unit::Foot);
823}
824
825Length
826Yards(double value)
827{
828 return Length(value, Length::Unit::Yard);
829}
830
831Length
832Miles(double value)
833{
834 return Length(value, Length::Unit::Mile);
835}
836
837} // namespace ns3
result rem
uint32_t q
uint32_t u
cairo_uint64_t remainder
Functor for hashing Length::Unit values.
Definition length.cc:203
std::size_t operator()(ns3::Length::Unit u) const noexcept
Produce a hash value for a Length::Unit.
Definition length.cc:212
An immutable class which represents a value in a specific length unit.
Definition length.h:261
double Value() const
The value of the quantity.
Definition length.h:309
Length::Unit Unit() const
The unit of the quantity.
Definition length.h:319
Represents a length in meters.
Definition length.h:233
void swap(Length &other)
Swap values with another object.
Definition length.cc:358
bool IsGreaterOrEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is equal or less in value than this instance.
Definition length.cc:350
double GetDouble() const
Current length value.
Definition length.cc:366
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.
Definition length.cc:342
double m_value
Length in meters.
Definition length.h:609
bool IsEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is equal in value to this instance.
Definition length.cc:303
Quantity As(Unit unit) const
Create a Quantity in a specific unit from a Length.
Definition length.cc:372
bool IsLessOrEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is greater or equal in value than this instance.
Definition length.cc:334
static std::optional< Length > TryParse(double value, const std::string &unit)
Attempt to construct a Length object from a value and a unit string.
Definition length.cc:229
Unit
Units of length in various measurement systems that are supported by the Length class.
Definition length.h:240
Length()
Default Constructor.
Definition length.cc:243
bool IsLess(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is greater in value than this instance.
Definition length.cc:326
bool IsNotEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is not equal in value to this instance.
Definition length.cc:318
#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.
Definition int64x64.h:121
bool operator>=(const int64x64_t &lhs, const int64x64_t &rhs)
Greater or equal operator.
Definition int64x64.h:162
bool operator<=(const int64x64_t &lhs, const int64x64_t &rhs)
Less or equal operator.
Definition int64x64.h:149
int64x64_t operator-(const int64x64_t &lhs, const int64x64_t &rhs)
Subtraction operator.
Definition int64x64.h:91
int64x64_t operator+(const int64x64_t &lhs, const int64x64_t &rhs)
Addition operator.
Definition int64x64.h:76
int64x64_t operator*(const int64x64_t &lhs, const int64x64_t &rhs)
Multiplication operator.
Definition int64x64.h:106
Length KiloMeters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:802
Length MilliMeters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:784
Length NauticalMiles(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:808
std::string ToName(Length::Unit unit, bool plural)
Return the name of the supplied unit.
Definition length.cc:529
bool operator>(const Length &left, const Length &right)
Check if left has a value greater than right.
Definition length.cc:406
Length Yards(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:826
Length Feet(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:820
Length Mod(const Length &numerator, const Length &denominator)
Calculate the amount remaining after dividing two lengths.
Definition length.cc:486
Length MicroMeters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:778
Length Miles(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:832
Length Meters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:796
std::string ToSymbol(Length::Unit unit)
Return the symbol of the supplied unit.
Definition length.cc:499
Length CentiMeters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:790
int64_t Div(const Length &numerator, const Length &denominator, Length *remainder)
Calculate how many times numerator can be split into denominator sized pieces.
Definition length.cc:467
Length NanoMeters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:772
Length Inches(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:814
std::optional< Length::Unit > FromString(std::string unitString)
Find the equivalent Length::Unit for a unit string.
Definition length.cc:565
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:246
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:274
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Length::Unit Unit
Save some typing by defining a short alias for Length::Unit.
Declaration of ns3::Length class.
Debug message logging.
double USToMeter(double value)
Convert a value from a US Customary unit (inches, feet, yards etc.) to meters.
Definition length.cc:90
double MeterToFoot(double value)
Convert a value in meters to the equivalent value in feet.
Definition length.cc:72
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.
Definition length.cc:123
double MeterToUS(double value)
Convert a value from meters to a US Customary unit (inches, feet, yards etc.).
Definition length.cc:108
double FootToMeter(double value)
Convert a value in feet to the equivalent value in meters.
Definition length.cc:59
double ScaleValue(double value)
Helper function to scale an input value by a given ratio.
Definition length.cc:46
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.
Definition callback.h:664
bool operator==(const EventId &a, const EventId &b)
Definition event-id.h:146
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
std::istream & operator>>(std::istream &is, Angles &a)
Definition angles.cc:172
bool operator<(const EventId &a, const EventId &b)
Definition event-id.h:159
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...
Definition length.cc:689