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 <tuple>
36#include <type_traits>
37#include <unordered_map>
38#include <vector>
39
50namespace {
60template<class R>
61double ScaleValue (double value)
62{
63 return (value * R::num) / static_cast<double> (R::den);
64}
65
73double FootToMeter (double value)
74{
75 return value * 0.3048;
76}
77
85double MeterToFoot (double value)
86{
87 return value * 3.28084;
88}
89
101template<class R>
102double USToMeter (double value)
103{
104 return FootToMeter ( ScaleValue<R> (value) );
105}
106
118template<class R>
119double MeterToUS (double value)
120{
121 return ScaleValue<R> ( MeterToFoot (value) );
122}
123
133double Convert (double value, ns3::Length::Unit fromUnit, ns3::Length::Unit toUnit)
134{
135 using Unit = ns3::Length::Unit;
136 using Key = std::pair<Unit, Unit>;
137 using Conversion = std::function<double (double)>;
138
142 struct KeyHash
143 {
144 std::size_t operator () (const Key& key) const noexcept
145 {
146 static_assert (sizeof(Unit) < sizeof(std::size_t),
147 "sizeof(Length::Unit) changed, it must be less than "
148 "sizeof(std::size_t)");
149
150 int shift = sizeof(Unit) * 8;
151 return static_cast<std::size_t> (key.first) << shift |
152 static_cast<std::size_t> (key.second);
153 }
154
155 };
156
157 using ConversionTable = std::unordered_map<Key, Conversion, KeyHash>;
158
159 static ConversionTable CONVERSIONS {
160 { {Unit::Nanometer, Unit::Meter}, ScaleValue<std::nano> },
161 { {Unit::Meter, Unit::Nanometer}, ScaleValue<std::giga> },
162 { {Unit::Micrometer, Unit::Meter}, ScaleValue<std::micro> },
163 { {Unit::Meter, Unit::Micrometer}, ScaleValue<std::mega> },
164 { {Unit::Millimeter, Unit::Meter}, ScaleValue<std::milli> },
165 { {Unit::Meter, Unit::Millimeter}, ScaleValue<std::kilo> },
166 { {Unit::Centimeter, Unit::Meter}, ScaleValue<std::centi> },
167 { {Unit::Meter, Unit::Centimeter}, ScaleValue<std::hecto> },
168 { {Unit::Meter, Unit::Meter}, ScaleValue<std::ratio<1,1> > },
169 { {Unit::Kilometer, Unit::Meter}, ScaleValue<std::kilo> },
170 { {Unit::Meter, Unit::Kilometer}, ScaleValue<std::milli> },
171 { {Unit::NauticalMile, Unit::Meter}, ScaleValue<std::ratio<1852, 1> > },
172 { {Unit::Meter, Unit::NauticalMile}, ScaleValue<std::ratio<1, 1852> > },
173 { {Unit::Inch, Unit::Meter}, USToMeter<std::ratio<1, 12> > },
174 { {Unit::Meter, Unit::Inch}, MeterToUS<std::ratio<12, 1> > },
175 { {Unit::Foot, Unit::Meter}, FootToMeter },
176 { {Unit::Meter, Unit::Foot}, MeterToFoot },
177 { {Unit::Yard, Unit::Meter}, USToMeter<std::ratio<3, 1> > },
178 { {Unit::Meter, Unit::Yard}, MeterToUS<std::ratio<1, 3> > },
179 { {Unit::Mile, Unit::Meter}, USToMeter<std::ratio<5280, 1> > },
180 { {Unit::Meter, Unit::Mile}, MeterToUS<std::ratio<1, 5280> > }
181 };
182
183 auto iter = CONVERSIONS.find ( Key {fromUnit, toUnit} );
184
185 if (iter == CONVERSIONS.end ())
186 {
187 NS_FATAL_ERROR ("No conversion defined for " << fromUnit
188 << " -> " << toUnit);
189 }
190
191 return iter->second (value);
192}
193
203{
204 return Convert (from.Value (), from.Unit (), toUnit);
205}
206
214{
215public:
223 std::size_t operator () (ns3::Length::Unit u) const noexcept
224 {
225 return static_cast<std::size_t> (u);
226 }
227};
228
229} // unnamed namespace
230
231namespace ns3 {
232
233NS_LOG_COMPONENT_DEFINE ("Length");
234
235// Implement the attribute helper
237
238std::tuple<bool, Length>
239Length::TryParse (double value, const std::string& unitString)
240{
241 NS_LOG_FUNCTION (value << unitString);
242
243 bool validUnit = false;
244 Length::Unit unit;
245
246 std::tie (validUnit, unit) = FromString (unitString);
247
248 Length length;
249
250 if (validUnit)
251 {
252 length = Length (value, unit);
253 }
254
255 return std::make_tuple (validUnit, length);
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 bool validUnit;
280 Length::Unit unit;
281
282 std::tie (validUnit, unit) = FromString (unitString);
283
284 if (!validUnit)
285 {
286 NS_FATAL_ERROR ("A Length object could not be constructed from the unit "
287 "string '" << unitString << "', because the string is not associated "
288 "with a Length::Unit entry");
289 }
290
291 m_value = Convert (value, unit, Length::Unit::Meter);
292}
293
294Length::Length (double value, Length::Unit unit)
295 : m_value (0)
296{
297 NS_LOG_FUNCTION (this << value << unit);
298
299 m_value = Convert (value, unit, Length::Unit::Meter);
300}
301
303 : Length (quantity.Value (), quantity.Unit ())
304{
305 NS_LOG_FUNCTION (this << quantity);
306}
307
308Length&
310{
311 NS_LOG_FUNCTION (this << q);
312
313 m_value = Convert (q, Length::Unit::Meter);
314
315 return *this;
316}
317
318bool
319Length::IsEqual (const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
320{
321 NS_LOG_FUNCTION (this << m_value << other.m_value << tolerance);
322
323 if ( m_value == other.m_value )
324 {
325 return true;
326 }
327
328 auto diff = std::abs (m_value - other.m_value);
329
330 return diff <= tolerance;
331}
332
333bool
334Length::IsNotEqual (const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
335{
336 NS_LOG_FUNCTION (this << m_value << other.m_value << tolerance);
337
338 return !IsEqual (other, tolerance);
339}
340
341bool
342Length::IsLess (const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
343{
344 NS_LOG_FUNCTION (this << m_value << other.m_value << tolerance);
345
346 return m_value < other.m_value && IsNotEqual (other, tolerance);
347}
348
349bool
350Length::IsLessOrEqual (const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
351{
352 NS_LOG_FUNCTION (this << m_value << other.m_value << tolerance);
353
354 return m_value < other.m_value || IsEqual (other, tolerance);
355}
356
357bool
358Length::IsGreater (const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
359{
360 NS_LOG_FUNCTION (this << m_value << other.m_value << tolerance);
361
362 return !IsLessOrEqual (other, tolerance);
363}
364
365bool
366Length::IsGreaterOrEqual (const Length& other, double tolerance /*=DEFAULT_TOLERANCE*/) const
367{
368 NS_LOG_FUNCTION (this << m_value << other.m_value << tolerance);
369
370 return !IsLess (other, tolerance);
371}
372
373void
375{
376 using std::swap;
377
378 swap (m_value, other.m_value);
379}
380
381double
383{
384 return m_value;
385}
386
389{
390 NS_LOG_FUNCTION (this << unit);
391
392 double value = Convert (m_value, Length::Unit::Meter, unit);
393
394 return Quantity (value, unit);
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
421bool
422operator> (const Length& left, const Length& right)
423{
424 return left.GetDouble () > right.GetDouble ();
425}
426
427bool
428operator>= (const Length& left, const Length& right)
429{
430 return left.GetDouble () >= right.GetDouble ();
431}
432
433Length
434operator+ (const Length& left, const Length& right)
435{
436 double value = left.GetDouble () + right.GetDouble ();
437 return Length ( value, Length::Unit::Meter );
438}
439
440Length
441operator- (const Length& left, const Length& right)
442{
443 double value = left.GetDouble () - right.GetDouble ();
444 return Length ( value, Length::Unit::Meter );
445}
446
447Length
448operator* (const Length& left, double scalar)
449{
450 double value = left.GetDouble () * scalar;
451 return Length ( value, Length::Unit::Meter );
452}
453
454Length
455operator* (double scalar, const Length & right)
456{
457 return right * scalar;
458}
459
460Length
461operator/ (const Length & left, double scalar)
462{
463 if (scalar == 0)
464 {
465 NS_FATAL_ERROR ("Attempted to divide Length by 0");
466 }
467
468 return left * (1.0 / scalar);
469}
470
471double
472operator/ (const Length & numerator, const Length& denominator)
473{
474 if (denominator.GetDouble () == 0)
475 {
476 return std::numeric_limits<double>::quiet_NaN ();
477 }
478
479 return numerator.GetDouble () / denominator.GetDouble ();
480}
481
482int64_t
483Div (const Length& numerator, const Length& denominator, Length* remainder)
484{
485 double value = numerator / denominator;
486
487 if (std::isnan (value))
488 {
489 NS_FATAL_ERROR ("numerator / denominator return NaN");
490 }
491
492 if ( remainder )
493 {
494 double rem = std::fmod (numerator.GetDouble (), denominator.GetDouble ());
495 *remainder = Length (rem, Length::Unit::Meter);
496 }
497
498 return static_cast<int64_t> (std::trunc (value));
499}
500
501Length
502Mod (const Length& numerator, const Length& denominator)
503{
504 double rem = std::fmod (numerator.GetDouble (), denominator.GetDouble ());
505
506 if (std::isnan (rem))
507 {
508 NS_FATAL_ERROR ("numerator / denominator return NaN");
509 }
510
511 return Length (rem, Length::Unit::Meter);
512}
513
514std::string
516{
517 using StringTable = std::unordered_map<Length::Unit, std::string, EnumHash>;
518
519 static const StringTable STRINGS {
520 {Length::Unit::Nanometer, "nm"},
521 {Length::Unit::Micrometer, "um"},
522 {Length::Unit::Millimeter, "mm"},
523 {Length::Unit::Centimeter, "cm"},
524 {Length::Unit::Meter, "m"},
525 {Length::Unit::Kilometer, "km"},
526 {Length::Unit::NauticalMile, "nmi"},
527 {Length::Unit::Inch, "in"},
528 {Length::Unit::Foot, "ft"},
529 {Length::Unit::Yard, "yd"},
530 {Length::Unit::Mile, "mi"}
531 };
532
533 auto iter = STRINGS.find (unit);
534
535 if (iter == STRINGS.end ())
536 {
537 NS_FATAL_ERROR ("A symbol could not be found for Length::Unit with value "
538 << EnumHash ()(unit));
539 }
540
541 return iter->second;
542}
543
544std::string
545ToName (Length::Unit unit, bool plural /*=false*/)
546{
547 using Entry = std::tuple<std::string, std::string>;
548 using StringTable = std::unordered_map<Length::Unit, Entry, EnumHash>;
549
550 static const StringTable STRINGS {
551 {Length::Unit::Nanometer, Entry{"nanometer", "nanometers"}},
552 {Length::Unit::Micrometer, Entry{"micrometer", "micrometer"}},
553 {Length::Unit::Millimeter, Entry{"millimeter", "millimeters"}},
554 {Length::Unit::Centimeter, Entry{"centimeter", "centimeters"}},
555 {Length::Unit::Meter, Entry{"meter", "meters"}},
556 {Length::Unit::Kilometer, Entry{"kilometer", "kilometers"}},
557 {Length::Unit::NauticalMile, Entry{"nautical mile", "nautical miles"}},
558 {Length::Unit::Inch, Entry{"inch", "inches"}},
559 {Length::Unit::Foot, Entry{"foot", "feet"}},
560 {Length::Unit::Yard, Entry{"yard", "yards"}},
561 {Length::Unit::Mile, Entry{"mile", "miles"}}
562 };
563
564 auto iter = STRINGS.find (unit);
565
566 if (iter == STRINGS.end ())
567 {
568 NS_FATAL_ERROR ("A symbol could not be found for Length::Unit with value "
569 << EnumHash ()(unit));
570 }
571
572 if (plural)
573 {
574 return std::get<1> (iter->second);
575 }
576
577 return std::get<0> (iter->second);
578}
579
580std::tuple<bool, Length::Unit>
581FromString (std::string unitString)
582{
583 using UnitTable = std::unordered_map<std::string, Length::Unit>;
584
585 static const UnitTable UNITS {
586 { "nm", Length::Unit::Nanometer },
587 { "nanometer", Length::Unit::Nanometer },
588 { "nanometers", Length::Unit::Nanometer },
589 { "nanometre", Length::Unit::Nanometer },
590 { "nanometres", Length::Unit::Nanometer },
591 { "um", Length::Unit::Micrometer },
592 { "micrometer", Length::Unit::Micrometer },
593 { "micrometers", Length::Unit::Micrometer },
594 { "micrometre", Length::Unit::Micrometer },
595 { "micrometres", Length::Unit::Micrometer },
596 { "mm", Length::Unit::Millimeter },
597 { "millimeter", Length::Unit::Millimeter },
598 { "millimeters", Length::Unit::Millimeter },
599 { "millimetre", Length::Unit::Millimeter },
600 { "millimetres", Length::Unit::Millimeter },
601 { "cm", Length::Unit::Centimeter },
602 { "centimeter", Length::Unit::Centimeter },
603 { "centimeters", Length::Unit::Centimeter },
604 { "centimetre", Length::Unit::Centimeter },
605 { "centimetres", Length::Unit::Centimeter },
606 { "m", Length::Unit::Meter },
607 { "meter", Length::Unit::Meter },
608 { "metre", Length::Unit::Meter },
609 { "meters", Length::Unit::Meter },
610 { "metres", Length::Unit::Meter },
611 { "km", Length::Unit::Kilometer },
612 { "kilometer", Length::Unit::Kilometer },
613 { "kilometers", Length::Unit::Kilometer },
614 { "kilometre", Length::Unit::Kilometer },
615 { "kilometres", Length::Unit::Kilometer },
616 { "nmi", Length::Unit::NauticalMile },
617 { "nauticalmile", Length::Unit::NauticalMile },
618 { "nauticalmiles", Length::Unit::NauticalMile },
619 { "in", Length::Unit::Inch },
620 { "inch", Length::Unit::Inch },
621 { "inches", Length::Unit::Inch },
622 { "ft", Length::Unit::Foot },
623 { "foot", Length::Unit::Foot },
624 { "feet", Length::Unit::Foot },
625 { "yd", Length::Unit::Yard },
626 { "yard", Length::Unit::Yard },
627 { "yards", Length::Unit::Yard },
628 { "mi", Length::Unit::Mile },
629 { "mile", Length::Unit::Mile },
630 { "miles", Length::Unit::Mile }
631 };
632
633 //function to trim whitespace and convert to lowercase in one pass
634 static auto Normalize = [] (const std::string& str)
635 {
636 std::string output;
637 output.reserve (str.size ());
638
639 for (unsigned char c : str)
640 {
641 //this strips all spaces not just beg/end but is fine for our purposes
642 if (std::isspace (c) )
643 {
644 continue;
645 }
646
647 output.push_back (std::tolower (c));
648 }
649
650 return output;
651 };
652
653 unitString = Normalize (unitString);
654
655 auto iter = UNITS.find (unitString);
656
657 bool valid = false;
658 Length::Unit unit;
659
660 if (iter != UNITS.end ())
661 {
662 valid = true;
663 unit = iter->second;
664 }
665
666 return std::make_tuple (valid, unit);
667}
668
669std::ostream&
670operator<< (std::ostream& stream, const Length& l)
671{
672 stream << l.As (Length::Unit::Meter);
673
674 return stream;
675}
676
677std::ostream&
678operator<< (std::ostream& stream, const Length::Quantity& q)
679{
680 stream << q.Value () << ' ' << ToSymbol (q.Unit ());
681
682 return stream;
683}
684
685std::ostream&
686operator<< (std::ostream& stream, Length::Unit unit)
687{
688 stream << ToName (unit);
689
690 return stream;
691}
692
709std::tuple<bool, double, std::string>
710ParseLengthString (const std::string& input)
711{
712 NS_LOG_FUNCTION (input);
713
714 double value = 0;
715 std::size_t pos = 0;
716 std::string symbol;
717
718 try
719 {
720 value = std::stod(input, &pos);
721 }
722 catch (const std::exception& e)
723 {
724 NS_LOG_ERROR ("Caught exception while parsing double: " << e.what());
725
726 return std::make_tuple(false, 0, "");
727 }
728
729 //skip any whitespace between value and symbol
730 while (pos < input.size () && std::isspace(input[pos]))
731 ++pos;
732
733 if (pos < input.size ())
734 {
735 NS_LOG_LOGIC ("String has value and symbol, extracting symbol");
736
737 //input has a double followed by a string
738 symbol = input.substr(pos);
739 }
740
741 return std::make_tuple(true, value, symbol);
742}
743
744std::istream&
745operator>> (std::istream& stream, Length& l)
746{
747 bool success = false;
748 double value = 0;
749 std::string symbol;
750 std::string temp;
751
752 //configure stream to skip whitespace in case it was disabled
753 auto origFlags = stream.flags ();
754 std::skipws (stream);
755
756 //Read the contents into a temporary string and parse it manually
757 stream >> temp;
758
759 std::tie(success, value, symbol) = ParseLengthString (temp);
760
761 if (success && symbol.empty ())
762 {
763 NS_LOG_LOGIC ("Temp string only contained value, extracting unit symbol from stream");
764
765 //temp only contained the double
766 //still need to read the symbol from the stream
767 stream >> symbol;
768 }
769
770 //special handling for nautical mile which is two words
771 if (symbol == "nautical")
772 {
773 stream >> temp;
774
775 if (!temp.empty ())
776 {
777 symbol.push_back (' ');
778 symbol.append (temp);
779 }
780 }
781
782 Length (value, symbol).swap (l);
783
784 //restore original flags
785 stream.flags (origFlags);
786
787 return stream;
788}
789
790Length
791NanoMeters (double value)
792{
793 return Length (value, Length::Unit::Nanometer);
794}
795
796Length
797MicroMeters (double value)
798{
799 return Length (value, Length::Unit::Micrometer);
800}
801
802Length
803MilliMeters (double value)
804{
805 return Length (value, Length::Unit::Millimeter);
806}
807
808Length
809CentiMeters (double value)
810{
811 return Length (value, Length::Unit::Centimeter);
812}
813
814Length
815Meters (double value)
816{
817 return Length (value, Length::Unit::Meter);
818}
819
820Length
821KiloMeters (double value)
822{
823 return Length (value, Length::Unit::Kilometer);
824}
825
826Length
827NauticalMiles (double value)
828{
829 return Length (value, Length::Unit::NauticalMile);
830}
831
832Length
833Inches (double value)
834{
835 return Length (value, Length::Unit::Inch);
836}
837
838Length
839Feet (double value)
840{
841 return Length (value, Length::Unit::Foot);
842}
843
844Length
845Yards (double value)
846{
847 return Length (value, Length::Unit::Yard);
848}
849
850Length
851Miles (double value)
852{
853 return Length (value, Length::Unit::Mile);
854}
855
858} // namespace ns3
Functor for hashing Length::Unit values.
Definition: length.cc:214
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:374
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:366
double GetDouble() const
Current length value.
Definition: length.cc:382
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:358
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:319
Quantity As(Unit unit) const
Create a Quantity in a specific unit from a Length.
Definition: length.cc:388
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:350
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:342
static std::tuple< bool, Length > TryParse(double value, const std::string &unit)
Attempt to construct a Length object from a value and a unit string.
Definition: length.cc:239
bool IsNotEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is not equal in value to this instance.
Definition: length.cc:334
#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:821
Length MilliMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:803
Length NauticalMiles(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:827
std::string ToName(Length::Unit unit, bool plural)
Return the name of the supplied unit.
Definition: length.cc:545
bool operator>(const Length &left, const Length &right)
Check if left has a value greater than right.
Definition: length.cc:422
Length Yards(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:845
Length Feet(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:839
Length Mod(const Length &numerator, const Length &denominator)
Calculate the amount remaining after dividing two lengths.
Definition: length.cc:502
Length MicroMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:797
Length Miles(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:851
std::tuple< bool, Length::Unit > FromString(std::string unitString)
Find the equivalent Length::Unit for a unit string.
Definition: length.cc:581
Length Meters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:815
std::string ToSymbol(Length::Unit unit)
Return the symbol of the supplied unit.
Definition: length.cc:515
Length CentiMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:809
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:483
Length NanoMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:791
Length Inches(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:833
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:257
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#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:202
double USToMeter(double value)
Convert a value from a US Customary unit (inches, feet, yards etc.) to meters.
Definition: length.cc:102
double MeterToFoot(double value)
Convert a value in meters to the equivalent value in feet.
Definition: length.cc:85
double MeterToUS(double value)
Convert a value from meters to a US Customary unit (inches, feet, yards etc.)
Definition: length.cc:119
double FootToMeter(double value)
Convert a value in feet to the equivalent value in meters.
Definition: length.cc:73
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==(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:710
bool operator!=(Callback< R, T1, T2, T3, T4, T5, T6, T7, T8, T9 > a, Callback< R, T1, T2, T3, T4, T5, T6, T7, T8, T9 > b)
Inequality test.
Definition: callback.h:1612