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