1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2019 Lawrence Livermore National Laboratory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Mathew Bielejeski <bielejeski1@llnl.gov>
19 */
20
21 #ifndef NS3_LENGTH_H_
22 #define NS3_LENGTH_H_
23
24 #include "attribute.h"
25 #include "attribute-helper.h"
26
27 #ifdef HAVE_BOOST
28 #include <boost/units/quantity.hpp>
29 #include <boost/units/systems/si.hpp>
30 #endif
31
32 #include <istream>
33 #include <limits>
34 #include <ostream>
35 #include <string>
36 #include <tuple>
37
38 /**
39 * \file
40 * \ingroup length
41 * Declaration of ns3::Length class
42 */
43
44 /**
45 * ns3 namespace
46 */
47 namespace ns3 {
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 contructors 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 quantitiy
150 boost::units::quantity<boost::units::si::length> q = 5 * boost::units::si::meter;
151 Length meters (q);
152 \endcode
153 *
154 * ## Arithmetic Operations ##
155 *
156 * The following arithmetic operations are supported:
157 *
158 * ### Addition ###
159 *
160 * Addition is between two Length instances
161 *
162 * \code
163 std::cout << Length(1, Length::Unit::Meter) + Length (2, Length::Unit::Meter); // output: "3 m"
164 \endcode
165 *
166 * ### Subtraction ###
167 *
168 * Subtraction is between two Length instances
169 *
170 * \code
171 std::cout << Length(3, Length::Unit::Meter) - Length (2, Length::Unit::Meter); // output: "1 m"
172 \endcode
173 *
174 * ### Multiplication ###
175 *
176 * Multiplication is only supported between a Length and a unitless scalar value
177 *
178 * \code
179 std::cout << Length(1, Length::Unit::Meter) * 5; // output: "5 m"
180
181 std::cout << 5 * Length (1, Length::Unit::Meter); // output: "5 m"
182 \endcode
183 *
184 *
185 * ### Division ###
186 *
187 * Division can be between a Length and a scalar or two Length objects.
188 *
189 * Division between a Length and a scalar returns a new Length.
190 *
191 * Division between two Length objects returns a unitless value.
192 *
193 * \code
194 std::cout << Length(5, Length::Unit::Meter) / 5; // output: "1 m"
195
196 std::cout << Length (5, Length::Unit::Meter) / Length (5, Length::Unit::Meter); // output: 1
197 \endcode
198 *
199 * ## Comparison Operations ##
200 *
201 * All the usual arithmetic comparison operations (=, !=, <, <=, >, >=) are supported.
202 * There are two forms of comparison operators: free function and member function.
203 * The free functions define =, !=, <, <=, >, >= and perform exact comparisons of
204 * the underlying double values. The Length class provides comparison
205 * operator functions (IsEqual, IsLess, IsGreater, etc.) which accept an
206 * additional tolerance value to control how much the underlying double values
207 * must match when performing the comparison.
208 *
209 * \code
210 //check for exact match
211 Length l (5, Length::Unit::Meter);
212
213 bool match = (l == l); // match is true
214
215 Length v1 (0.02, Length::Unit::Meter);
216 Length v2 (0.022, Length::Unit::Meter);
217
218 match = (v1 == v2); // match is false
219
220 double tolerance = 0.01;
221 bool mostly_match = v1.IsEqual (v2, tolerance); // mostly_match is true
222 \endcode
223 *
224 * ## Serialization ##
225 *
226 * The Length class supports serialization using the << and >> operators.
227 * By default the output serialization is in meters. Use Length::As to output
228 * the Length value in a different unit.
229 *
230 * \code
231 Length m(5, Length::Unit::Meter);
232
233 //output: 5 m, 0.005 km, 16.4042 ft
234 std::cout << m << ", " << m.As(Length::Unit::Kilometer) << ", " << m.As(Length::Unit::Foot);
235 \endcode
236 *
237 */
238 class Length
239 {
240 public:
241 /**
242 * Units of length in various measurement systems that are supported by the
243 * Length class
244 */
245 enum Unit : uint16_t
246 {
247 //Metric Units
248 Nanometer = 1, //!< 1e<sup>-9</sup> meters
249 Micrometer, //!< 1e<sup>-6</sup> meters
250 Millimeter, //!< 1e<sup>-3</sup> meters
251 Centimeter, //!< 1e<sup>-2</sup> meters
252 Meter, //!< Base length unit in metric system
253 Kilometer, //!< 1e<sup>3</sup> meters
254 NauticalMile, //!< 1,852 meters
255
256 //US Customary Units
257 Inch, //!< 1/12 of a foot
258 Foot, //!< Base length unit in US customary system
259 Yard, //!< 3 feet
260 Mile //!< 5,280 feet
261 };
262
263 /**
264 * An immutable class which represents a value in a specific length unit
265 */
266 class Quantity
267 {
268 public:
269 /**
270 * Constructor
271 *
272 * \param value Length value
273 * \param unit Length unit of the value
274 */
Quantity(double value,Length::Unit unit)275 Quantity (double value, Length::Unit unit)
276 : m_value (value),
277 m_unit (unit)
278 { }
279
280 /**
281 * Copy Constructor
282 */
283 Quantity (const Quantity&) = default;
284
285 /**
286 * Move Constructor
287 */
288 Quantity (Quantity&&) = default;
289
290 /**
291 * Destructor
292 */
293 ~Quantity () = default;
294
295 /**
296 * Copy Assignment Operator
297 */
298 Quantity& operator= (const Quantity&) = default;
299
300 /**
301 * Move Assignment Operator
302 */
303 Quantity& operator= (Quantity&&) = default;
304
305 /**
306 * The value of the quantity
307 *
308 * \return The value of this quantity
309 */
Value()310 double Value () const
311 {
312 return m_value;
313 }
314
315 /**
316 * The unit of the quantity
317 *
318 * \return The unit of this quantity
319 */
Unit()320 Length::Unit Unit () const
321 {
322 return m_unit;
323 }
324
325 private:
326 double m_value; //!< Value of the length
327 Length::Unit m_unit; //!< unit of length of the value
328 };
329
330 /**
331 * Default tolerance value used for the member comparison functions (IsEqual,
332 * IsLess, etc.)
333 *
334 * The default tolerance is set to epsilon which is defined as the difference
335 * between 1.0 and the next value that can be represented by a double.
336 */
337 static constexpr double DEFAULT_TOLERANCE = std::numeric_limits<double>::epsilon ();
338
339 /**
340 * Attempt to construct a Length object from a value and a unit string
341 *
342 * \p unit can either be the full name of the unit (meter, kilometer, mile, etc.)
343 * or the symbol of the unit (m, km, mi, etc.)
344 *
345 * This function will return false if \p unit does not map to a known type.
346 *
347 * \param value Numeric value of the new length
348 * \param unit Unit that the value represents
349 *
350 * \return A tuple containing the success or failure of the parsing and a Length
351 * object. If the boolean element is true, then the Length element contains the
352 * parsed result. If the boolean element is false, the value of the Length
353 * element is undefined.
354 */
355 static std::tuple<bool, Length> TryParse (double value, const std::string& unit);
356
357 /**
358 * Default Constructor
359 *
360 * Initialize with a value of 0 meters.
361 */
362 Length ();
363
364 /**
365 * String Constructor
366 *
367 * Parses \p text and initializes the value with the parsed result.
368 *
369 * The expected format of \p text is \<number\> \<unit\> or \<number\>\<unit\>
370 *
371 * \param text Serialized length value
372 */
373 Length (const std::string& text);
374
375 /**
376 * Construct a Length object from a value and a unit string
377 *
378 * \p unit can either be the full name of the unit (meter, kilometer, mile, etc.)
379 * or the symbol of the unit (m, km, mi, etc.)
380 *
381 * \warning NS_FATAL_ERROR is called if \p unit is not a valid unit string.
382 * \warning Use Length::TryParse to parse potentially bad values without terminating.
383 *
384 * \param value Numeric value of the new length
385 * \param unit Unit that the value represents
386 */
387 Length (double value, const std::string& unit);
388
389 /**
390 * Construct a Length object from a value and a unit
391 *
392 * \warning NS_FATAL_ERROR is called if \p unit is not valid.
393 * \warning Use Length::TryParse to parse potentially bad values without terminating.
394 *
395 * \param value Numeric value of the new length
396 * \param unit Length unit of the value
397 */
398 Length (double value, Length::Unit unit);
399
400 /**
401 * Construct a Length object from a Quantity
402 *
403 * \param quantity Quantity representing a length value and unit
404 */
405 Length (Quantity quantity);
406
407 #ifdef HAVE_BOOST_UNITS
408 /**
409 * Construct a Length object from a boost::units::quantity
410 *
411 * \note The boost::units:quantity must contain a unit that derives from
412 * the length dimension. Passing a quantity with a Unit that is not a length
413 * unit will result in a compile time error
414 *
415 * \tparam U A boost::units length unit
416 * \tparam T Numeric data type of the quantity value
417 *
418 * \param quantity A boost::units length quantity
419 */
420 template <class U, class T>
421 explicit Length (boost::units::quantity<U, T> quantity);
422 #endif
423
424 /**
425 * Copy Constructor
426 *
427 * Initialize an object with the value from \p other.
428 *
429 * \param other Length object to copy
430 */
431 Length (const Length& other) = default;
432
433 /**
434 * Move Constructor
435 *
436 * Initialize an object with the value from \p other.
437 *
438 * After the move completes, \p other is left in an undefined but
439 * useable state.
440 *
441 * \param other Length object to move
442 */
443 Length (Length&& other) = default;
444
445 /**
446 * Destructor
447 */
448 ~Length () = default;
449
450 /**
451 * Copy Assignment operator
452 *
453 * Replace the current value with the value from \p other
454 *
455 * \param other Length object to copy
456 *
457 * \return Reference to the updated object
458 */
459 Length& operator= (const Length& other) = default;
460
461 /**
462 * Move Assignment operator
463 *
464 * Replace the current value with the value from \p other
465 * After the move, \p other is left in an undefined but valid state
466 *
467 * \param other Length object to move
468 *
469 * \return Reference to the updated object
470 */
471 Length& operator= (Length&& other) = default;
472
473 /**
474 * Assignment operator
475 *
476 * Replace the current value with the value from \p q
477 *
478 * \param q Quantity holding the value to assign
479 *
480 * \return Reference to the updated object
481 */
482 Length& operator= (const Length::Quantity& q);
483
484 /**
485 * Check if \p other is equal in value to this instance.
486 *
487 * \param other Value to compare against
488 * \param tolerance Smallest difference allowed between the two
489 * values to still be considered equal
490 *
491 * \return true if the absolute difference between lengths
492 * is less than or equal to \p tolerance
493 */
494 bool IsEqual (const Length& other, double tolerance = DEFAULT_TOLERANCE) const;
495
496 /**
497 * Check if \p other is not equal in value to this instance.
498 *
499 * \param other Value to compare against
500 * \param tolerance Smallest difference allowed between the two
501 * values to still be considered equal
502 *
503 * \return true if the absolute difference between lengths
504 * is greater than \p tolerance
505 */
506 bool IsNotEqual (const Length& other, double tolerance = DEFAULT_TOLERANCE) const;
507
508 /**
509 * Check if \p other is greater in value than this instance.
510 *
511 * \param other Value to compare against
512 * \param tolerance Smallest difference allowed between the two
513 * values to still be considered equal
514 *
515 * \return true if the values are not equal and \p other is
516 * greater in value
517 */
518 bool IsLess (const Length& other, double tolerance = DEFAULT_TOLERANCE) const;
519
520 /**
521 * Check if \p other is greater or equal in value than this instance.
522 *
523 * \param other Value to compare against
524 * \param tolerance Smallest difference allowed between the two
525 * values to still be considered equal
526 *
527 * Equivalent to:
528 \code
529 IsEqual(other, tolerance) || IsLess(other, tolerance)
530 \endcode
531 *
532 * \return true if the values are equal or \p other is
533 * greater in value
534 */
535 bool IsLessOrEqual (const Length& other, double tolerance = DEFAULT_TOLERANCE) const;
536
537 /**
538 * Check if \p other is less in value than this instance.
539 *
540 * \param other Value to compare against
541 * \param tolerance Smallest difference allowed between the two
542 * values to still be considered equal
543 *
544 * Equivalent to:
545 \code
546 !(IsLessOrEqual(other, tolerance))
547 \endcode
548 *
549 * \return true if the values are not equal and \p other is
550 * less in value
551 */
552 bool IsGreater (const Length& other, double tolerance = DEFAULT_TOLERANCE) const;
553
554 /**
555 * Check if \p other is equal or less in value than this instance.
556 *
557 * \param other Value to compare against
558 * \param tolerance Smallest difference allowed between the two
559 * values to still be considered equal
560 *
561 * Equivalent to:
562 \code
563 !IsLess(other, tolerance)
564 \endcode
565 *
566 * \return true if the values are equal or \p other is
567 * less in value
568 */
569 bool IsGreaterOrEqual (const Length& other, double tolerance = DEFAULT_TOLERANCE) const;
570
571 /**
572 * Swap values with another object
573 *
574 * Swap the current value with the value in \p other.
575 *
576 * Equivalent to:
577 \code
578 Length temp(*this);
579 *this = other;
580 other = temp;
581 \endcode
582 *
583 * \param other Length object to swap
584 */
585 void swap (Length& other);
586
587 /**
588 * Current length value
589 *
590 * Equivalent to:
591 \code
592 As (Length::Unit::Meter).Value ()
593 \endcode
594 * \return The current value, in meters
595 */
596 double GetDouble () const;
597
598 /**
599 * Create a Quantity in a specific unit from a Length
600 *
601 * Converts the current length value to the equivalent value specified by
602 * \p unit and returns a Quantity object with the converted value and unit
603 *
604 * \param unit The desired unit of the returned Quantity
605 *
606 * \return A quantity representing the length in the requested unit
607 */
608 Quantity As (Unit unit) const;
609
610 private:
611 double m_value; //!< Length in meters
612 }; // class Length
613
614 /**
615 * Define LengthValue class to support using Length objects as attributes
616 */
617 ATTRIBUTE_HELPER_HEADER (Length);
618
619 /**
620 * \relates Length
621 * \brief Return the symbol of the supplied unit
622 *
623 * The symbol of the unit is the shortened form of the unit name and is usually
624 * two or three characters long
625 *
626 * \param unit The unit to symbolize
627 *
628 * \return String containing the symbol of \p unit
629 */
630 std::string ToSymbol (Length::Unit unit);
631
632 /**
633 * \relates Length
634 * \brief Return the name of the supplied unit
635 *
636 * The value returned by this function is the common name of \p unit. The output
637 * is always lowercase.
638 *
639 * If \p plural is true, then the plural form of the common name is returned
640 * instead.
641 *
642 * \param unit The unit to name
643 * \param plural Boolean indicating if the returned string should contain the
644 * plural form of the name
645 *
646 * \return String containing the full name of \p unit
647 */
648 std::string ToName (Length::Unit unit, bool plural = false);
649
650 /**
651 * \relates Length
652 * \brief Find the equivalent Length::Unit for a unit string
653 *
654 * The string value can be a symbol or name (plural or singular).
655 *
656 * The string comparison ignores case so strings like "NanoMeter", "centiMeter",
657 * "METER" will all match the correct unit.
658 *
659 * Leading and trailing whitespace are trimmed from the string before searching
660 * for a match.
661 *
662 * \param unitString String containing the symbol or name of a length unit
663 *
664 * \return A tuple containing a boolean and a Length::Unit. When the boolean
665 * is true, the Length::Unit contains a valid value. When the boolean is false,
666 * a match for the string could not be found and the Length::Unit value is
667 * undefined
668 */
669 std::tuple<bool, Length::Unit> FromString (std::string unitString);
670
671 /**
672 * \relates Length
673 * \brief Write a length value to an output stream.
674 *
675 * The output of the length is in meters.
676 *
677 * Equivalent to:
678 * \code
679 * stream << l.As (Meter);
680 * \endcode
681 *
682 * \param stream Output stream
683 * \param l Length value to write to the stream
684 *
685 * \return Reference to the output stream
686 */
687 std::ostream& operator<< (std::ostream& stream, const Length& l);
688
689 /**
690 * \relates Length
691 * \brief Write a Quantity to an output stream.
692 *
693 * The data written to the output stream will have the format \<value\> \<symbol\>
694 *
695 * Equivalent to:
696 * \code
697 stream << q.Value () << ' ' << ToSymbol (q.Unit());
698 \endcode
699 *
700 * \param stream Output stream
701 * \param q Quantity to write to the output stream
702 *
703 * \return Reference to the output stream
704 */
705 std::ostream& operator<< (std::ostream& stream, const Length::Quantity& q);
706
707 /**
708 * \relates Length
709 * \brief Write a Length::Unit to an output stream.
710 *
711 * Writes the name of \p unit to the output stream
712 *
713 * Equivalent to:
714 * \code
715 stream << ToName (unit);
716 \endcode
717 *
718 * \param stream Output stream
719 * \param unit Length unit to output
720 *
721 * \return Reference to the output stream
722 */
723 std::ostream& operator<< (std::ostream& stream, Length::Unit unit);
724
725 /**
726 * \relates Length
727 * \brief Read a length value from an input stream.
728 *
729 * The expected format of the input is \<number\> \<unit\>
730 * or \<number\>\<unit\>
731 * This function calls NS_ABORT if the input stream does not contain
732 * a valid length string
733 *
734 * \param stream Input stream
735 * \param l Object where the deserialized value will be stored
736 *
737 * \return Reference to the input stream
738 */
739 std::istream& operator>> (std::istream& stream, Length& l);
740
741 /**
742 * \relates Length
743 * \brief Compare two length objects for equality.
744 *
745 * Equivalent to:
746 * \code
747 * left.IsEqual(right, 0);
748 * \endcode
749 *
750 * \param left Left length object
751 * \param right Right length object
752 *
753 * \return true if \p l and \p r have the same value
754 */
755 bool operator== (const Length& left, const Length& right);
756
757 /**
758 * \relates Length
759 * \brief Compare two length objects for inequality.
760 *
761 * Equivalent to:
762 * \code
763 * l.IsNotEqual(r, 0);
764 * \endcode
765 *
766 * \param l Left length object
767 * \param r Right length object
768 *
769 * \return true if \p l and \p r do not have the same value
770 */
771 bool operator!= (const Length& l, const Length& r);
772
773 /**
774 * \relates Length
775 * \brief Check if \p l has a value less than \p r
776 *
777 * Equivalent to:
778 * \code
779 * l.IsLess(r, 0);
780 * \endcode
781 *
782 * \param l Left length object
783 * \param r Right length object
784 *
785 * \return true if \p l is less than \p r
786 */
787 bool operator< (const Length& l, const Length& r);
788
789 /**
790 * \relates Length
791 * \brief Check if \p l has a value less than or equal to \p r
792 *
793 * Equivalent to:
794 * \code
795 * l.IsLessOrEqual(r, 0);
796 * \endcode
797 *
798 * \param l Left length object
799 * \param r Right length object
800 *
801 * \return true if \p l is less than or equal to \p r
802 */
803 bool operator<= (const Length& l, const Length& r);
804
805 /**
806 * \relates Length
807 * \brief Check if \p l has a value greater than \p r
808 *
809 * Equivalent to:
810 * \code
811 * l.IsGreater(r, 0);
812 * \endcode
813 *
814 * \param l Left length object
815 * \param r Right length object
816 *
817 * \return true if \p l is greater than \p r
818 */
819 bool operator> (const Length& l, const Length& r);
820
821 /**
822 * \relates Length
823 * \brief Check if \p l has a value greater than or equal to \p r
824 *
825 * Equivalent to:
826 * \code
827 * l.IsGreaterOrEqual(r, 0);
828 * \endcode
829 *
830 * \param l Left length object
831 * \param r Right length object
832 *
833 * \return true if \p l is greater than or equal to \p r
834 */
835 bool operator>= (const Length& l, const Length& r);
836
837 /**
838 * \relates Length
839 * \brief Add two length values together.
840 *
841 * Adds the values of \p first to \p second and returns a new
842 * Length object containing the result.
843 *
844 * \param first A Length object
845 * \param second A Length object
846 *
847 * \return A newly constructed Length object containing the
848 * result of first + second
849 */
850 Length operator+ (const Length& first, const Length& second);
851
852 /**
853 * \relates Length
854 * \brief Subtract two length values.
855 *
856 * Subtracts the value of \p second from \p first and returns a
857 * new Length object containing the result.
858 *
859 * \param first A Length object
860 * \param second A Length object
861 *
862 * \return A newly constructed Length object containing the
863 * result of first - second
864 */
865 Length operator- (const Length& first, const Length& second);
866
867 /**
868 * \relates Length
869 * \brief Multiply a length value by a scalar
870 *
871 * Multiplies the value \p right by \p scalar and returns a new
872 * Length object containing the result.
873 *
874 * \param scalar Multiplication factor
875 * \param right Length value
876 *
877 * \return A newly constructed Length object containing the result
878 * of right * scalar.
879 */
880 Length operator* (double scalar, const Length& right);
881
882 /**
883 * \relates Length
884 * \brief Multiply a length value by a scalar
885 *
886 * Multiplies the value \p left by \p scalar and returns a new
887 * Length object containing the result.
888 *
889 * \param left Length value
890 * \param scalar Multiplication factor
891 *
892 * \return A newly constructed Length object containing the result
893 * of left * scalar.
894 */
895 Length operator* (const Length& left, double scalar);
896
897 /**
898 * \relates Length
899 * \brief Divide a length value by a scalar
900 *
901 * Divides the value \p left by \p scalar and returns a new
902 * Length object containing the result.
903 *
904 * \p scalar must contain a non zero value.
905 * NS_FATAL_ERROR is called if \p scalar is zero
906 *
907 * \param left Length value
908 * \param scalar Multiplication factor
909 *
910 * \return A newly constructed Length object containing the result
911 * of left / scalar.
912 */
913 Length operator/ (const Length& left, double scalar);
914
915 /**
916 * \relates Length
917 * \brief Divide a length value by another length value
918 *
919 * Divides the value \p numerator by the value \p denominator and
920 * returns a scalar value containing the result.
921 *
922 * The return value will be NaN if \p denominator is 0.
923 *
924 * \param numerator The top value of the division
925 * \param denominator The bottom value of the division
926 *
927 * \return A scalar value that is the result of numerator / denominator or
928 * NaN if \p denominator is 0
929 */
930 double operator/ (const Length& numerator, const Length& denominator);
931
932 /**
933 * \relates Length
934 * \brief Calculate how many times \p numerator can be split into \p denominator
935 * sized pieces.
936 *
937 * If the result of \p numerator / \p denominator is not a whole number, the
938 * result is rounded toward zero to the nearest whole number.
939 * The amount remaining after the division can be retrieved by passing a pointer
940 * to a Length in \p remainder. The remainder will be less than \p denominator
941 * and have the same sign as \p numerator.
942 *
943 * NS_FATAL_ERROR is called if \p denominator is 0.
944 *
945 * \param numerator The value to split
946 * \param denominator The length of each split
947 * \param remainder Location to store the remainder
948 *
949 * \return The number of times \p numerator can be split into \p denominator
950 * sized pieces, rounded down to the nearest whole number
951 */
952 int64_t Div (const Length& numerator, const Length& denominator, Length* remainder = nullptr);
953
954 /**
955 * \relates Length
956 * \brief Calculate the amount remaining after dividing two lengths
957 *
958 * The returned value will be less than \p denominator and have the same sign as
959 * \p numerator.
960 *
961 * NS_FATAL_ERROR is called if \p denominator is 0.
962 *
963 * \param numerator The value to split
964 * \param denominator The length of each split
965 *
966 * \return The amount remaining after splitting \p numerator into \p denominator
967 * sized pieces.
968 */
969 Length Mod (const Length& numerator, const Length& denominator);
970
971 /**
972 * \ingroup length
973 * \relates Length
974 */
975 /**@{*/
976 /**
977 * Construct a Length from nanometers
978 *
979 * \param value Value in nanometers
980 *
981 * \return Length object constructed using Length::Unit::Nanometer
982 */
983 Length NanoMeters (double value);
984
985 /**
986 * Construct a Length from micrometers
987 *
988 * \param value Value in micrometers
989 *
990 * \return Length object constructed using Length::Unit::Micrometer
991 */
992 Length MicroMeters (double value);
993
994 /**
995 * Construct a Length from millimeters
996 *
997 * \param value Value in millimeters
998 *
999 * \return Length object constructed using Length::Unit::Millimeter
1000 */
1001 Length MilliMeters (double value);
1002
1003 /**
1004 * Construct a Length from centimeters
1005 *
1006 * \param value Value in centimeters
1007 *
1008 * \return Length object constructed using Length::Unit::Centimeter
1009 */
1010 Length CentiMeters (double value);
1011
1012 /**
1013 * Construct a Length from meters
1014 *
1015 * \param value Value in meters
1016 *
1017 * \return Length object constructed using Length::Unit::Meter
1018 */
1019 Length Meters (double value);
1020
1021 /**
1022 * Construct a Length from kilometers
1023 *
1024 * \param value Value in kilometers
1025 *
1026 * \return Length object constructed using Length::Unit::Kilometer
1027 */
1028 Length KiloMeters (double value);
1029
1030 /**
1031 * Construct a Length from nautical miles
1032 *
1033 * \param value Value in nautical miles
1034 *
1035 * \return Length object constructed using Length::Unit::NauticalMile
1036 */
1037 Length NauticalMiles (double value);
1038
1039 /**
1040 * Construct a Length from inches
1041 *
1042 * \param value Value in inches
1043 *
1044 * \return Length object constructed using Length::Unit::Inch
1045 */
1046 Length Inches (double value);
1047
1048 /**
1049 * Construct a Length from feet
1050 *
1051 * \param value Value in feet
1052 *
1053 * \return Length object constructed using Length::Unit::Foot
1054 */
1055 Length Feet (double value);
1056
1057 /**
1058 * Construct a Length from yards
1059 *
1060 * \param value Value in yards
1061 *
1062 * \return Length object constructed using Length::Unit::Yard
1063 */
1064 Length Yards (double value);
1065
1066 /**
1067 * Construct a Length from miles
1068 *
1069 * \param value Value in miles
1070 *
1071 * \return Length object constructed using Length::Unit::Mile
1072 */
1073 Length Miles (double value);
1074 /**@}*/
1075
1076 #ifdef HAVE_BOOST_UNITS
1077 template <class U, class T>
Length(boost::units::quantity<U,T> quantity)1078 Length::Length (boost::units::quantity<U, T> quantity)
1079 : m_value (0)
1080 {
1081 namespace bu = boost::units;
1082 using BoostMeters = bu::quantity<bu::si::length, double>;
1083
1084 //convert value to meters
1085 m_value = static_cast<BoostMeters> (quantity).value ();
1086 }
1087 #endif
1088
1089 } // namespace ns3
1090
1091 #endif /* NS3_LENGTH_H_ */
1092
1093