View Source Warder.Multirange (warder v0.1.2)

Multirange Implementation

Creation / Manipulation

Multiranges should not be created or modified manually. Use new/1, or empty/0 to create multiranges.

Ecto Type

If ecto and postgrex are installed, you can use the Warder.Multirange type:

defmodule Model do
  use Ecto.Schema

  alias Warder.Multirange

  @type t :: %{multirange: Multirange.t(integer())}

  schema "models" do
    field :multirange, Multirange,
      db_type: :int8multirange,
      inner_type: :integer
  end
end

Options

  • db_type - The database type to use for the range column. For example :int8multirange.
  • inner_type - The ecto type of the elements in the range. For example :integer.

Summary

Functions

Is first adjacent to second?

Check if first contains second.

Computes the difference of the multiranges.

Create new empty multirange

Computes the intersection of the multiranges.

Is first strictly left of second?

Computes the smallest range that all parts of the multirange.

Create a new Multirange for the given ranges

Does first not extend to the left of second?

Does first not extend to the right of second?

Does first overlap with second, that is, do they have any common elements?

Is first strictly right of second?

Computes the union of the multiranges.

Types

@type t() :: t(term())
Link to this type

t(subtype)

View Source (since 0.1.0)
@type t(subtype) :: %Warder.Multirange{ranges: [Warder.Range.t(subtype)]}

Functions

Link to this function

adjacent?(first, second)

View Source (since 0.1.0)
@spec adjacent?(
  first :: t(subtype) | Warder.Range.t(subtype),
  second :: t(subtype) | Warder.Range.t(subtype)
) :: boolean()
when subtype: Warder.Element.t()

Is first adjacent to second?

Both first and second can either be a multirange or a range.

Examples

iex> Warder.Multirange.adjacent?(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)]),
...>   Warder.Multirange.new([Warder.Range.new!(20, 30)]
...> ))
false

iex> Warder.Multirange.adjacent?(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)]), Warder.Range.new!(20, 30)
...> )
false

iex> Warder.Multirange.adjacent?(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)]), Warder.Range.new!(10, 20)
...> )
true
Link to this function

contains?(first, second)

View Source (since 0.1.0)
@spec contains?(
  first :: t(subtype) | Warder.Range.t(subtype) | subtype,
  second :: t(subtype) | Warder.Range.t(subtype) | subtype
) :: boolean()
when subtype: Warder.Element.t()

Check if first contains second.

Both first and second can either be a multirange, range or an element.

Does the first multirange contain the second multirange or range?

Examples

iex> Warder.Multirange.contains?(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)]),
...>   Warder.Multirange.new([Warder.Range.new!(1, 5)])
...> )
true

iex> Warder.Multirange.contains?(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)]),
...>   Warder.Range.new!(1, 10)
...> )
true

iex> Warder.Multirange.contains?(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)]),
...>   5
...> )
true

iex> Warder.Multirange.contains?(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)]),
...>   20
...> )
false
Link to this function

difference(first, second)

View Source (since 0.1.0)
@spec difference(first :: t(subtype), second :: t(subtype)) :: t(subtype)
when subtype: Warder.Element.t()

Computes the difference of the multiranges.

Examples

iex> Warder.Multirange.difference(
...>   Warder.Multirange.new([Warder.Range.new!(5, 20)]),
...>   Warder.Multirange.new([Warder.Range.new!(10, 15)])
...> )
%Warder.Multirange{ranges: [
  %Warder.Range{lower: 5, upper: 10, lower_inclusive: true, upper_inclusive: false},
  %Warder.Range{lower: 15, upper: 20, lower_inclusive: true, upper_inclusive: false}
]}
@spec empty() :: t(subtype) when subtype: Warder.Element.t()

Create new empty multirange

Examples

iex> Warder.Multirange.empty()
%Warder.Multirange{ranges: []}
Link to this function

intersection(first, second)

View Source (since 0.1.0)
@spec intersection(first :: t(subtype), second :: t(subtype)) :: t(subtype)
when subtype: Warder.Element.t()

Computes the intersection of the multiranges.

Examples

iex> Warder.Multirange.intersection(
...>   Warder.Multirange.new([Warder.Range.new!(5, 15)]),
...>   Warder.Multirange.new([Warder.Range.new!(10, 20)])
...> )
%Warder.Multirange{ranges: [
  %Warder.Range{lower: 10, upper: 15, lower_inclusive: true, upper_inclusive: false}
]}
Link to this function

left?(first, second)

View Source (since 0.1.0)
@spec left?(
  first :: t(subtype) | Warder.Range.t(subtype),
  second :: t(subtype) | Warder.Range.t(subtype)
) :: boolean()
when subtype: Warder.Element.t()

Is first strictly left of second?

Both first and second can either be a multirange or a range.

Examples

iex> Warder.Multirange.left?(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)]),
...>   Warder.Multirange.new([Warder.Range.new!(20, 30)])
...> )
true

iex> Warder.Multirange.left?(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)]),
...>   Warder.Range.new!(20, 30)
...> )
true

