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