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 
49 namespace {
59 template<class R>
60 double ScaleValue (double value)
61 {
62  return (value * R::num) / static_cast<double> (R::den);
63 }
64 
72 double FootToMeter (double value)
73 {
74  return value * 0.3048;
75 }
76 
84 double MeterToFoot (double value)
85 {
86  return value * 3.28084;
87 }
88 
100 template<class R>
101 double USToMeter (double value)
102 {
103  return FootToMeter ( ScaleValue<R> (value) );
104 }
105 
117 template<class R>
118 double MeterToUS (double value)
119 {
120  return ScaleValue<R> ( MeterToFoot (value) );
121 }
122 
132 double 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 
201 double Convert (const ns3::Length::Quantity& from, ns3::Length::Unit toUnit)
202 {
203  return Convert (from.Value (), from.Unit (), toUnit);
204 }
205 
212 class EnumHash
213 {
214 public:
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 
230 namespace ns3 {
231 
232 NS_LOG_COMPONENT_DEFINE ("Length");
233 
234 // Implement the attribute helper
236 
237 std::optional<Length>
238 Length::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 
258 Length::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 
268 Length::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 
285 Length::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 
299 Length&
301 {
302  NS_LOG_FUNCTION (this << q);
303 
304  m_value = Convert (q, Length::Unit::Meter);
305 
306  return *this;
307 }
308 
309 bool
310 Length::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 
324 bool
325 Length::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 
332 bool
333 Length::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 
340 bool
341 Length::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 
348 bool
349 Length::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 
356 bool
357 Length::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 
364 void
366 {
367  using std::swap;
368 
369  swap (m_value, other.m_value);
370 }
371 
372 double
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 
388 bool
389 operator== (const Length& left, const Length& right)
390 {
391  return left.GetDouble () == right.GetDouble ();
392 }
393 
394 bool
395 operator!= (const Length& left, const Length& right)
396 {
397  return left.GetDouble () != right.GetDouble ();
398 }
399 
400 bool
401 operator< (const Length& left, const Length& right)
402 {
403  return left.GetDouble () < right.GetDouble ();
404 }
405 
406 bool
407 operator<= (const Length& left, const Length& right)
408 {
409  return left.GetDouble () <= right.GetDouble ();
410 }
411 
412 bool
413 operator> (const Length& left, const Length& right)
414 {
415  return left.GetDouble () > right.GetDouble ();
416 }
417 
418 bool
419 operator>= (const Length& left, const Length& right)
420 {
421  return left.GetDouble () >= right.GetDouble ();
422 }
423 
424 Length
425 operator+ (const Length& left, const Length& right)
426 {
427  double value = left.GetDouble () + right.GetDouble ();
428  return Length ( value, Length::Unit::Meter );
429 }
430 
431 Length
432 operator- (const Length& left, const Length& right)
433 {
434  double value = left.GetDouble () - right.GetDouble ();
435  return Length ( value, Length::Unit::Meter );
436 }
437 
438 Length
439 operator* (const Length& left, double scalar)
440 {
441  double value = left.GetDouble () * scalar;
442  return Length ( value, Length::Unit::Meter );
443 }
444 
445 Length
446 operator* (double scalar, const Length & right)
447 {
448  return right * scalar;
449 }
450 
451 Length
452 operator/ (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 
462 double
463 operator/ (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 
473 int64_t
474 Div (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 
492 Length
493 Mod (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 
505 std::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 
535 std::string
536 ToName (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 
571 std::optional<Length::Unit>
572 FromString (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 
656 std::ostream&
657 operator<< (std::ostream& stream, const Length& l)
658 {
659  stream << l.As (Length::Unit::Meter);
660 
661  return stream;
662 }
663 
664 std::ostream&
665 operator<< (std::ostream& stream, const Length::Quantity& q)
666 {
667  stream << q.Value () << ' ' << ToSymbol (q.Unit ());
668 
669  return stream;
670 }
671 
672 std::ostream&
673 operator<< (std::ostream& stream, Length::Unit unit)
674 {
675  stream << ToName (unit);
676 
677  return stream;
678 }
679 
696 std::tuple<bool, double, std::string>
697 ParseLengthString (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 
731 std::istream&
732 operator>> (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 
777 Length
778 NanoMeters (double value)
779 {
780  return Length (value, Length::Unit::Nanometer);
781 }
782 
783 Length
784 MicroMeters (double value)
785 {
786  return Length (value, Length::Unit::Micrometer);
787 }
788 
789 Length
790 MilliMeters (double value)
791 {
792  return Length (value, Length::Unit::Millimeter);
793 }
794 
795 Length
796 CentiMeters (double value)
797 {
798  return Length (value, Length::Unit::Centimeter);
799 }
800 
801 Length
802 Meters (double value)
803 {
804  return Length (value, Length::Unit::Meter);
805 }
806 
807 Length
808 KiloMeters (double value)
809 {
810  return Length (value, Length::Unit::Kilometer);
811 }
812 
813 Length
814 NauticalMiles (double value)
815 {
816  return Length (value, Length::Unit::NauticalMile);
817 }
818 
819 Length
820 Inches (double value)
821 {
822  return Length (value, Length::Unit::Inch);
823 }
824 
825 Length
826 Feet (double value)
827 {
828  return Length (value, Length::Unit::Foot);
829 }
830 
831 Length
832 Yards (double value)
833 {
834  return Length (value, Length::Unit::Yard);
835 }
836 
837 Length
838 Miles (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
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 & operator=(const Length &other)=default
Copy Assignment operator.
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: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: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.
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
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.h:158
ATTRIBUTE_HELPER_CPP(Length)
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:176
void swap(UUID &uuid1, UUID &uuid2) noexcept
Definition: uuid.cc:212
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
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:162
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:139