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