A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
length.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019 Lawrence Livermore National Laboratory
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathew Bielejeski <bielejeski1@llnl.gov>
7 */
8
9#ifndef NS3_LENGTH_H_
10#define NS3_LENGTH_H_
11
12#include "attribute-helper.h"
13#include "attribute.h"
14
15#ifdef HAVE_BOOST
16#include <boost/units/quantity.hpp>
17#include <boost/units/systems/si.hpp>
18#endif
19
20#include <istream>
21#include <limits>
22#include <optional>
23#include <ostream>
24#include <string>
25
26/**
27 * @file
28 * @ingroup length
29 * Declaration of ns3::Length class
30 */
31
32/**
33 * ns3 namespace
34 */
35namespace ns3
36{
37
38/**
39 * @ingroup core
40 * @defgroup length Length
41 *
42 * Management of lengths in real world units.
43 *
44 */
45
46/**
47 * @ingroup length
48 *
49 * Represents a length in meters
50 *
51 * The purpose of this class is to replace the use of raw numbers (ints, doubles)
52 * that have implicit lengths with a class that represents lengths with an explicit
53 * unit. Using raw values with implicit units can lead to bugs when a value is
54 * assumed to represent one unit but actually represents another. For example,
55 * assuming a value represents a length in meters when it in fact represents a
56 * length in kilometers.
57 *
58 * The Length class prevents this confusion by storing values internally as
59 * doubles representing lengths in Meters and providing conversion functions
60 * to convert to/from other length units (kilometers, miles, etc.).
61 *
62 * ## Supported Units ##
63 *
64 * Conversion to and from meters is supported for the following units:
65 *
66 * ### Metric ###
67 * - nanometer
68 * - micrometer
69 * - millimeter
70 * - centimeter
71 * - meter
72 * - kilometer
73 * - nautical mile
74 *
75 * ### US Customary ###
76 * - inch
77 * - foot
78 * - yard
79 * - mile
80 *
81 * ## Construction ##
82 *
83 * Length objects can be constructed in a number of different ways
84 *
85 * ### String Constructor ###
86 *
87 * The string constructor parses strings with the format <number><unit> or
88 * <number> <unit> and creates the equivalent Length value in meters.
89 * <unit> can be the full name of the unit (nanometer, kilometer, foot, etc.) or the
90 * abbreviated name (nm, km, ft, etc.).
91 *
92 * @code
93 * //construct lengths from strings
94 * Length foot ("1foot");
95 * Length cm ("1cm");
96 * Length mile ("1 mile");
97 * Length km ("1 km");
98 *
99 * //nautical mile is special because it is two words
100 * Length nautmile ("1 nautical mile");
101 * Length nmi ("1 nmi");
102 * @endcode
103 *
104 * ### Quantity Constructor ###
105 *
106 * Quantity is a class that describes a value and a unit type. For example, meter
107 * is a unit while 5 meters is a quantity.
108 * The Length constructor takes the quantity instance and converts it to the
109 * equivalent value in meters.
110 *
111 * @code
112 * //construct a Length representing 2 kilometers
113 * Length::Quantity q (2, Length::Unit::Kilometer);
114 * Length km(q);
115 * @endcode
116 *
117 * ### Value/Unit Constructor
118 *
119 * Two constructors are provided which take a value and a unit as separate
120 * parameters. The difference between the two constructors is that one takes
121 * the unit as a string and the other takes the unit as a Length::Unit value.
122 * An assertion is triggered if the string does not map to a valid
123 * Length::Unit
124 *
125 * @code
126 * //These two constructors are equivalent
127 * Length l1 (1, "cm");
128 * Length l2 (1, Length::Unit::Centimeter);
129 * @endcode
130 *
131 * ### boost::units
132 *
133 * If the boost::units library is discovered during ns-3 configuration an
134 * additional constructor is enabled which allows constructing Length objects
135 * from boost::unit quantities.
136 *
137 * @code
138 * //construct length from a boost::units quantity
139 * boost::units::quantity<boost::units::si::length> q
140 * = 5 * boost::units::si::meter;
141 * Length meters (q);
142 * @endcode
143 *
144 * ## Arithmetic Operations ##
145 *
146 * The following arithmetic operations are supported:
147 *
148 * ### Addition ###
149 *
150 * Addition is between two Length instances
151 *
152 * @code
153 * std::cout << Length(1, Length::Unit::Meter) + Length (2, Length::Unit::Meter);
154 * // output: "3 m"
155 * @endcode
156 *
157 * ### Subtraction ###
158 *
159 * Subtraction is between two Length instances
160 *
161 * @code
162 * std::cout << Length(3, Length::Unit::Meter) - Length (2, Length::Unit::Meter);
163 * // output: "1 m"
164 * @endcode
165 *
166 * ### Multiplication ###
167 *
168 * Multiplication is only supported between a Length and a unitless scalar value
169 *
170 * @code
171 * std::cout << Length(1, Length::Unit::Meter) * 5; // output: "5 m"
172 *
173 * std::cout << 5 * Length (1, Length::Unit::Meter); // output: "5 m"
174 * @endcode
175 *
176 *
177 * ### Division ###
178 *
179 * Division can be between a Length and a scalar or two Length objects.
180 *
181 * Division between a Length and a scalar returns a new Length.
182 *
183 * Division between two Length objects returns a unitless value.
184 *
185 * @code
186 * std::cout << Length(5, Length::Unit::Meter) / 5; // output: "1 m"
187 *
188 * std::cout << Length (5, Length::Unit::Meter) / Length (5, Length::Unit::Meter);
189 * // output: 1
190 * @endcode
191 *
192 * ## Comparison Operations ##
193 *
194 * All the usual arithmetic comparison operations (=, !=, <, <=, >, >=) are supported.
195 * There are two forms of comparison operators: free function and member function.
196 * The free functions define =, !=, <, <=, >, >= and perform exact comparisons of
197 * the underlying double values. The Length class provides comparison
198 * operator functions (IsEqual, IsLess, IsGreater, etc.) which accept an
199 * additional tolerance value to control how much the underlying double values
200 * must match when performing the comparison.
201 *
202 * @code
203 * //check for exact match
204 * Length l (5, Length::Unit::Meter);
205 *
206 * bool match = (l == l); // match is true
207 *
208 * Length v1 (0.02, Length::Unit::Meter);
209 * Length v2 (0.022, Length::Unit::Meter);
210 *
211 * match = (v1 == v2); // match is false
212 *
213 * double tolerance = 0.01;
214 * bool mostly_match = v1.IsEqual (v2, tolerance); // mostly_match is true
215 * @endcode
216 *
217 * ## Serialization ##
218 *
219 * The Length class supports serialization using the << and >> operators.
220 * By default the output serialization is in meters. Use Length::As to output
221 * the Length value in a different unit.
222 *
223 * @code
224 * Length m(5, Length::Unit::Meter);
225 *
226 * std::cout << m << ", "
227 * << m.As(Length::Unit::Kilometer) << ", "
228 * << m.As(Length::Unit::Foot);
229 * //output: 5 m, 0.005 km, 16.4042 ft
230 * @endcode
231 */
233{
234 public:
235 /**
236 * Units of length in various measurement systems that are supported by the
237 * Length class
238 */
239 enum Unit : uint16_t
240 {
241 // Metric Units
242 Nanometer = 1, //!< 1e<sup>-9</sup> meters
243 Micrometer, //!< 1e<sup>-6</sup> meters
244 Millimeter, //!< 1e<sup>-3</sup> meters
245 Centimeter, //!< 1e<sup>-2</sup> meters
246 Meter, //!< Base length unit in metric system
247 Kilometer, //!< 1e<sup>3</sup> meters
248 NauticalMile, //!< 1,852 meters
249
250 // US Customary Units
251 Inch, //!< 1/12 of a foot
252 Foot, //!< Base length unit in US customary system
253 Yard, //!< 3 feet
254 Mile //!< 5,280 feet
255 };
256
257 /**
258 * An immutable class which represents a value in a specific length unit
259 */
261 {
262 public:
263 /**
264 * Constructor
265 *
266 * @param value Length value
267 * @param unit Length unit of the value
268 */
269 Quantity(double value, Length::Unit unit)
270 : m_value(value),
271 m_unit(unit)
272 {
273 }
274
275 /**
276 * Copy Constructor
277 */
278 Quantity(const Quantity&) = default;
279
280 /**
281 * Move Constructor
282 */
283 Quantity(Quantity&&) = default;
284
285 /**
286 * Destructor
287 */
288 ~Quantity() = default;
289
290 /**
291 * Copy Assignment Operator
292 * @param [in] other The source to copy from.
293 * @returns this.
294 */
295 Quantity& operator=(const Quantity& other) = default;
296
297 /**
298 * Move Assignment Operator
299 * @param [in] other The source to move from.
300 * @returns this.
301 */
302 Quantity& operator=(Quantity&& other) = default;
303
304 /**
305 * The value of the quantity
306 *
307 * @return The value of this quantity
308 */
309 double Value() const
310 {
311 return m_value;
312 }
313
314 /**
315 * The unit of the quantity
316 *
317 * @return The unit of this quantity
318 */
320 {
321 return m_unit;
322 }
323
324 private:
325 double m_value; //!< Value of the length
326 Length::Unit m_unit; //!< unit of length of the value
327 };
328
329 /**
330 * Default tolerance value used for the member comparison functions (IsEqual,
331 * IsLess, etc.)
332 *
333 * The default tolerance is set to epsilon which is defined as the difference
334 * between 1.0 and the next value that can be represented by a double.
335 */
336 static constexpr double DEFAULT_TOLERANCE = std::numeric_limits<double>::epsilon();
337
338 /**
339 * Attempt to construct a Length object from a value and a unit string
340 *
341 * \p unit can either be the full name of the unit (meter, kilometer, mile, etc.)
342 * or the symbol of the unit (m, km, mi, etc.)
343 *
344 * This function will return false if \p unit does not map to a known type.
345 *
346 * @param value Numeric value of the new length
347 * @param unit Unit that the value represents
348 *
349 * @return A std::optional object containing the Length object constructed from
350 * the given value and unit, if the attempt to construct the Length object was
351 * successful.
352 */
353 static std::optional<Length> TryParse(double value, const std::string& unit);
354
355 /**
356 * Default Constructor
357 *
358 * Initialize with a value of 0 meters.
359 */
360 Length();
361
362 /**
363 * String Constructor
364 *
365 * Parses \p text and initializes the value with the parsed result.
366 *
367 * The expected format of \p text is <number> <unit> or <number><unit>
368 *
369 * @param text Serialized length value
370 */
371 Length(const std::string& text);
372
373 /**
374 * Construct a Length object from a value and a unit string
375 *
376 * \p unit can either be the full name of the unit (meter, kilometer, mile, etc.)
377 * or the symbol of the unit (m, km, mi, etc.)
378 *
379 * @warning NS_FATAL_ERROR is called if \p unit is not a valid unit string.
380 * @warning Use Length::TryParse to parse potentially bad values without terminating.
381 *
382 * @param value Numeric value of the new length
383 * @param unit Unit that the value represents
384 */
385 Length(double value, const std::string& unit);
386
387 /**
388 * Construct a Length object from a value and a unit
389 *
390 * @warning NS_FATAL_ERROR is called if \p unit is not valid.
391 * @warning Use Length::TryParse to parse potentially bad values without terminating.
392 *
393 * @param value Numeric value of the new length
394 * @param unit Length unit of the value
395 */
396 Length(double value, Length::Unit unit);
397
398 /**
399 * Construct a Length object from a Quantity
400 *
401 * @param quantity Quantity representing a length value and unit
402 */
403 Length(Quantity quantity);
404
405#ifdef HAVE_BOOST_UNITS
406 /**
407 * Construct a Length object from a boost::units::quantity
408 *
409 * @note The boost::units:quantity must contain a unit that derives from
410 * the length dimension. Passing a quantity with a Unit that is not a length
411 * unit will result in a compile time error
412 *
413 * @tparam U A boost::units length unit
414 * @tparam T Numeric data type of the quantity value
415 *
416 * @param quantity A boost::units length quantity
417 */
418 template <class U, class T>
419 explicit Length(boost::units::quantity<U, T> quantity);
420#endif
421
422 /**
423 * Copy Constructor
424 *
425 * Initialize an object with the value from \p other.
426 *
427 * @param other Length object to copy
428 */
429 Length(const Length& other) = default;
430
431 /**
432 * Move Constructor
433 *
434 * Initialize an object with the value from \p other.
435 *
436 * After the move completes, \p other is left in an undefined but
437 * usable state.
438 *
439 * @param other Length object to move
440 */
441 Length(Length&& other) = default;
442
443 /**
444 * Destructor
445 */
446 ~Length() = default;
447
448 /**
449 * Copy Assignment operator
450 *
451 * Replace the current value with the value from \p other
452 *
453 * @param other Length object to copy
454 *
455 * @return Reference to the updated object
456 */
457 Length& operator=(const Length& other) = default;
458
459 /**
460 * Move Assignment operator
461 *
462 * Replace the current value with the value from \p other
463 * After the move, \p other is left in an undefined but valid state
464 *
465 * @param other Length object to move
466 *
467 * @return Reference to the updated object
468 */
469 Length& operator=(Length&& other) = default;
470
471 /**
472 * Assignment operator
473 *
474 * Replace the current value with the value from \p q
475 *
476 * @param q Quantity holding the value to assign
477 *
478 * @return Reference to the updated object
479 */
481
482 /**
483 * Check if \p other is equal in value to this instance.
484 *
485 * @param other Value to compare against
486 * @param tolerance Smallest difference allowed between the two
487 * values to still be considered equal
488 *
489 * @return true if the absolute difference between lengths
490 * is less than or equal to \p tolerance
491 */
492 bool IsEqual(const Length& other, double tolerance = DEFAULT_TOLERANCE) const;
493
494 /**
495 * Check if \p other is not equal in value to this instance.
496 *
497 * @param other Value to compare against
498 * @param tolerance Smallest difference allowed between the two
499 * values to still be considered equal
500 *
501 * @return true if the absolute difference between lengths
502 * is greater than \p tolerance
503 */
504 bool IsNotEqual(const Length& other, double tolerance = DEFAULT_TOLERANCE) const;
505
506 /**
507 * Check if \p other is greater in value than this instance.
508 *
509 * @param other Value to compare against
510 * @param tolerance Smallest difference allowed between the two
511 * values to still be considered equal
512 *
513 * @return true if the values are not equal and \p other is
514 * greater in value
515 */
516 bool IsLess(const Length& other, double tolerance = DEFAULT_TOLERANCE) const;
517
518 /**
519 * Check if \p other is greater or equal in value than this instance.
520 *
521 * @param other Value to compare against
522 * @param tolerance Smallest difference allowed between the two
523 * values to still be considered equal
524 *
525 * Equivalent to:
526 * @code
527 * IsEqual(other, tolerance) || IsLess(other, tolerance)
528 * @endcode
529 *
530 * @return true if the values are equal or \p other is
531 * greater in value
532 */
533 bool IsLessOrEqual(const Length& other, double tolerance = DEFAULT_TOLERANCE) const;
534
535 /**
536 * Check if \p other is less in value than this instance.
537 *
538 * @param other Value to compare against
539 * @param tolerance Smallest difference allowed between the two
540 * values to still be considered equal
541 *
542 * Equivalent to:
543 * @code
544 * !(IsLessOrEqual(other, tolerance))
545 * @endcode
546 *
547 * @return true if the values are not equal and \p other is
548 * less in value
549 */
550 bool IsGreater(const Length& other, double tolerance = DEFAULT_TOLERANCE) const;
551
552 /**
553 * Check if \p other is equal or less in value than this instance.
554 *
555 * @param other Value to compare against
556 * @param tolerance Smallest difference allowed between the two
557 * values to still be considered equal
558 *
559 * Equivalent to:
560 * @code
561 * !IsLess(other, tolerance)
562 * @endcode
563 *
564 * @return true if the values are equal or \p other is
565 * less in value
566 */
567 bool IsGreaterOrEqual(const Length& other, double tolerance = DEFAULT_TOLERANCE) const;
568
569 /**
570 * Swap values with another object
571 *
572 * Swap the current value with the value in \p other.
573 *
574 * Equivalent to:
575 * @code
576 * Length temp(*this);
577 * *this = other;
578 * other = temp;
579 * @endcode
580 *
581 * @param other Length object to swap
582 */
583 void swap(Length& other);
584
585 /**
586 * Current length value
587 *
588 * Equivalent to:
589 * @code
590 * As (Length::Unit::Meter).Value ()
591 * @endcode
592 * @return The current value, in meters
593 */
594 double GetDouble() const;
595
596 /**
597 * Create a Quantity in a specific unit from a Length
598 *
599 * Converts the current length value to the equivalent value specified by
600 * \p unit and returns a Quantity object with the converted value and unit
601 *
602 * @param unit The desired unit of the returned Quantity
603 *
604 * @return A quantity representing the length in the requested unit
605 */
606 Quantity As(Unit unit) const;
607
608 private:
609 double m_value; //!< Length in meters
610
611 // end of class Length
612};
613
615
616/**
617 * @ingroup length
618 * @brief Return the symbol of the supplied unit
619 *
620 * The symbol of the unit is the shortened form of the unit name and is usually
621 * two or three characters long
622 *
623 * @param unit The unit to symbolize
624 *
625 * @return String containing the symbol of \p unit
626 */
627std::string ToSymbol(Length::Unit unit);
628
629/**
630 * @ingroup length
631 * @brief Return the name of the supplied unit
632 *
633 * The value returned by this function is the common name of \p unit. The output
634 * is always lowercase.
635 *
636 * If \p plural is true, then the plural form of the common name is returned
637 * instead.
638 *
639 * @param unit The unit to name
640 * @param plural Boolean indicating if the returned string should contain the
641 * plural form of the name
642 *
643 * @return String containing the full name of \p unit
644 */
645std::string ToName(Length::Unit unit, bool plural = false);
646
647/**
648 * @ingroup length
649 * @brief Find the equivalent Length::Unit for a unit string
650 *
651 * The string value can be a symbol or name (plural or singular).
652 *
653 * The string comparison ignores case so strings like "NanoMeter", "centiMeter",
654 * "METER" will all match the correct unit.
655 *
656 * Leading and trailing whitespace are trimmed from the string before searching
657 * for a match.
658 *
659 * @param unitString String containing the symbol or name of a length unit
660 *
661 * @return A std::optional object containing a Length::Unit if a match for the
662 * string could be found
663 */
664std::optional<Length::Unit> FromString(std::string unitString);
665
666/**
667 * @ingroup length
668 * @brief Write a length value to an output stream.
669 *
670 * The output of the length is in meters.
671 *
672 * Equivalent to:
673 * @code
674 * stream << l.As (Meter);
675 * @endcode
676 *
677 * @param stream Output stream
678 * @param l Length value to write to the stream
679 *
680 * @return Reference to the output stream
681 */
682std::ostream& operator<<(std::ostream& stream, const Length& l);
683
684/**
685 * @ingroup length
686 * @brief Write a Quantity to an output stream.
687 *
688 * The data written to the output stream will have the format <value> <symbol>
689 *
690 * Equivalent to:
691 * @code
692 * stream << q.Value () << ' ' << ToSymbol (q.Unit());
693 * @endcode
694 *
695 * @param stream Output stream
696 * @param q Quantity to write to the output stream
697 *
698 * @return Reference to the output stream
699 */
700std::ostream& operator<<(std::ostream& stream, const Length::Quantity& q);
701
702/**
703 * @ingroup length
704 * @brief Write a Length::Unit to an output stream.
705 *
706 * Writes the name of \p unit to the output stream
707 *
708 * Equivalent to:
709 * @code
710 * stream << ToName (unit);
711 * @endcode
712 *
713 * @param stream Output stream
714 * @param unit Length unit to output
715 *
716 * @return Reference to the output stream
717 */
718std::ostream& operator<<(std::ostream& stream, Length::Unit unit);
719
720/**
721 * @ingroup length
722 * @brief Read a length value from an input stream.
723 *
724 * The expected format of the input is <number> <unit>
725 * or <number><unit>
726 * This function calls NS_ABORT if the input stream does not contain
727 * a valid length string
728 *
729 * @param stream Input stream
730 * @param l Object where the deserialized value will be stored
731 *
732 * @return Reference to the input stream
733 */
734std::istream& operator>>(std::istream& stream, Length& l);
735
736/**
737 * @ingroup length
738 * @brief Compare two length objects for equality.
739 *
740 * Equivalent to:
741 * @code
742 * left.IsEqual(right, 0);
743 * @endcode
744 *
745 * @param left Left length object
746 * @param right Right length object
747 *
748 * @return true if \p left and \p right have the same value
749 */
750bool operator==(const Length& left, const Length& right);
751
752/**
753 * @ingroup length
754 * @brief Compare two length objects for inequality.
755 *
756 * Equivalent to:
757 * @code
758 * left.IsNotEqual(right, 0);
759 * @endcode
760 *
761 * @param left Left length object
762 * @param right Right length object
763 *
764 * @return true if \p left and \p right do not have the same value
765 */
766bool operator!=(const Length& left, const Length& right);
767
768/**
769 * @ingroup length
770 * @brief Check if \p left has a value less than \p right
771 *
772 * Equivalent to:
773 * @code
774 * left.IsLess(right, 0);
775 * @endcode
776 *
777 * @param left Left length object
778 * @param right Right length object
779 *
780 * @return true if \p left is less than \p right
781 */
782bool operator<(const Length& left, const Length& right);
783
784/**
785 * @ingroup length
786 * @brief Check if \p left has a value less than or equal to \p right
787 *
788 * Equivalent to:
789 * @code
790 * left.IsLessOrEqual(right, 0);
791 * @endcode
792 *
793 * @param left Left length object
794 * @param right Right length object
795 *
796 * @return true if \p left is less than or equal to \p right
797 */
798bool operator<=(const Length& left, const Length& right);
799
800/**
801 * @ingroup length
802 * @brief Check if \p left has a value greater than \p right
803 *
804 * Equivalent to:
805 * @code
806 * left.IsGreater(right, 0);
807 * @endcode
808 *
809 * @param left Left length object
810 * @param right Right length object
811 *
812 * @return true if \p left is greater than \p right
813 */
814bool operator>(const Length& left, const Length& right);
815
816/**
817 * @ingroup length
818 * @brief Check if \p left has a value greater than or equal to \p right
819 *
820 * Equivalent to:
821 * @code
822 * left.IsGreaterOrEqual(right, 0);
823 * @endcode
824 *
825 * @param left Left length object
826 * @param right Right length object
827 *
828 * @return true if \p left is greater than or equal to \p right
829 */
830bool operator>=(const Length& left, const Length& right);
831
832/**
833 * @ingroup length
834 * @brief Add two length values together.
835 *
836 * Adds the values of \p left to \p right and returns a new
837 * Length object containing the result.
838 *
839 * @param left A Length object
840 * @param right A Length object
841 *
842 * @return A newly constructed Length object containing the
843 * result of `left + right`.
844 */
845Length operator+(const Length& left, const Length& right);
846
847/**
848 * @ingroup length
849 * @brief Subtract two length values.
850 *
851 * Subtracts the value of \p right from \p left and returns a
852 * new Length object containing the result.
853 *
854 * @param left A Length object
855 * @param right A Length object
856 *
857 * @return A newly constructed Length object containing the
858 * result of `left - right`.
859 */
860Length operator-(const Length& left, const Length& right);
861
862/**
863 * @ingroup length
864 * @brief Multiply a length value by a scalar
865 *
866 * Multiplies the value \p l by \p scalar and returns a new
867 * Length object containing the result.
868 *
869 * @param l The Length object
870 * @param scalar Multiplication factor
871 *
872 * @return A newly constructed Length object containing the result
873 * of `l * scalar`.
874 */
875Length operator*(double scalar, const Length& l);
876/**
877 * @ingroup length
878 * @brief Multiply a length value by a scalar
879 *
880 * Multiplies the value \p l by \p scalar and returns a new
881 * Length object containing the result.
882 *
883 * @param l The Length object
884 * @param scalar Multiplication factor
885 *
886 * @return A newly constructed Length object containing the result
887 * of `l * scalar`.
888 */
889Length operator*(const Length& l, double scalar);
890
891/**
892 * @ingroup length
893 * @brief Divide a length value by a scalar
894 *
895 * Divides the value \p left by \p scalar and returns a new
896 * Length object containing the result.
897 *
898 * \p scalar must contain a non zero value.
899 * NS_FATAL_ERROR is called if \p scalar is zero
900 *
901 * @param left Length value
902 * @param scalar Multiplication factor
903 *
904 * @return A newly constructed Length object containing the result
905 * of `left / scalar`.
906 */
907Length operator/(const Length& left, double scalar);
908
909/**
910 * @ingroup length
911 * @brief Divide a length value by another length value
912 *
913 * Divides the value \p numerator by the value \p denominator and
914 * returns a scalar value containing the result.
915 *
916 * The return value will be NaN if \p denominator is 0.
917 *
918 * @param numerator The top value of the division
919 * @param denominator The bottom value of the division
920 *
921 * @return A scalar value that is the result of `numerator / denominator` or
922 * NaN if \p denominator is 0.
923 */
924double operator/(const Length& numerator, const Length& denominator);
925
926/**
927 * @ingroup length
928 * @brief Calculate how many times \p numerator can be split into \p denominator
929 * sized pieces.
930 *
931 * If the result of `numerator / denominator` is not a whole number, the
932 * result is rounded toward zero to the nearest whole number.
933 * The amount remaining after the division can be retrieved by passing a pointer
934 * to a Length in \p remainder. The remainder will be less than \p denominator
935 * and have the same sign as \p numerator.
936 *
937 * NS_FATAL_ERROR is called if \p denominator is 0.
938 *
939 * @param numerator The value to split
940 * @param denominator The length of each split
941 * @param remainder Location to store the remainder
942 *
943 * @return The number of times \p numerator can be split into \p denominator
944 * sized pieces, rounded down to the nearest whole number
945 */
946int64_t Div(const Length& numerator, const Length& denominator, Length* remainder = nullptr);
947
948/**
949 * @ingroup length
950 * @brief Calculate the amount remaining after dividing two lengths
951 *
952 * The returned value will be less than \p denominator and have the same sign as
953 * \p numerator.
954 *
955 * NS_FATAL_ERROR is called if \p denominator is 0.
956 *
957 * @param numerator The value to split
958 * @param denominator The length of each split
959 *
960 * @return The amount remaining after splitting \p numerator into \p denominator
961 * sized pieces.
962 */
963Length Mod(const Length& numerator, const Length& denominator);
964
965/**
966 * Construct a length from a value in the indicated unit.
967 * @{
968 * @ingroup length
969 * @param value The numerical value.
970 * @returns Length object.
971 */
972Length NanoMeters(double value);
973Length MicroMeters(double value);
974Length MilliMeters(double value);
975Length CentiMeters(double value);
976Length Meters(double value);
977Length KiloMeters(double value);
978Length NauticalMiles(double value);
979Length Inches(double value);
980Length Feet(double value);
981Length Yards(double value);
982Length Miles(double value);
983/**@}*/
984
985#ifdef HAVE_BOOST_UNITS
986template <class U, class T>
987Length::Length(boost::units::quantity<U, T> quantity)
988 : m_value(0)
989{
990 namespace bu = boost::units;
991 using BoostMeters = bu::quantity<bu::si::length, double>;
992
993 // convert value to meters
994 m_value = static_cast<BoostMeters>(quantity).value();
995}
996#endif
997
998} // namespace ns3
999
1000#endif /* NS3_LENGTH_H_ */
Attribute helper (ATTRIBUTE_ )macros definition.
ns3::AttributeValue, ns3::AttributeAccessor and ns3::AttributeChecker declarations.
An immutable class which represents a value in a specific length unit.
Definition length.h:261
Quantity & operator=(Quantity &&other)=default
Move Assignment Operator.
double m_value
Value of the length.
Definition length.h:325
Quantity(double value, Length::Unit unit)
Constructor.
Definition length.h:269
Quantity & operator=(const Quantity &other)=default
Copy Assignment Operator.
~Quantity()=default
Destructor.
double Value() const
The value of the quantity.
Definition length.h:309
Length::Unit Unit() const
The unit of the quantity.
Definition length.h:319
Quantity(const Quantity &)=default
Copy Constructor.
Length::Unit m_unit
unit of length of the value
Definition length.h:326
Quantity(Quantity &&)=default
Move Constructor.
Represents a length in meters.
Definition length.h:233
void swap(Length &other)
Swap values with another object.
Definition length.cc:362
static constexpr double DEFAULT_TOLERANCE
Default tolerance value used for the member comparison functions (IsEqual, IsLess,...
Definition length.h:336
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:354
double GetDouble() const
Current length value.
Definition length.cc:370
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:346
double m_value
Length in meters.
Definition length.h:609
Length & operator=(Length &&other)=default
Move Assignment operator.
Length(const Length &other)=default
Copy Constructor.
bool IsEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is equal in value to this instance.
Definition length.cc:307
Quantity As(Unit unit) const
Create a Quantity in a specific unit from a Length.
Definition length.cc:376
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:338
Length(Length &&other)=default
Move Constructor.
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:233
~Length()=default
Destructor.
Unit
Units of length in various measurement systems that are supported by the Length class.
Definition length.h:240
@ NauticalMile
1,852 meters
Definition length.h:248
@ Micrometer
1e-6 meters
Definition length.h:243
@ Foot
Base length unit in US customary system.
Definition length.h:252
@ Inch
1/12 of a foot
Definition length.h:251
@ Centimeter
1e-2 meters
Definition length.h:245
@ Mile
5,280 feet
Definition length.h:254
@ Kilometer
1e3 meters
Definition length.h:247
@ Meter
Base length unit in metric system.
Definition length.h:246
@ Yard
3 feet
Definition length.h:253
@ Nanometer
1e-9 meters
Definition length.h:242
@ Millimeter
1e-3 meters
Definition length.h:244
Length()
Default Constructor.
Definition length.cc:247
bool IsLess(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is greater in value than this instance.
Definition length.cc:330
bool IsNotEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is not equal in value to this instance.
Definition length.cc:322
#define ATTRIBUTE_HELPER_HEADER(type)
Declare the attribute value, accessor and checkers for class type
int64x64_t operator/(const int64x64_t &lhs, const int64x64_t &rhs)
Division operator.
Definition int64x64.h:121
bool operator>=(const int64x64_t &lhs, const int64x64_t &rhs)
Greater or equal operator.
Definition int64x64.h:162
bool operator<=(const int64x64_t &lhs, const int64x64_t &rhs)
Less or equal operator.
Definition int64x64.h:149
int64x64_t operator-(const int64x64_t &lhs, const int64x64_t &rhs)
Subtraction operator.
Definition int64x64.h:91
int64x64_t operator+(const int64x64_t &lhs, const int64x64_t &rhs)
Addition operator.
Definition int64x64.h:76
int64x64_t operator*(const int64x64_t &lhs, const int64x64_t &rhs)
Multiplication operator.
Definition int64x64.h:106
Length KiloMeters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:806
Length MilliMeters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:788
Length NauticalMiles(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:812
std::string ToName(Length::Unit unit, bool plural)
Return the name of the supplied unit.
Definition length.cc:533
bool operator>(const Length &left, const Length &right)
Check if left has a value greater than right.
Definition length.cc:410
Length Yards(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:830
Length Feet(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:824
Length Mod(const Length &numerator, const Length &denominator)
Calculate the amount remaining after dividing two lengths.
Definition length.cc:490
Length MicroMeters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:782
Length Miles(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:836
Length Meters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:800
std::string ToSymbol(Length::Unit unit)
Return the symbol of the supplied unit.
Definition length.cc:503
Length CentiMeters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:794
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:471
Length NanoMeters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:776
Length Inches(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:818
std::optional< Length::Unit > FromString(std::string unitString)
Find the equivalent Length::Unit for a unit string.
Definition length.cc:569
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:658
bool operator==(const EventId &a, const EventId &b)
Definition event-id.h:155
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
std::istream & operator>>(std::istream &is, Angles &a)
Definition angles.cc:172
bool operator<(const EventId &a, const EventId &b)
Definition event-id.h:168