Trait providing assertion methods that can be called at compile time from macros to validate literals in source code.
An AnyVal for positive Doubles.
An AnyVal for positive Doubles.
Note: a PosDouble may not equal 0. If you want positive
number or 0, use PosZDouble.
Because PosDouble is an AnyVal it
will usually be as efficient as an Double, being
boxed only when a Double would have been boxed.
The PosDouble.apply factory method is
implemented in terms of a macro that checks literals for
validity at compile time. Calling
PosDouble.apply with a literal
Double value will either produce a valid
PosDouble instance at run time or an error at
compile time. Here's an example:
scala> import anyvals._
import anyvals._
scala> PosDouble(1.0)
res1: org.scalactic.anyvals.PosDouble = PosDouble(1.0)
scala> PosDouble(0.0)
<console>:14: error: PosDouble.apply can only be invoked on a positive (i > 0.0) floating point literal, like PosDouble(42.0).
PosDouble(0.0)
^
PosDouble.apply cannot be used if the value
being passed is a variable (i.e., not a literal),
because the macro cannot determine the validity of variables
at compile time (just literals). If you try to pass a
variable to PosDouble.apply, you'll get a
compiler error that suggests you use a different factor
method, PosDouble.from, instead:
scala> val x = 1.0
x: Double = 1.0
scala> PosDouble(x)
<console>:15: error: PosDouble.apply can only be invoked on a floating point literal, like PosDouble(42.0). Please use PosDouble.from instead.
PosDouble(x)
^
The PosDouble.from factory method will inspect
the value at runtime and return an
Option[PosDouble]. If the value is valid,
PosDouble.from will return a
Some[PosDouble], else it will return a
None. Here's an example:
scala> PosDouble.from(x) res4: Option[org.scalactic.anyvals.PosDouble] = Some(PosDouble(1.0)) scala> val y = 0.0 y: Double = 0.0 scala> PosDouble.from(y) res5: Option[org.scalactic.anyvals.PosDouble] = None
The PosDouble.apply factory method is marked
implicit, so that you can pass literal Doubles
into methods that require PosDouble, and get the
same compile-time checking you get when calling
PosDouble.apply explicitly. Here's an example:
scala> def invert(pos: PosDouble): Double = Double.MaxValue - pos
invert: (pos: org.scalactic.anyvals.PosDouble)Double
scala> invert(1.1)
res6: Double = 1.7976931348623157E308
scala> invert(Double.MaxValue)
res8: Double = 0.0
scala> invert(0.0)
<console>:15: error: PosDouble.apply can only be invoked on a positive (i > 0.0) floating point literal, like PosDouble(42.0).
invert(0.0)
^
scala> invert(-1.0)
<console>:15: error: PosDouble.apply can only be invoked on a positive (i > 0.0) floating point literal, like PosDouble(42.0).
invert(-1.0)
^
This example also demonstrates that the
PosDouble companion object also defines implicit
widening conversions when a similar conversion is provided in
Scala. This makes it convenient to use a
PosDouble where a Double is
needed. An example is the subtraction in the body of the
invert method defined above,
Double.MaxValue - pos. Although
Double.MaxValue is a Double, which
has no - method that takes a
PosDouble (the type of pos), you
can still subtract pos, because the
PosDouble will be implicitly widened to
Double.
An AnyVal for positive Floats.
An AnyVal for positive Floats.
Note: a PosFloat may not equal 0. If you want positive
number or 0, use PosZFloat.
Because PosFloat is an AnyVal it
will usually be as efficient as an Float, being
boxed only when an Float would have been boxed.
The PosFloat.apply factory method is implemented
in terms of a macro that checks literals for validity at
compile time. Calling PosFloat.apply with a
literal Float value will either produce a valid
PosFloat instance at run time or an error at
compile time. Here's an example:
scala> import anyvals._
import anyvals._
scala> PosFloat(1.0F)
res0: org.scalactic.anyvals.PosFloat = PosFloat(1.0)
scala> PosFloat(0.0F)
<console>:14: error: PosFloat.apply can only be invoked on a positive (i > 0.0F) floating point literal, like PosFloat(42.0F).
PosFloat(0.0F)
^
PosFloat.apply cannot be used if the value being
passed is a variable (i.e., not a literal), because
the macro cannot determine the validity of variables at
compile time (just literals). If you try to pass a variable
to PosFloat.apply, you'll get a compiler error
that suggests you use a different factor method,
PosFloat.from, instead:
scala> val x = 1.0F
x: Float = 1.0
scala> PosFloat(x)
<console>:15: error: PosFloat.apply can only be invoked on a floating point literal, like PosFloat(42.0F). Please use PosFloat.from instead.
PosFloat(x)
^
The PosFloat.from factory method will inspect
the value at runtime and return an
Option[PosFloat]. If the value is valid,
PosFloat.from will return a
Some[PosFloat], else it will return a
None. Here's an example:
scala> PosFloat.from(x) res3: Option[org.scalactic.anyvals.PosFloat] = Some(PosFloat(1.0)) scala> val y = 0.0F y: Float = 0.0 scala> PosFloat.from(y) res4: Option[org.scalactic.anyvals.PosFloat] = None
The PosFloat.apply factory method is marked
implicit, so that you can pass literal Floats
into methods that require PosFloat, and get the
same compile-time checking you get when calling
PosFloat.apply explicitly. Here's an example:
scala> def invert(pos: PosFloat): Float = Float.MaxValue - pos
invert: (pos: org.scalactic.anyvals.PosFloat)Float
scala> invert(1.1F)
res5: Float = 3.4028235E38
scala> invert(Float.MaxValue)
res6: Float = 0.0
scala> invert(0.0F)
<console>:15: error: PosFloat.apply can only be invoked on a positive (i > 0.0F) floating point literal, like PosFloat(42.0F).
invert(0.0F)
^
scala> invert(-1.1F)
<console>:15: error: PosFloat.apply can only be invoked on a positive (i > 0.0F) floating point literal, like PosFloat(42.0F).
invert(-1.1F)
^
This example also demonstrates that the PosFloat
companion object also defines implicit widening conversions
when no loss of precision will occur. This makes it convenient to use a
PosFloat where a Float or wider
type is needed. An example is the subtraction in the body of
the invert method defined above,
Float.MaxValue - pos. Although
Float.MaxValue is a Float, which
has no - method that takes a
PosFloat (the type of pos), you can
still subtract pos, because the
PosFloat will be implicitly widened to
Float.
An AnyVal for positive Ints.
An AnyVal for positive Ints.
Note: a PosInt may not equal 0. If you want positive
number or 0, use PosZInt.
Because PosInt is an AnyVal it will usually be
as efficient as an Int, being boxed only when an Int
would have been boxed.
The PosInt.apply factory method is implemented in terms of a macro that
checks literals for validity at compile time. Calling PosInt.apply with
a literal Int value will either produce a valid PosInt instance
at run time or an error at compile time. Here's an example:
scala> import anyvals._
import anyvals._
scala> PosInt(1)
res0: org.scalactic.anyvals.PosInt = PosInt(1)
scala> PosInt(0)
<console>:14: error: PosInt.apply can only be invoked on a positive (i > 0) integer literal, like PosInt(42).
PosInt(0)
^
PosInt.apply cannot be used if the value being passed is a variable (i.e., not a literal), because
the macro cannot determine the validity of variables at compile time (just literals). If you try to pass a variable
to PosInt.apply, you'll get a compiler error that suggests you use a different factor method,
PosInt.from, instead:
scala> val x = 1
x: Int = 1
scala> PosInt(x)
<console>:15: error: PosInt.apply can only be invoked on an integer literal, like PosInt(42). Please use PosInt.from instead.
PosInt(x)
^
The PosInt.from factory method will inspect the value at runtime and return an Option[PosInt]. If
the value is valid, PosInt.from will return a Some[PosInt], else it will return a None.
Here's an example:
scala> PosInt.from(x) res3: Option[org.scalactic.anyvals.PosInt] = Some(PosInt(1)) scala> val y = 0 y: Int = 0 scala> PosInt.from(y) res4: Option[org.scalactic.anyvals.PosInt] = None
The PosInt.apply factory method is marked implicit, so that you can pass literal Ints
into methods that require PosInt, and get the same compile-time checking you get when calling
PosInt.apply explicitly. Here's an example:
scala> def invert(pos: PosInt): Int = Int.MaxValue - pos
invert: (pos: org.scalactic.anyvals.PosInt)Int
scala> invert(1)
res0: Int = 2147483646
scala> invert(Int.MaxValue)
res1: Int = 0
scala> invert(0)
<console>:15: error: PosInt.apply can only be invoked on a positive (i > 0) integer literal, like PosInt(42).
invert(0)
^
scala> invert(-1)
<console>:15: error: PosInt.apply can only be invoked on a positive (i > 0) integer literal, like PosInt(42).
invert(-1)
^
This example also demonstrates that the PosInt companion object also defines implicit widening conversions
when either no loss of precision will occur or a similar conversion is provided in Scala. (For example, the implicit
conversion from Int to Float in Scala can lose precision.) This makes it convenient to
use a PosInt where an Int or wider type is needed. An example is the subtraction in the body
of the invert method defined above, Int.MaxValue - pos. Although Int.MaxValue is
an Int, which has no - method that takes a PosInt (the type of pos),
you can still subtract pos, because the PosInt will be implicitly widened to Int.
An AnyVal for positive Longs.
An AnyVal for positive Longs.
Note: a PosLong may not equal 0. If you want positive
number or 0, use PosZLong.
Because PosLong is an AnyVal it
will usually be as efficient as an Long, being
boxed only when an Long would have been boxed.
The PosLong.apply factory method is implemented
in terms of a macro that checks literals for validity at
compile time. Calling PosLong.apply with a
literal Long value will either produce a valid
PosLong instance at run time or an error at
compile time. Here's an example:
scala> import anyvals._
import anyvals._
scala> PosLong(1L)
res0: org.scalactic.anyvals.PosLong = PosLong(1)
scala> PosLong(0L)
<console>:14: error: PosLong.apply can only be invoked on a positive (i > 0L) integer literal, like PosLong(42L).
PosLong(0L)
^
PosLong.apply cannot be used if the value being
passed is a variable (i.e., not a literal), because
the macro cannot determine the validity of variables at
compile time (just literals). If you try to pass a variable
to PosLong.apply, you'll get a compiler error
that suggests you use a different factor method,
PosLong.from, instead:
scala> val x = 1L
x: Long = 1
scala> PosLong(x)
<console>:15: error: PosLong.apply can only be invoked on an integer literal, like PosLong(42L). Please use PosLong.from instead.
PosLong(x)
^
The PosLong.from factory method will inspect the
value at runtime and return an
Option[PosLong]. If the value is valid,
PosLong.from will return a
Some[PosLong], else it will return a
None. Here's an example:
scala> PosLong.from(x) res3: Option[org.scalactic.anyvals.PosLong] = Some(PosLong(1)) scala> val y = 0L y: Long = 0 scala> PosLong.from(y) res4: Option[org.scalactic.anyvals.PosLong] = None
The PosLong.apply factory method is marked
implicit, so that you can pass literal Longs
into methods that require PosLong, and get the
same compile-time checking you get when calling
PosLong.apply explicitly. Here's an example:
scala> def invert(pos: PosLong): Long = Long.MaxValue - pos
invert: (pos: org.scalactic.anyvals.PosLong)Long
scala> invert(1L)
res5: Long = 9223372036854775806
scala> invert(Long.MaxValue)
res6: Long = 0
scala> invert(0L)
<console>:15: error: PosLong.apply can only be invoked on a positive (i > 0L) integer literal, like PosLong(42L).
invert(0L)
^
scala> invert(-1L)
<console>:15: error: PosLong.apply can only be invoked on a positive (i > 0L) integer literal, like PosLong(42L).
invert(-1L)
^
This example also demonstrates that the PosLong
companion object also defines implicit widening conversions
when either no loss of precision will occur or a similar
conversion is provided in Scala. (For example, the implicit
conversion from Long to Double in
Scala can lose precision.) This makes it convenient to use a
PosLong where a Long or wider type
is needed. An example is the subtraction in the body of the
invert method defined above, Long.MaxValue
- pos. Although Long.MaxValue is a
Long, which has no - method that
takes a PosLong (the type of pos),
you can still subtract pos, because the
PosLong will be implicitly widened to
Long.
An AnyVal for non-negative Doubles.
An AnyVal for non-negative Doubles.
Because PosZDouble is an AnyVal it will usually be
as efficient as an Double, being boxed only when a
Double would have been boxed.
The PosZDouble.apply factory method is
implemented in terms of a macro that checks literals for
validity at compile time. Calling
PosZDouble.apply with a literal
Double value will either produce a valid
PosZDouble instance at run time or an error at
compile time. Here's an example:
scala> import anyvals._
import anyvals._
scala> PosZDouble(1.1)
res0: org.scalactic.anyvals.PosZDouble = PosZDouble(1.1)
scala> PosZDouble(0.0)
res1: org.scalactic.anyvals.PosZDouble = PosZDouble(0.0)
scala> PosZDouble(-1.1)
<console>:14: error: PosZDouble.apply can only be invoked on a non-negative (i >= 0.0) floating point literal, like PosZDouble(42.0).
PosZDouble(-1.1)
^
PosZDouble.apply cannot be used if the value
being passed is a variable (i.e., not a literal),
because the macro cannot determine the validity of variables
at compile time (just literals). If you try to pass a
variable to PosZDouble.apply, you'll get a
compiler error that suggests you use a different factor
method, PosZDouble.from, instead:
scala> val x = 1.1
x: Double = 1.1
scala> PosZDouble(x)
<console>:15: error: PosZDouble.apply can only be invoked on a floating point literal, like PosZDouble(42.0). Please use PosZDouble.from instead.
PosZDouble(x)
^
The PosZDouble.from factory method will inspect
the value at runtime and return an
Option[PosZDouble]. If the value is valid,
PosZDouble.from will return a
Some[PosZDouble], else it will return a
None. Here's an example:
scala> PosZDouble.from(x) res4: Option[org.scalactic.anyvals.PosZDouble] = Some(PosZDouble(1.1)) scala> val y = -1.1 y: Double = -1.1 scala> PosZDouble.from(y) res5: Option[org.scalactic.anyvals.PosZDouble] = None
The PosZDouble.apply factory method is marked implicit, so that
you can pass literal Doubles into methods that require
PosZDouble, and get the same compile-time checking you get when
calling PosZDouble.apply explicitly. Here's an example:
scala> def invert(pos: PosZDouble): Double = Double.MaxValue - pos
invert: (pos: org.scalactic.anyvals.PosZDouble)Double
scala> invert(0.0)
res6: Double = 1.7976931348623157E308
scala> invert(Double.MaxValue)
res7: Double = 0.0
scala> invert(-1.1)
<console>:15: error: PosZDouble.apply can only be invoked on a non-negative (i >= 0.0) floating point literal, like PosZDouble(42.0).
invert(-1.1)
^
This example also demonstrates that the
PosZDouble companion object also defines
implicit widening conversions when a similar conversion is
provided in Scala. This makes it convenient to use a
PosZDouble where a Double or wider
type is needed. An example is the subtraction in the body of
the invert method defined above,
Double.MaxValue - pos. Although
Double.MaxValue is a Double, which
has no - method that takes a
PosZDouble (the type of pos), you
can still subtract pos, because the
PosZDouble will be implicitly widened to
Double.
An AnyVal for non-negative Floats.
An AnyVal for non-negative Floats.
Because PosZFloat is an AnyVal it will usually be
as efficient as an Float, being boxed only when a
Float would have been boxed.
The PosZFloat.apply factory method is
implemented in terms of a macro that checks literals for
validity at compile time. Calling
PosZFloat.apply with a literal
Float value will either produce a valid
PosZFloat instance at run time or an error at
compile time. Here's an example:
scala> import anyvals._
import anyvals._
scala> PosZFloat(1.1F)
res0: org.scalactic.anyvals.PosZFloat = PosZFloat(1.1)
scala> PosZFloat(0.0F)
res1: org.scalactic.anyvals.PosZFloat = PosZFloat(0.0)
scala> PosZFloat(-1.1F)
<console>:14: error: PosZFloat.apply can only be invoked on a non-negative (i >= 0.0F) floating point literal, like PosZFloat(42.0F).
PosZFloat(-1.1F)
^
PosZFloat.apply cannot be used if the value
being passed is a variable (i.e., not a literal),
because the macro cannot determine the validity of variables
at compile time (just literals). If you try to pass a
variable to PosZFloat.apply, you'll get a
compiler error that suggests you use a different factor
method, PosZFloat.from, instead:
scala> val x = 1.1F
x: Float = 1.1
scala> PosZFloat(x)
<console>:15: error: PosZFloat.apply can only be invoked on a floating point literal, like PosZFloat(42.0F). Please use PosZFloat.from instead.
PosZFloat(x)
^
The PosZFloat.from factory method will inspect
the value at runtime and return an
Option[PosZFloat]. If the value is valid,
PosZFloat.from will return a
Some[PosZFloat], else it will return a
None. Here's an example:
scala> PosZFloat.from(x) res4: Option[org.scalactic.anyvals.PosZFloat] = Some(PosZFloat(1.1)) scala> val y = -1.1F y: Float = -1.1 scala> PosZFloat.from(y) res5: Option[org.scalactic.anyvals.PosZFloat] = None
The PosZFloat.apply factory method is marked implicit, so that
you can pass literal Floats into methods that require
PosZFloat, and get the same compile-time checking you get when
calling PosZFloat.apply explicitly. Here's an example:
scala> def invert(pos: PosZFloat): Float = Float.MaxValue - pos
invert: (pos: org.scalactic.anyvals.PosZFloat)Float
scala> invert(0.0F)
res6: Float = 3.4028235E38
scala> invert(Float.MaxValue)
res7: Float = 0.0
scala> invert(-1.1F)
<console>:15: error: PosZFloat.apply can only be invoked on a non-negative (i >= 0.0F) floating point literal, like PosZFloat(42.0F).
invert(-1.1F)
^
This example also demonstrates that the
PosZFloat companion object also defines
implicit widening conversions when a similar conversion is
provided in Scala. This makes it convenient to use a
PosZFloat where a Float or wider
type is needed. An example is the subtraction in the body of
the invert method defined above,
Float.MaxValue - pos. Although
Float.MaxValue is an Float, which
has no - method that takes a
PosZFloat (the type of pos), you
can still subtract pos, because the
PosZFloat will be implicitly widened to
Float.
An AnyVal for non-negative Ints.
An AnyVal for non-negative Ints.
Because PosZInt is an AnyVal it will usually be
as efficient as an Int, being boxed only when an
Int would have been boxed.
The PosZInt.apply factory method is implemented in terms of a
macro that checks literals for validity at compile time. Calling
PosZInt.apply with a literal Int value will either
produce a valid PosZInt instance at run time or an error at
compile time. Here's an example:
scala> import anyvals._
import anyvals._
scala> PosZInt(1)
res0: org.scalactic.anyvals.PosZInt = PosZInt(1)
scala> PosZInt(0)
res1: org.scalactic.anyvals.PosZInt = PosZInt(0)
scala> PosZInt(-1)
<console>:14: error: PosZInt.apply can only be invoked on a non-negative (i >= 0) integer literal, like PosZInt(42).
PosZInt(-1)
^
PosZInt.apply cannot be used if the value being passed is a
variable (i.e., not a literal), because the macro cannot determine
the validity of variables at compile time (just literals). If you try to
pass a variable to PosZInt.apply, you'll get a compiler error
that suggests you use a different factor method, PosZInt.from,
instead:
scala> val x = 1
x: Int = 1
scala> PosZInt(x)
<console>:15: error: PosZInt.apply can only be invoked on an integer literal, like PosZInt(42). Please use PosZInt.from instead.
PosZInt(x)
^
The PosZInt.from factory method will inspect the value at runtime and return an Option[PosZInt]. If
the value is valid, PosZInt.from will return a Some[PosZInt], else it will return a None.
Here's an example:
scala> PosZInt.from(x) res4: Option[org.scalactic.anyvals.PosZInt] = Some(PosZInt(1)) scala> val y = -1 y: Int = -1 scala> PosZInt.from(y) res5: Option[org.scalactic.anyvals.PosZInt] = None
The PosZInt.apply factory method is marked implicit, so that
you can pass literal Ints into methods that require
PosZInt, and get the same compile-time checking you get when
calling PosZInt.apply explicitly. Here's an example:
scala> def invert(pos: PosZInt): Int = Int.MaxValue - pos
invert: (pos: org.scalactic.anyvals.PosZInt)Int
scala> invert(0)
res7: Int = 2147483647
scala> invert(Int.MaxValue)
res8: Int = 0
scala> invert(-1)
<console>:15: error: PosZInt.apply can only be invoked on a non-negative (i >= 0) integer literal, like PosZInt(42).
invert(-1)
^
This example also demonstrates that the PosZInt
companion object also defines implicit widening conversions
when either no loss of precision will occur or a similar
conversion is provided in Scala. (For example, the implicit
conversion from Int to Float in
Scala can lose precision.) This makes it convenient to use a
PosZInt where an Int or wider type
is needed. An example is the subtraction in the body of the
invert method defined above, Int.MaxValue
- pos. Although Int.MaxValue is an
Int, which has no - method that
takes a PosZInt (the type of pos),
you can still subtract pos, because the
PosZInt will be implicitly widened to
Int.
An AnyVal for non-negative Longs.
An AnyVal for non-negative Longs.
Because PosZLong is an AnyVal it will usually be
as efficient as an Long, being boxed only when an
Long would have been boxed.
The PosZLong.apply factory method is implemented in terms of a
macro that checks literals for validity at compile time. Calling
PosZLong.apply with a literal Long value will
either produce a valid PosZLong instance at run time or an
error at compile time. Here's an example:
scala> import anyvals._
import anyvals._
scala> PosZLong(1L)
res0: org.scalactic.anyvals.PosZLong = PosZLong(1)
scala> PosZLong(0L)
res1: org.scalactic.anyvals.PosZLong = PosZLong(0)
scala> PosZLong(-1L)
<console>:14: error: PosZLong.apply can only be invoked on a non-negative (i >= 0L) integer literal, like PosZLong(42L).
PosZLong(-1L)
^
PosZLong.apply cannot be used if the value being passed is a
variable (i.e., not a literal), because the macro cannot determine
the validity of variables at compile time (just literals). If you try to
pass a variable to PosZLong.apply, you'll get a compiler error
that suggests you use a different factor method, PosZLong.from,
instead:
scala> val x = 1L
x: Long = 1
scala> PosZLong(x)
<console>:15: error: PosZLong.apply can only be invoked on an integer literal, like PosZLong(42L). Please use PosZLong.from instead.
PosZLong(x)
^
The PosZLong.from factory method will inspect the value at runtime and return an Option[PosZLong]. If
the value is valid, PosZLong.from will return a Some[PosZLong], else it will return a None.
Here's an example:
scala> PosZLong.from(x) res4: Option[org.scalactic.anyvals.PosZLong] = Some(PosZLong(1)) scala> val y = -1L y: Long = -1 scala> PosZLong.from(y) res5: Option[org.scalactic.anyvals.PosZLong] = None
The PosZLong.apply factory method is marked implicit, so that
you can pass literal Longs into methods that require
PosZLong, and get the same compile-time checking you get when
calling PosZLong.apply explicitly. Here's an example:
scala> def invert(pos: PosZLong): Long = Long.MaxValue - pos
invert: (pos: org.scalactic.anyvals.PosZLong)Long
scala> invert(0L)
res6: Long = 9223372036854775807
scala> invert(Long.MaxValue)
res7: Long = 0
scala> invert(-1L)
<console>:15: error: PosZLong.apply can only be invoked on a non-negative (i >= 0L) integer literal, like PosZLong(42L).
invert(-1L)
^
This example also demonstrates that the PosZLong
companion object also defines implicit widening conversions
when either no loss of precision will occur or a similar
conversion is provided in Scala. (For example, the implicit
conversion from Long to Double in
Scala can lose precision.) This makes it convenient to use a
PosZLong where a Long or wider type
is needed. An example is the subtraction in the body of the
invert method defined above, Long.MaxValue
- pos. Although Long.MaxValue is a
Long, which has no - method that
takes a PosZLong (the type of pos),
you can still subtract pos, because the
PosZLong will be implicitly widened to
Long.
Companion object that facilitates the importing of CompileTimeAssertions members as
an alternative to mixing in the trait.
Companion object that facilitates the importing of CompileTimeAssertions members as
an alternative to mixing in the trait.
The companion object for PosDouble that offers
factory methods that produce PosDoubles,
implicit widening conversions from PosDouble to
other numeric types, and maximum and minimum constant values
for PosDouble.
The companion object for PosDouble that offers
factory methods that produce PosDoubles,
implicit widening conversions from PosDouble to
other numeric types, and maximum and minimum constant values
for PosDouble.
The companion object for PosFloat that offers
factory methods that produce PosFloats,
implicit widening conversions from PosFloat to
other numeric types, and maximum and minimum constant values
for PosFloat.
The companion object for PosFloat that offers
factory methods that produce PosFloats,
implicit widening conversions from PosFloat to
other numeric types, and maximum and minimum constant values
for PosFloat.
The companion object for PosInt that offers factory methods that
produce PosInts, implicit widening conversions from PosInt
to other numeric types, and maximum and minimum constant values for PosInt.
The companion object for PosInt that offers factory methods that
produce PosInts, implicit widening conversions from PosInt
to other numeric types, and maximum and minimum constant values for PosInt.
The companion object for PosLong that offers
factory methods that produce PosLongs, implicit
widening conversions from PosLong to other
numeric types, and maximum and minimum constant values for
PosLong.
The companion object for PosLong that offers
factory methods that produce PosLongs, implicit
widening conversions from PosLong to other
numeric types, and maximum and minimum constant values for
PosLong.
The companion object for PosZDouble that offers
factory methods that produce PosZDoubles, implicit
widening conversions from PosZDouble to other
numeric types, and maximum and minimum constant values for
PosZDouble.
The companion object for PosZDouble that offers
factory methods that produce PosZDoubles, implicit
widening conversions from PosZDouble to other
numeric types, and maximum and minimum constant values for
PosZDouble.
The companion object for PosZFloat that offers
factory methods that produce PosZFloats, implicit
widening conversions from PosZFloat to other
numeric types, and maximum and minimum constant values for
PosZFloat.
The companion object for PosZFloat that offers
factory methods that produce PosZFloats, implicit
widening conversions from PosZFloat to other
numeric types, and maximum and minimum constant values for
PosZFloat.
The companion object for PosZInt that offers
factory methods that produce PosZInts, implicit
widening conversions from PosZInt to other
numeric types, and maximum and minimum constant values for
PosZInt.
The companion object for PosZInt that offers
factory methods that produce PosZInts, implicit
widening conversions from PosZInt to other
numeric types, and maximum and minimum constant values for
PosZInt.
The companion object for PosZLong that offers
factory methods that produce PosZLongs, implicit
widening conversions from PosZLong to other
numeric types, and maximum and minimum constant values for
PosZLong.
The companion object for PosZLong that offers
factory methods that produce PosZLongs, implicit
widening conversions from PosZLong to other
numeric types, and maximum and minimum constant values for
PosZLong.
Trait providing assertion methods that can be called at compile time from macros to validate literals in source code.
The intent of
CompileTimeAssertionsis to make it easier to createAnyVals that restrict the values of types for which Scala supports literals:Int,Long,Float,Double,Char, andString. For example, if you are using odd integers in many places in your code, you might have validity checks scattered throughout your code. Here's an example of a method that both requires an oddIntis passed (as a precondition, and ensures an odd *Intis returned (as a postcondition):In either the precondition or postcondition check fails, an exception will be thrown at runtime. If you have many methods like this you may want to create a type to represent an odd
Int, so that the checking for validity errors is isolated in just one place. By using anAnyValyou can avoid boxing theInt, which may be more efficient. This might look like:An
AnyValcannot have any constructor code, so to ensure that anyIntpassed to theOddIntconstructor is actually odd, the constructor must be private. That way the only way to construct a newOddIntis via theapplyfactory method in theOddIntcompanion object, which can require that the value be odd. This design eliminates the need for placingrequireandensuringclauses anywhere else that oddInts are needed, because the type promises the constraint. ThenextOddmethod could, therefore, be rewritten as:Using the compile-time assertions provided by this trait, you can construct a factory method implemented vai a macro wthat causes a compile failure if
OddInt.applyis passed anything besides an oddIntliteral. ClassOddIntwould look exactly the same as before:In the companion object, however, the
applymethod would be implemented in terms of a macro. Because theapplymethod will only work with literals, you'll need a second method that can work an any expression of typeInt. Although you could write a factory method that throws a runtime exception if a non-oddIntis passed, we recommend afrommethod that returns anOption. The returnedOptioncan be processed to deal with the potential for non-odd values.The
applymethod refers to a macro implementation method in classPosIntMacro. The macro implementation of any such method can look very similar to this one. The only changes you'd need to make is theisValidmethod implementation and the text of the error messages.The
isValidmethod just takes the underlying type and returnstrueif it is valid, elsefalse. This method is placed here so the same valiation code can be used both in thefrommethod at runtime and theapplymacro at compile time. Theapplyactually does just two things. It calls aensureValidIntLiteral, performing a compile-time assertion that value passed toapplyis anIntliteral that is valid (in this case, odd). If the assertion fails,ensureValidIntLiteralwill complete abruptly with an exception that will contain an appropriate error message (one of the two you passed in) and cause a compiler error with that message. If the assertion succeeds,ensureValidIntLiteralwill just return normally. The next line of code will then execute. This line of code must construct an AST (abstract syntax tree) of code that will replace theOddInt.applyinvocation. We invoke the other factory method that returns anOption, and since we've proven at compile time that thatOptionwill be defined, we callgeton it.You may wish to use quasi-quotes instead of reify. The reason we use reify is that this also works on 2.10 without any additional plugin (i.e., you don't need macro paradise), and Scalactic supports 2.10.