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