iex> Warder.Multirange.left?(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)]),
...>   Warder.Range.new!(5, 15)
...> )
false
Link to this function

merge(multirange)

View Source (since 0.1.0)
@spec merge(multirange :: t(subtype)) :: Warder.Range.t(subtype)
when subtype: Warder.Element.t()

Computes the smallest range that all parts of the multirange.

Examples

iex> Warder.Multirange.merge(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10), Warder.Range.new!(20, 30)])
...> )
%Warder.Range{lower: 1, upper: 30, lower_inclusive: true, upper_inclusive: false}
Link to this function

new(ranges)

View Source (since 0.1.0)
@spec new(ranges :: [Warder.Range.t(subtype)]) :: t(subtype)
when subtype: Warder.Element.t()

Create a new Multirange for the given ranges

Examples

iex> Warder.Multirange.new([
...>   Warder.Range.new!(1, 10),
...>   Warder.Range.new!(5, 15),
...>   Warder.Range.new!(20, 30)
...>])
%Warder.Multirange{ranges: [
  %Warder.Range{lower: 1, upper: 15, lower_inclusive: true, upper_inclusive: false},
  %Warder.Range{lower: 20, upper: 30, lower_inclusive: true, upper_inclusive: false}
]}
Link to this function

no_extend_left?(first, second)

View Source (since 0.1.0)
@spec no_extend_left?(
  first :: t(subtype) | Warder.Range.t(subtype),
  second :: t(subtype) | Warder.Range.t(subtype)
) :: boolean()
when subtype: Warder.Element.t()

Does first not extend to the left of second?

Both first and second can either be a multirange or a range.

Examples

iex> Warder.Multirange.no_extend_left?(
...>   Warder.Multirange.new([Warder.Range.new!(20, 30)]),
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)])
...> )
true

iex> Warder.Multirange.no_extend_left?(
...>   Warder.Range.new!(20, 30),
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)])
...> )
true

iex> Warder.Multirange.no_extend_left?(
...>   Warder.Range.new!(1, 10),
...>   Warder.Multirange.new([Warder.Range.new!(5, 10)])
...> )
false
Link to this function

no_extend_right?(first, second)

View Source (since 0.1.0)
@spec no_extend_right?(
  first :: t(subtype) | Warder.Range.t(subtype),
  second :: t(subtype) | Warder.Range.t(subtype)
) :: boolean()
when subtype: Warder.Element.t()

Does first not extend to the right of second?

Both first and second can either be a multirange or a range.

Examples

iex> Warder.Multirange.no_extend_right?(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)]),
...>   Warder.Multirange.new([Warder.Range.new!(20, 30)])
...> )
true

iex> Warder.Multirange.no_extend_right?(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)]),
...>   Warder.Range.new!(20, 30)
...> )
true

iex> Warder.Multirange.no_extend_right?(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)]),
...>   Warder.Range.new!(1, 5)
...> )
false
Link to this function

overlap?(first, second)

View Source (since 0.1.0)
@spec overlap?(
  first :: t(subtype) | Warder.Range.t(subtype),
  second :: t(subtype) | Warder.Range.t(subtype)
) :: boolean()
when subtype: Warder.Element.t()

Does first overlap with second, that is, do they have any common elements?

Both first and second can either be a multirange or a range.

Examples

iex> Warder.Multirange.overlap?(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)]),
...>   Warder.Multirange.new([Warder.Range.new!(5, 15)])
...> )
true

iex> Warder.Multirange.overlap?(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)]),
...>   Warder.Range.new!(5, 15)
...> )
true

iex> Warder.Multirange.overlap?(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)]),
...>   Warder.Range.new!(20, 30)
...> )
false
Link to this function

right?(first, second)

View Source (since 0.1.0)
@spec right?(
  first :: t(subtype) | Warder.Range.t(subtype),
  second :: t(subtype) | Warder.Range.t(subtype)
) :: boolean()
when subtype: Warder.Element.t()
@spec right?(
  first :: t(subtype) | Warder.Range.t(subtype),
  second :: t(subtype) | Warder.Range.t(subtype)
) :: boolean()
when subtype: Warder.Element.t()

Is first strictly right of second?

Both first and second can either be a multirange or a range.

Examples

iex> Warder.Multirange.right?(
...>   Warder.Multirange.new([Warder.Range.new!(20, 30)]),
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)])
...> )
true

iex> Warder.Multirange.right?(
...>   Warder.Range.new!(20, 30),
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)])
...> )
true

iex> Warder.Multirange.right?(
...>   Warder.Range.new!(5, 15),
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)])
...> )
false
Link to this function

union(first, second)

View Source (since 0.1.0)
@spec union(first :: t(subtype), second :: t(subtype)) :: t(subtype)
when subtype: Warder.Element.t()

Computes the union of the multiranges.

Examples

iex> Warder.Multirange.union(
...>   Warder.Multirange.new([Warder.Range.new!(1, 10)]),
...> Warder.Multirange.new([Warder.Range.new!(5, 15)])
...> )
%Warder.Multirange{ranges: [
  %Warder.Range{lower: 1, upper: 15, lower_inclusive: true, upper_inclusive: false}
]}