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