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