A Discrete-Event Network Simulator
API
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 "ns3/length.h"
21
22#include "ns3/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
48namespace
49{
59template <class R>
60double
62{
63 return (value * R::num) / static_cast<double>(R::den);
64}
65
73double
75{
76 return value * 0.3048;
77}
78
86double
88{
89 return value * 3.28084;
90}
91
103template <class R>
104double
106{
107 return FootToMeter(ScaleValue<R>(value));
108}
109
121template <class R>
122double
124{
125 return ScaleValue<R>(MeterToFoot(value));
126}
127
137double
139{
140 using Unit = ns3::Length::Unit;
141 using Key = std::pair<Unit, Unit>;
142 using Conversion = std::function<double(double)>;
143
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 auto iter = CONVERSIONS.find(Key{fromUnit, toUnit});
187
188 if (iter == CONVERSIONS.end())
189 {
190 NS_FATAL_ERROR("No conversion defined for " << fromUnit << " -> " << toUnit);
191 }
192
193 return iter->second(value);
194}
195
204double
206{
207 return Convert(from.Value(), from.Unit(), toUnit);
208}
209
217{
218 public:
226 std::size_t operator()(ns3::Length::Unit u) const noexcept
227 {
228 return static_cast<std::size_t>(u);
229 }
230};
231
232} // unnamed namespace
233
234namespace ns3
235{
236
238
239// Implement the attribute helper
241
242std::optional<Length>
243Length::TryParse(double value, const std::string& unitString)
244{
245 NS_LOG_FUNCTION(value << unitString);
246
247 auto unit = FromString(unitString);
248
249 if (unit.has_value())
250 {
251 return Length(value, *unit);
252 }
253
254 return std::nullopt;
255}
256
258 : m_value(0)
259{
260 NS_LOG_FUNCTION(this);
261}
262
263Length::Length(const std::string& input)
264 : m_value(0)
265{
266 NS_LOG_FUNCTION(this << input);
267
268 std::istringstream stream(input);
269
270 stream >> *this;
271}
272
273Length::Length(double value, const std::string& unitString)
274 : m_value(0)
275{
276 NS_LOG_FUNCTION(this << value << unitString);
277
278 auto unit = FromString(unitString);
279
280 if (!unit.has_value())
281 {
282 NS_FATAL_ERROR("A Length object could not be constructed from the unit "
283 "string '"
284 << unitString
285 << "', because the string is not associated "
286 "with a Length::Unit entry");
287 }
288
289 m_value = Convert(value, *unit, Length::Unit::Meter);
290}
291
293 : m_value(0)
294{
295 NS_LOG_FUNCTION(this << value << unit);
296
297 m_value = Convert(value, unit, Length::Unit::Meter);
298}
299
301 : Length(quantity.Value(), quantity.Unit())
302{
303 NS_LOG_FUNCTION(this << quantity);
304}
305
306Length&
308{
309 NS_LOG_FUNCTION(this << q);
310
311 m_value = Convert(q, Length::Unit::Meter);
312
313 return *this;
314}
315
316bool
317Length::IsEqual(const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
318{
319 NS_LOG_FUNCTION(this << m_value << other.m_value << tolerance);
320
321 if (m_value == other.m_value)
322 {
323 return true;
324 }
325
326 auto diff = std::abs(m_value - other.m_value);
327
328 return diff <= tolerance;
329}
330
331bool
332Length::IsNotEqual(const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
333{
334 NS_LOG_FUNCTION(this << m_value << other.m_value << tolerance);
335
336 return !IsEqual(other, tolerance);
337}
338
339bool
340Length::IsLess(const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
341{
342 NS_LOG_FUNCTION(this << m_value << other.m_value << tolerance);
343
344 return m_value < other.m_value && IsNotEqual(other, tolerance);
345}
346
347bool
348Length::IsLessOrEqual(const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
349{
350 NS_LOG_FUNCTION(this << m_value << other.m_value << tolerance);
351
352 return m_value < other.m_value || IsEqual(other, tolerance);
353}
354
355bool
356Length::IsGreater(const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
357{
358 NS_LOG_FUNCTION(this << m_value << other.m_value << tolerance);
359
360 return !IsLessOrEqual(other, tolerance);
361}
362
363bool
364Length::IsGreaterOrEqual(const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
365{
366 NS_LOG_FUNCTION(this << m_value << other.m_value << tolerance);
367
368 return !IsLess(other, tolerance);
369}
370
371void
373{
374 using std::swap;
375
376 swap(m_value, other.m_value);
377}
378
379double
381{
382 return m_value;
383}
384
387{
388 NS_LOG_FUNCTION(this << unit);
389
390 double value = Convert(m_value, Length::Unit::Meter, unit);
391
392 return Quantity(value, unit);
393}
394
395bool
396operator==(const Length& left, const Length& right)
397{
398 return left.GetDouble() == right.GetDouble();
399}
400
401bool
402operator!=(const Length& left, const Length& right)
403{
404 return left.GetDouble() != right.GetDouble();
405}
406
407bool
408operator<(const Length& left, const Length& right)
409{
410 return left.GetDouble() < right.GetDouble();
411}
412
413bool
414operator<=(const Length& left, const Length& right)
415{
416 return left.GetDouble() <= right.GetDouble();
417}
418
419bool
420operator>(const Length& left, const Length& right)
421{
422 return left.GetDouble() > right.GetDouble();
423}
424
425bool
426operator>=(const Length& left, const Length& right)
427{
428 return left.GetDouble() >= right.GetDouble();
429}
430
431Length
432operator+(const Length& left, const Length& right)
433{
434 double value = left.GetDouble() + right.GetDouble();
435 return Length(value, Length::Unit::Meter);
436}
437
438Length
439operator-(const Length& left, const Length& right)
440{
441 double value = left.GetDouble() - right.GetDouble();
442 return Length(value, Length::Unit::Meter);
443}
444
445Length
446operator*(const Length& left, double scalar)
447{
448 double value = left.GetDouble() * scalar;
449 return Length(value, Length::Unit::Meter);
450}
451
452Length
453operator*(double scalar, const Length& right)
454{
455 return right * scalar;
456}
457
458Length
459operator/(const Length& left, double scalar)
460{
461 if (scalar == 0)
462 {
463 NS_FATAL_ERROR("Attempted to divide Length by 0");
464 }
465
466 return left * (1.0 / scalar);
467}
468
469double
470operator/(const Length& numerator, const Length& denominator)
471{
472 if (denominator.GetDouble() == 0)
473 {
474 return std::numeric_limits<double>::quiet_NaN();
475 }
476
477 return numerator.GetDouble() / denominator.GetDouble();
478}
479
480int64_t
481Div(const Length& numerator, const Length& denominator, Length* remainder)
482{
483 double value = numerator / denominator;
484
485 if (std::isnan(value))
486 {
487 NS_FATAL_ERROR("numerator / denominator return NaN");
488 }
489
490 if (remainder)
491 {
492 double rem = std::fmod(numerator.GetDouble(), denominator.GetDouble());
493 *remainder = Length(rem, Length::Unit::Meter);
494 }
495
496 return static_cast<int64_t>(std::trunc(value));
497}
498
499Length
500Mod(const Length& numerator, const Length& denominator)
501{
502 double rem = std::fmod(numerator.GetDouble(), denominator.GetDouble());
503
504 if (std::isnan(rem))
505 {
506 NS_FATAL_ERROR("numerator / denominator return NaN");
507 }
508
509 return Length(rem, Length::Unit::Meter);
510}
511
512std::string
514{
515 using StringTable = std::unordered_map<Length::Unit, std::string, EnumHash>;
516
517 static const StringTable STRINGS{{Length::Unit::Nanometer, "nm"},
518 {Length::Unit::Micrometer, "um"},
519 {Length::Unit::Millimeter, "mm"},
520 {Length::Unit::Centimeter, "cm"},
521 {Length::Unit::Meter, "m"},
522 {Length::Unit::Kilometer, "km"},
523 {Length::Unit::NauticalMile, "nmi"},
524 {Length::Unit::Inch, "in"},
525 {Length::Unit::Foot, "ft"},
526 {Length::Unit::Yard, "yd"},
527 {Length::Unit::Mile, "mi"}};
528
529 auto iter = STRINGS.find(unit);
530
531 if (iter == STRINGS.end())
532 {
533 NS_FATAL_ERROR("A symbol could not be found for Length::Unit with value "
534 << EnumHash()(unit));
535 }
536
537 return iter->second;
538}
539
540std::string
541ToName(Length::Unit unit, bool plural /*=false*/)
542{
543 using Entry = std::tuple<std::string, std::string>;
544 using StringTable = std::unordered_map<Length::Unit, Entry, EnumHash>;
545
546 static const StringTable STRINGS{
547 {Length::Unit::Nanometer, Entry{"nanometer", "nanometers"}},
548 {Length::Unit::Micrometer, Entry{"micrometer", "micrometer"}},
549 {Length::Unit::Millimeter, Entry{"millimeter", "millimeters"}},
550 {Length::Unit::Centimeter, Entry{"centimeter", "centimeters"}},
551 {Length::Unit::Meter, Entry{"meter", "meters"}},
552 {Length::Unit::Kilometer, Entry{"kilometer", "kilometers"}},
553 {Length::Unit::NauticalMile, Entry{"nautical mile", "nautical miles"}},
554 {Length::Unit::Inch, Entry{"inch", "inches"}},
555 {Length::Unit::Foot, Entry{"foot", "feet"}},
556 {Length::Unit::Yard, Entry{"yard", "yards"}},
557 {Length::Unit::Mile, Entry{"mile", "miles"}}};
558
559 auto iter = STRINGS.find(unit);
560
561 if (iter == STRINGS.end())
562 {
563 NS_FATAL_ERROR("A symbol could not be found for Length::Unit with value "
564 << EnumHash()(unit));
565 }
566
567 if (plural)
568 {
569 return std::get<1>(iter->second);
570 }
571
572 return std::get<0>(iter->second);
573}
574
575std::optional<Length::Unit>
576FromString(std::string unitString)
577{
578 using UnitTable = std::unordered_map<std::string, Length::Unit>;
579
580 static const UnitTable UNITS{{"nm", Length::Unit::Nanometer},
581 {"nanometer", Length::Unit::Nanometer},
582 {"nanometers", Length::Unit::Nanometer},
583 {"nanometre", Length::Unit::Nanometer},
584 {"nanometres", Length::Unit::Nanometer},
585 {"um", Length::Unit::Micrometer},
586 {"micrometer", Length::Unit::Micrometer},
587 {"micrometers", Length::Unit::Micrometer},
588 {"micrometre", Length::Unit::Micrometer},
589 {"micrometres", Length::Unit::Micrometer},
590 {"mm", Length::Unit::Millimeter},
591 {"millimeter", Length::Unit::Millimeter},
592 {"millimeters", Length::Unit::Millimeter},
593 {"millimetre", Length::Unit::Millimeter},
594 {"millimetres", Length::Unit::Millimeter},
595 {"cm", Length::Unit::Centimeter},
596 {"centimeter", Length::Unit::Centimeter},
597 {"centimeters", Length::Unit::Centimeter},
598 {"centimetre", Length::Unit::Centimeter},
599 {"centimetres", Length::Unit::Centimeter},
600 {"m", Length::Unit::Meter},
601 {"meter", Length::Unit::Meter},
602 {"metre", Length::Unit::Meter},
603 {"meters", Length::Unit::Meter},
604 {"metres", Length::Unit::Meter},
605 {"km", Length::Unit::Kilometer},
606 {"kilometer", Length::Unit::Kilometer},
607 {"kilometers", Length::Unit::Kilometer},
608 {"kilometre", Length::Unit::Kilometer},
609 {"kilometres", Length::Unit::Kilometer},
610 {"nmi", Length::Unit::NauticalMile},
611 {"nauticalmile", Length::Unit::NauticalMile},
612 {"nauticalmiles", Length::Unit::NauticalMile},
613 {"in", Length::Unit::Inch},
614 {"inch", Length::Unit::Inch},
615 {"inches", Length::Unit::Inch},
616 {"ft", Length::Unit::Foot},
617 {"foot", Length::Unit::Foot},
618 {"feet", Length::Unit::Foot},
619 {"yd", Length::Unit::Yard},
620 {"yard", Length::Unit::Yard},
621 {"yards", Length::Unit::Yard},
622 {"mi", Length::Unit::Mile},
623 {"mile", Length::Unit::Mile},
624 {"miles", Length::Unit::Mile}};
625
626 // function to trim whitespace and convert to lowercase in one pass
627 static auto Normalize = [](const std::string& str) {
628 std::string output;
629 output.reserve(str.size());
630
631 for (unsigned char c : str)
632 {
633 // this strips all spaces not just beg/end but is fine for our purposes
634 if (std::isspace(c))
635 {
636 continue;
637 }
638
639 output.push_back(std::tolower(c));
640 }
641
642 return output;
643 };
644
645 unitString = Normalize(unitString);
646
647 auto iter = UNITS.find(unitString);
648
649 if (iter != UNITS.end())
650 {
651 return iter->second;
652 }
653
654 return std::nullopt;
655}
656
657std::ostream&
658operator<<(std::ostream& stream, const Length& l)
659{
660 stream << l.As(Length::Unit::Meter);
661
662 return stream;
663}
664
665std::ostream&
666operator<<(std::ostream& stream, const Length::Quantity& q)
667{
668 stream << q.Value() << ' ' << ToSymbol(q.Unit());
669
670 return stream;
671}
672
673std::ostream&
674operator<<(std::ostream& stream, Length::Unit unit)
675{
676 stream << ToName(unit);
677
678 return stream;
679}
680
697std::tuple<bool, double, std::string>
698ParseLengthString(const std::string& input)
699{
700 NS_LOG_FUNCTION(input);
701
702 double value = 0;
703 std::size_t pos = 0;
704 std::string symbol;
705
706 try
707 {
708 value = std::stod(input, &pos);
709 }
710 catch (const std::exception& e)
711 {
712 NS_LOG_ERROR("Caught exception while parsing double: " << e.what());
713
714 return std::make_tuple(false, 0, "");
715 }
716
717 // skip any whitespace between value and symbol
718 while (pos < input.size() && std::isspace(input[pos]))
719 {
720 ++pos;
721 }
722
723 if (pos < input.size())
724 {
725 NS_LOG_LOGIC("String has value and symbol, extracting symbol");
726
727 // input has a double followed by a string
728 symbol = input.substr(pos);
729 }
730
731 return std::make_tuple(true, value, symbol);
732}
733
734std::istream&
735operator>>(std::istream& stream, Length& l)
736{
737 bool success = false;
738 double value = 0;
739 std::string symbol;
740 std::string temp;
741
742 // configure stream to skip whitespace in case it was disabled
743 auto origFlags = stream.flags();
744 std::skipws(stream);
745
746 // Read the contents into a temporary string and parse it manually
747 stream >> temp;
748
749 std::tie(success, value, symbol) = ParseLengthString(temp);
750
751 if (success && symbol.empty())
752 {
753 NS_LOG_LOGIC("Temp string only contained value, extracting unit symbol from stream");
754
755 // temp only contained the double
756 // still need to read the symbol from the stream
757 stream >> symbol;
758 }
759
760 // special handling for nautical mile which is two words
761 if (symbol == "nautical")
762 {
763 stream >> temp;
764
765 if (!temp.empty())
766 {
767 symbol.push_back(' ');
768 symbol.append(temp);
769 }
770 }
771
772 Length(value, symbol).swap(l);
773
774 // restore original flags
775 stream.flags(origFlags);
776
777 return stream;
778}
779
780Length
782{
783 return Length(value, Length::Unit::Nanometer);
784}
785
786Length
788{
789 return Length(value, Length::Unit::Micrometer);
790}
791
792Length
794{
795 return Length(value, Length::Unit::Millimeter);
796}
797
798Length
800{
801 return Length(value, Length::Unit::Centimeter);
802}
803
804Length
806{
807 return Length(value, Length::Unit::Meter);
808}
809
810Length
812{
813 return Length(value, Length::Unit::Kilometer);
814}
815
816Length
818{
819 return Length(value, Length::Unit::NauticalMile);
820}
821
822Length
824{
825 return Length(value, Length::Unit::Inch);
826}
827
828Length
829Feet(double value)
830{
831 return Length(value, Length::Unit::Foot);
832}
833
834Length
836{
837 return Length(value, Length::Unit::Yard);
838}
839
840Length
842{
843 return Length(value, Length::Unit::Mile);
844}
845
848} // namespace ns3
Functor for hashing Length::Unit values.
Definition: length.cc:217
std::size_t operator()(ns3::Length::Unit u) const noexcept
Produce a hash value for a Length::Unit.
Definition: length.cc:226
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:372
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:364
double GetDouble() const
Current length value.
Definition: length.cc:380
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:356
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:317
Quantity As(Unit unit) const
Create a Quantity in a specific unit from a Length.
Definition: length.cc:386
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:348
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:243
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:257
bool IsLess(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is greater in value than this instance.
Definition: length.cc:340
bool IsNotEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is not equal in value to this instance.
Definition: length.cc:332
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:160
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:811
Length MilliMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:793
Length NauticalMiles(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:817
std::string ToName(Length::Unit unit, bool plural)
Return the name of the supplied unit.
Definition: length.cc:541
bool operator>(const Length &left, const Length &right)
Check if left has a value greater than right.
Definition: length.cc:420
Length Yards(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:835
Length Feet(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:829
Length Mod(const Length &numerator, const Length &denominator)
Calculate the amount remaining after dividing two lengths.
Definition: length.cc:500
Length MicroMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:787
Length Miles(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:841
Length Meters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:805
std::string ToSymbol(Length::Unit unit)
Return the symbol of the supplied unit.
Definition: length.cc:513
Length CentiMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:799
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:481
Length NanoMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:781
Length Inches(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:823
std::optional< Length::Unit > FromString(std::string unitString)
Find the equivalent Length::Unit for a unit string.
Definition: length.cc:576
#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.
double Convert(const ns3::Length::Quantity &from, ns3::Length::Unit toUnit)
Convert a Length::Quantity to the equivalent value in another unit.
Definition: length.cc:205
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 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:665
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:129
ATTRIBUTE_HELPER_CPP(Length)
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:153
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:698
value
Definition: second.py:41