RangeId.h 4.29 KB
Newer Older
1 2 3 4 5 6 7 8
//============================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt for details.
//  This software is distributed WITHOUT ANY WARRANTY; without even
//  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
//  PURPOSE.  See the above copyright notice for more information.
//
9
//  Copyright 2017 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
10 11 12
//  Copyright 2017 UT-Battelle, LLC.
//  Copyright 2017 Los Alamos National Security.
//
13
//  Under the terms of Contract DE-NA0003525 with NTESS,
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
//  the U.S. Government retains certain rights in this software.
//
//  Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
//  Laboratory (LANL), the U.S. Government retains certain rights in
//  this software.
//============================================================================
#ifndef vtk_m_RangeId_h
#define vtk_m_RangeId_h

#include <vtkm/Math.h>
#include <vtkm/Types.h>

namespace vtkm
{

/// \brief Represent a range of vtkm::Id values.
///
/// \c vtkm::RangeId is a helper class for representing a range of vtkm::Id
/// values. This is specified simply with a \c Min and \c Max value, where
/// \c Max is exclusive.
///
/// \c RangeId also contains several helper functions for computing and
/// maintaining the range.
///
struct RangeId
{
  vtkm::Id Min;
  vtkm::Id Max;

  VTKM_EXEC_CONT
  RangeId()
    : Min(0)
    , Max(0)
  {
  }

  VTKM_EXEC_CONT
  RangeId(vtkm::Id min, vtkm::Id max)
    : Min(min)
    , Max(max)
  {
  }

  /// \b Determine if the range is valid.
  ///
  /// \c IsNonEmpty return true if the range contains some valid values between
  /// \c Min and \c Max. If \c Max <= \c Min, then no values satisfy
  /// the range and \c IsNonEmpty returns false. Otherwise, return true.
  ///
  VTKM_EXEC_CONT
  bool IsNonEmpty() const { return (this->Min < this->Max); }

  /// \b Determines if a value is within the range.
  ///
  /// \c Contains returns true if the give value is within the range, false
  /// otherwise.
  ///
  VTKM_EXEC_CONT
  bool Contains(vtkm::Id value) const { return ((this->Min <= value) && (this->Max > value)); }

  /// \b Returns the length of the range.
  ///
  /// \c Length computes the distance between the min and max. If the range
  /// is empty, 0 is returned.
  ///
  VTKM_EXEC_CONT
  vtkm::Id Length() const { return this->Max - this->Min; }

  /// \b Returns the center of the range.
  ///
  /// \c Center computes the middle value of the range.
  ///
  VTKM_EXEC_CONT
  vtkm::Id Center() const { return (this->Min + this->Max) / 2; }

  /// \b Expand range to include a value.
  ///
  /// This version of \c Include expands the range just enough to include the
  /// given value. If the range already includes this value, then nothing is
  /// done.
  ///
  VTKM_EXEC_CONT
  void Include(vtkm::Id value)
  {
    this->Min = vtkm::Min(this->Min, value);
    this->Max = vtkm::Max(this->Max, value + 1);
  }

  /// \b Expand range to include other range.
  ///
  /// This version of \c Include expands this range just enough to include that
luz.paz's avatar
luz.paz committed
105
  /// of another range. Essentially it is the union of the two ranges.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
  ///
  VTKM_EXEC_CONT
  void Include(const vtkm::RangeId& range)
  {
    this->Min = vtkm::Min(this->Min, range.Min);
    this->Max = vtkm::Max(this->Max, range.Max);
  }

  /// \b Return the union of this and another range.
  ///
  /// This is a nondestructive form of \c Include.
  ///
  VTKM_EXEC_CONT
  vtkm::RangeId Union(const vtkm::RangeId& other) const
  {
    vtkm::RangeId unionRange(*this);
    unionRange.Include(other);
    return unionRange;
  }

  /// \b Operator for union
  ///
  VTKM_EXEC_CONT
  vtkm::RangeId operator+(const vtkm::RangeId& other) const { return this->Union(other); }

  VTKM_EXEC_CONT
  bool operator==(const vtkm::RangeId& other) const
  {
    return ((this->Min == other.Min) && (this->Max == other.Max));
  }

  VTKM_EXEC_CONT
  bool operator!=(const vtkm::RangeId& other) const
  {
    return ((this->Min != other.Min) || (this->Max != other.Max));
  }
};

} // namespace vtkm

/// Helper function for printing ranges during testing
///
static inline VTKM_CONT std::ostream& operator<<(std::ostream& stream, const vtkm::RangeId& range)
{
  return stream << "[" << range.Min << ".." << range.Max << ")";
}

#endif // vtk_m_RangeId_h