Skip to main content

gridly/grid/
view.rs

1use core::fmt::{self, Debug, Display, Formatter, Write};
2use core::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator};
3use core::marker::PhantomData;
4use core::ops::Index;
5
6use crate::grid::{BoundsError, GridBounds};
7use crate::location::{Column, Component as LocComponent, Location, LocationLike, Row};
8use crate::range::{ColumnRangeError, ComponentRange, LocationRange, RangeError, RowRangeError};
9
10// Add a usize to an isize, return an isize. Overflows if necessary.
11
12/// Base Reader trait for grids. This trait provides the grid's cell type,
13/// `Item`, and an unsafe getter method for fetching a cell at a bounds-checked
14/// location. It uses this unsafe getter, plus [`GridBounds`] based
15/// bounds-checking, to provide a comprehensive and safe interface for reading
16/// and iterating over elements in a grid.
17pub trait Grid: GridBounds {
18    /// The item type stored in the grid
19    type Item;
20
21    /// Get a reference to a cell, without doing bounds checking. Implementors
22    /// of this method are allowed to assume that bounds checking has already
23    /// been performed on the location, which means that implementors are allowed
24    /// to do their own unsafe `get` operations on the underlying storage,
25    /// where relevant / possible.
26    ///
27    /// # Safety
28    ///
29    /// Callers must ensure that the location has been bounds-checked before
30    /// calling this method. The safe interface to `Grid` automatically performs
31    /// this checking for you.
32    unsafe fn get_unchecked(&self, location: Location) -> &Self::Item;
33
34    /// Get a reference to a cell in a grid. Returns an error if the location
35    /// is out of bounds with the specific boundary violation.
36    #[inline]
37    fn get(&self, location: impl LocationLike) -> Result<&Self::Item, BoundsError> {
38        self.check_location(location)
39            .map(move |loc| unsafe { self.get_unchecked(loc) })
40    }
41
42    /// Get a view of a grid, over its rows or columns. A view of a grid is
43    /// similar to a slice, but instead of being a view over specific elements,
44    /// it's a view over the rows and columns. See `[View]` for details.
45    #[inline]
46    fn view<T: LocComponent>(&self) -> View<Self, T> {
47        View::new(self)
48    }
49
50    /// Get a view of a grid's rows. See `[View]` for details.
51    #[inline]
52    fn rows(&self) -> RowsView<Self> {
53        self.view()
54    }
55
56    /// Get a view of a grid's columns. See `[View]` for details.
57    #[inline]
58    fn columns(&self) -> ColumnsView<Self> {
59        self.view()
60    }
61
62    /// Get a view of a single row or column in a grid, without bounds
63    /// checking that row or column index.
64    ///
65    /// # Safety
66    ///
67    /// Callers must ensure that the index has been bounds-checked before
68    /// calling this method.
69    #[inline]
70    unsafe fn single_view_unchecked<T: LocComponent>(&self, index: T) -> SingleView<Self, T> {
71        SingleView::new_unchecked(self, index)
72    }
73
74    /// Get a view of a single row in a grid, without bounds checking that row's index.
75    ///
76    /// # Safety
77    ///
78    /// Callers must ensure that the row index has been bounds-checked before
79    /// calling this method.
80    #[inline]
81    unsafe fn row_unchecked(&self, row: Row) -> RowView<Self> {
82        self.single_view_unchecked(row)
83    }
84
85    /// Get a view of a single column in a grid, without bounds checking that column's index.
86    ///
87    /// # Safety
88    ///
89    /// Callers must ensure that the column index has been bounds-checked before
90    /// calling this method.
91    #[inline]
92    unsafe fn column_unchecked(&self, column: Column) -> ColumnView<Self> {
93        self.single_view_unchecked(column)
94    }
95
96    /// Get a view of a single row or column in a grid. Returns an error if the index of the
97    /// row or column is out of bounds for the grid.
98    #[inline]
99    fn single_view<T: LocComponent>(&self, index: T) -> Result<SingleView<Self, T>, RangeError<T>> {
100        SingleView::new(self, index)
101    }
102
103    /// Get a view of a single row in a grid. Returns an error if the index of the row is
104    /// out of bounds for the grid.
105    #[inline]
106    fn row(&self, row: impl Into<Row>) -> Result<RowView<Self>, RowRangeError> {
107        self.single_view(row.into())
108    }
109
110    /// Get a view of a single column in a grid. Returns an error if the index of the column
111    /// is out of bounds for the grid.
112    #[inline]
113    fn column(&self, column: impl Into<Column>) -> Result<ColumnView<Self>, ColumnRangeError> {
114        self.single_view(column.into())
115    }
116
117    /// Make a grid [`Display`]able, using a function that defines how each of its
118    /// cells are printed. For each row, the adapter simply prints each cell
119    /// in the row, followed by a newline.
120    ///
121    /// Note that this adapter doesn't make any attempt to ensure the printed
122    /// grid is visually a rectangle. It is up to the display adapter function
123    /// `func` to ensure that each cell has the same width when printed.
124    #[inline]
125    fn display_with<T, F>(&self, func: F) -> DisplayAdapter<&Self, F>
126    where
127        F: Fn(&Self::Item) -> T,
128        T: Display,
129    {
130        DisplayAdapter { grid: self, func }
131    }
132}
133
134impl<G: Grid> Grid for &G {
135    type Item = G::Item;
136
137    #[inline]
138    unsafe fn get_unchecked(&self, location: Location) -> &Self::Item {
139        G::get_unchecked(self, location)
140    }
141}
142
143impl<G: Grid> Grid for &mut G {
144    type Item = G::Item;
145
146    #[inline]
147    unsafe fn get_unchecked(&self, location: Location) -> &Self::Item {
148        G::get_unchecked(self, location)
149    }
150}
151
152// TODO: is there a compelling reason to separate View and ViewIter? Would it
153// be preferable to make View an iterator, directly? Right now the rationalle
154// is that it slightly complicates the mental model of `View`, since getting
155// an offset would be based on the current, partially iterated range.
156
157/// A view of the rows or columns in a grid.
158///
159/// This struct provides a row- or column-major view of a grid. For instance,
160/// a `View<MyGrid, Row>` is a view of all of the rows in `MyGrid`. The view
161/// can be indexed over its type (for instance, a `View<G, Row>` can be
162/// indexed by [`Row`]). It can also be iterated, where each iteration step
163/// produces a [`SingleView`], which is a view of a single row or column (that
164/// single view can itself be iterated to get all the cells).
165#[derive(Debug)]
166pub struct View<'a, G: Grid + ?Sized, T: LocComponent> {
167    grid: &'a G,
168    index: PhantomData<T>,
169}
170
171impl<'a, G: Grid + ?Sized, T: LocComponent> View<'a, G, T> {
172    /// Create a grid view. Grid views are pretty boring because they don't need
173    /// to include anything besides the grid itself; the important stuff is
174    /// encoded in the type.
175    #[inline]
176    fn new(grid: &'a G) -> Self {
177        Self {
178            grid,
179            index: PhantomData,
180        }
181    }
182
183    /// Get the length of this view; that is, the number of Rows or Columns
184    #[inline]
185    pub fn len(&self) -> T::Distance {
186        self.grid.dimension()
187    }
188
189    /// Get a view of a single row or column of the grid, without bounds checking
190    /// the index.
191    ///
192    /// # Safety
193    ///
194    /// Callers must ensure that the index has been bounds-checked before
195    /// calling this method.
196    #[inline]
197    pub unsafe fn get_unchecked(&self, index: T) -> SingleView<'a, G, T> {
198        SingleView::new_unchecked(self.grid, index)
199    }
200
201    /// Get a view of a single row or column of the grid. Returns a range error
202    /// if the index is out of range.
203    #[inline]
204    pub fn get(&self, index: T) -> Result<SingleView<'a, G, T>, RangeError<T>> {
205        SingleView::new(self.grid, index)
206    }
207
208    /// Get a range over all the row or column indexes of this view.
209    #[inline]
210    pub fn range(&self) -> ComponentRange<T> {
211        self.grid.range()
212    }
213
214    /// Create an iterator over the rows or columns of the grid. Each iterated
215    /// element is a [`SingleView`], which is a view over a single row or column
216    /// of the grid.
217    #[inline]
218    pub fn iter(
219        &self,
220    ) -> impl Iterator<Item = SingleView<'a, G, T>>
221           + DoubleEndedIterator
222           + FusedIterator
223           + ExactSizeIterator
224           + Debug
225           + Clone {
226        let grid = self.grid;
227        self.range()
228            .map(move |index| unsafe { SingleView::new_unchecked(grid, index) })
229    }
230}
231
232// Custom clone implementation, because View is `Clone` even if G and T are not
233impl<'a, G: Grid + ?Sized, T: LocComponent> Clone for View<'a, G, T> {
234    fn clone(&self) -> Self {
235        Self {
236            grid: self.grid,
237            index: PhantomData,
238        }
239    }
240}
241
242// TODO: impl Index for GridView. Requires Higher Kinded Lifetimes, because
243// Index currently requires an &'a T, but we want to return a GridSingleView<'a, T>
244// TODO: IntoIterator. We'd rather not maintain our own iterator type, so for
245// now we require uses to use the iter() method.
246
247/// A view over the rows of a grid.
248///
249/// See `View` for more details.
250pub type RowsView<'a, G> = View<'a, G, Row>;
251
252impl<'a, G: Grid + ?Sized> RowsView<'a, G> {
253    #[inline]
254    pub fn row(&self, row: impl Into<Row>) -> Result<RowView<'a, G>, RowRangeError> {
255        self.get(row.into())
256    }
257}
258
259/// A view over the columns of a grid.
260///
261/// See `View` for more details.
262pub type ColumnsView<'a, G> = View<'a, G, Column>;
263
264impl<'a, G: Grid + ?Sized> ColumnsView<'a, G> {
265    #[inline]
266    pub fn column(&self, column: impl Into<Column>) -> Result<ColumnView<'a, G>, ColumnRangeError> {
267        self.get(column.into())
268    }
269}
270
271/// View of a single Row or Column of a grid.
272///
273/// A `SingleView` provides a view over a single row or column of a grid, based
274/// on its generic parameter. For instance, a SingleView<'a, G, Row> is a view
275/// over a single row of a grid.
276///
277/// A `SingleView` can be indexed; for instance, a [`RowView`] can be indexed
278/// with a [`Column`] to a get a specific cell.
279#[derive(Debug)]
280pub struct SingleView<'a, G: Grid + ?Sized, T: LocComponent> {
281    grid: &'a G,
282
283    // Implementor notes: a GridSingleView's index field is guaranteed to
284    // have been bounds checked against the grid. Therefore, we provide
285    // unsafe and checked constructors, then freely use unsafe accessors
286    // in the safe interface.
287    index: T,
288}
289
290impl<'a, G: Grid + ?Sized, T: LocComponent> SingleView<'a, G, T> {
291    #[inline]
292    unsafe fn new_unchecked(grid: &'a G, index: T) -> Self {
293        Self { grid, index }
294    }
295
296    #[inline]
297    fn new(grid: &'a G, index: T) -> Result<Self, RangeError<T>> {
298        grid.check_component(index)
299            .map(move |index| unsafe { Self::new_unchecked(grid, index) })
300    }
301
302    /// Get the length of this view. For example, for a
303    /// `SingleView<'a, G, Row>`, get the number of columns.
304    #[inline]
305    pub fn len(&self) -> <T::Converse as LocComponent>::Distance {
306        self.grid.dimension()
307    }
308
309    /// Get the index of the Row or Column that this view represents. This index
310    /// is safely guaranteed to have been bounds checked when the `SingleView`
311    /// was constructed.
312    #[inline]
313    pub fn index(&self) -> T {
314        self.index
315    }
316
317    /// Get a particular cell in the row or column by an index, without bounds
318    /// checking the index.
319    ///
320    /// # Safety
321    ///
322    /// Callers must ensure that the index has been bounds-checked before
323    /// calling this method.
324    #[inline]
325    pub unsafe fn get_unchecked(&self, cross: T::Converse) -> &'a G::Item {
326        self.grid.get_unchecked(self.index.combine(cross))
327    }
328
329    /// Get a particular cell in the row or column, or return an error if the
330    /// index is out of bounds.
331    #[inline]
332    pub fn get(&self, cross: T::Converse) -> Result<&'a G::Item, RangeError<T::Converse>> {
333        self.grid
334            .check_component(cross)
335            .map(move |cross| unsafe { self.get_unchecked(cross) })
336    }
337
338    /// Get the specific locations associated with this view.
339    #[inline]
340    pub fn range(&self) -> LocationRange<T> {
341        LocationRange::new(self.index, self.grid.range())
342    }
343
344    /// Get an iterator over the cells in this row or column
345    #[inline]
346    pub fn iter(
347        &self,
348    ) -> impl Iterator<Item = &'a G::Item>
349           + DoubleEndedIterator
350           + FusedIterator
351           + ExactSizeIterator
352           + Debug
353           + Clone {
354        let grid = self.grid;
355        self.range()
356            .map(move |loc| unsafe { grid.get_unchecked(loc) })
357    }
358
359    /// Get an iterator over `(Location, &Item)` pairs for this row or column.
360    #[inline]
361    pub fn iter_with_locations(
362        &self,
363    ) -> impl Iterator<Item = (Location, &'a G::Item)>
364           + DoubleEndedIterator
365           + FusedIterator
366           + ExactSizeIterator
367           + Debug
368           + Clone {
369        let grid = self.grid;
370        self.range()
371            .map(move |loc| (loc, unsafe { grid.get_unchecked(loc) }))
372    }
373
374    /// Get an iterator over `(Index, &Item)` pairs for this column. For instance,
375    /// for a `RowView`, this iterates over `(Column, &Item)` pairs.
376    #[inline]
377    pub fn iter_with_indices(
378        &self,
379    ) -> impl Iterator<Item = (T::Converse, &'a G::Item)>
380           + DoubleEndedIterator
381           + FusedIterator
382           + ExactSizeIterator
383           + Debug
384           + Clone {
385        let grid = self.grid;
386
387        self.range()
388            .map(move |loc| (loc.get_component(), unsafe { grid.get_unchecked(loc) }))
389    }
390}
391
392impl<'a, G: Grid + ?Sized, T: LocComponent> Index<T::Converse> for SingleView<'a, G, T> {
393    type Output = G::Item;
394
395    #[inline]
396    fn index(&self, idx: T::Converse) -> &G::Item {
397        self.get(idx).unwrap_or_else(|err| match err {
398            RangeError::TooHigh(max) => panic!("{:?} too high, must be < {:?}", idx, max),
399            RangeError::TooLow(min) => panic!("{:?} too low, must be >= {:?}", idx, min),
400        })
401    }
402}
403
404// Manually implement clone, because T and G do not need to be clone.
405impl<'a, G: Grid + ?Sized, T: LocComponent> Clone for SingleView<'a, G, T> {
406    fn clone(&self) -> Self {
407        Self {
408            grid: self.grid,
409            index: self.index,
410        }
411    }
412}
413
414/// A view of a single row of a grid.
415///
416/// See [`SingleView`] for more details.
417pub type RowView<'a, G> = SingleView<'a, G, Row>;
418
419impl<'a, G: Grid + ?Sized> RowView<'a, G> {
420    /// Get a reference to the cell in a specific column of this view's row.
421    #[inline]
422    pub fn column(&self, column: impl Into<Column>) -> Result<&'a G::Item, ColumnRangeError> {
423        self.get(column.into())
424    }
425}
426
427/// A view of a single column of a grid.
428///
429/// See [`SingleView`] for more details.
430pub type ColumnView<'a, G> = SingleView<'a, G, Column>;
431
432impl<'a, G: Grid + ?Sized> ColumnView<'a, G> {
433    /// Get a reference to the cell in a specific row of this view's column.
434    #[inline]
435    pub fn row(&self, row: impl Into<Row>) -> Result<&'a G::Item, RowRangeError> {
436        self.get(row.into())
437    }
438}
439
440/// A wrapper around a grid, allowing it to be printed via [`Display`]. See
441/// [`Grid`]`::`[`display_with`][Grid::display_with] for details.
442#[derive(Debug, Copy, Clone)]
443pub struct DisplayAdapter<T, F> {
444    func: F,
445    grid: T,
446}
447
448impl<T, F, R> Display for DisplayAdapter<T, F>
449where
450    T: Grid,
451    F: Fn(&T::Item) -> R,
452    R: Display,
453{
454    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
455        let func = &self.func;
456
457        self.grid.rows().iter().try_for_each(move |row| {
458            row.iter().map(func).try_for_each(|cell| cell.fmt(f))?;
459            f.write_char('\n')
460        })
461    }
462}
463
464#[cfg(test)]
465mod tests {
466    use crate::grid::BoundsError;
467    use crate::prelude::*;
468    use crate::range::{ColumnRangeError, RangeError, RowRangeError};
469
470    // A stack-allocated grid with a fixed size of three rows by two columns.
471    // The root of this grid is (-1, 0), which means that the valid rows are
472    // [-1, 0, 1] and the valid columns are [0, 1]
473    #[derive(Debug, Eq, PartialEq)]
474    struct ThreeByTwo<T> {
475        rows: [[T; 2]; 3],
476    }
477
478    impl<T> GridBounds for ThreeByTwo<T> {
479        fn dimensions(&self) -> Vector {
480            Vector::new(3, 2)
481        }
482
483        fn root(&self) -> Location {
484            Location::new(-1, 0)
485        }
486    }
487
488    impl<T> Grid for ThreeByTwo<T> {
489        type Item = T;
490
491        unsafe fn get_unchecked(&self, location: Location) -> &T {
492            // Normally we don't need to bounds check the location, but for
493            // testing purposes we want to make sure that a location outside
494            // the valid bounds never gets through.
495            assert!(location.row.0 >= -1 && location.row.0 <= 1);
496            assert!(location.column.0 >= 0 && location.column.0 <= 1);
497
498            self.rows
499                .get_unchecked((location.row.0 + 1) as usize)
500                .get_unchecked(location.column.0 as usize)
501        }
502    }
503
504    static TEST_GRID: ThreeByTwo<i16> = ThreeByTwo {
505        rows: [[1, 2], [3, 4], [5, 6]],
506    };
507
508    static TEST_ROWS: [(Row, Option<RowRangeError>); 3] = [
509        (Row(-10), Some(RangeError::TooLow(Row(-1)))),
510        (Row(0), None),
511        (Row(10), Some(RangeError::TooHigh(Row(2)))),
512    ];
513
514    static TEST_COLUMNS: [(Column, Option<ColumnRangeError>); 3] = [
515        (Column(-10), Some(RangeError::TooLow(Column(0)))),
516        (Column(0), None),
517        (Column(10), Some(RangeError::TooHigh(Column(2)))),
518    ];
519
520    #[test]
521    fn test_get_in_bounds() {
522        let mut value = 1;
523
524        for row in Row(-1).span(Rows(3)) {
525            for column in Column(0).span(Columns(2)) {
526                assert_eq!(TEST_GRID.get(row + column), Ok(&value));
527                value += 1;
528            }
529        }
530    }
531
532    #[test]
533    fn test_out_of_bounds() {
534        for &(row, row_error) in &TEST_ROWS {
535            for &(column, column_error) in &TEST_COLUMNS {
536                let result = TEST_GRID.get(row + column);
537
538                match result {
539                    Err(BoundsError::Row(err)) => {
540                        assert_eq!(row_error, Some(err));
541                        assert_eq!(column_error, None);
542                    }
543                    Err(BoundsError::Column(err)) => {
544                        assert_eq!(row_error, None);
545                        assert_eq!(column_error, Some(err));
546                    }
547                    Err(BoundsError::Both { row, column }) => {
548                        assert_eq!(row_error, Some(row));
549                        assert_eq!(column_error, Some(column));
550                    }
551                    // We're only testing boundary errors here
552                    Ok(_) => {}
553                }
554            }
555        }
556    }
557
558    /*
559    // Set of view and iterator tests that test the row, column, and generic
560    // versions of all the relevant methods.
561    macro_rules! view_test_suite {
562        (
563            $suite_name:ident :
564            get_view: $get_view:ident,
565            get_single_view: $get_single_view_from_grid:ident,
566            get_single_view_from_view: $get_single_view_from_view:ident,
567            get_cell_from_single_view: $get_cell_from_single_view:ident,
568            get_len: $get_len:ident,
569            get_root: $get_root:ident,
570            Component: $Component:ident,
571            Distance: $Distance:ident,
572            Converse: $Converse:ident,
573            Range: $Range:ident,
574            RangeError: $RangeError:ident,
575            ConverseRangeError: $ConverseRangeError:ident,
576            View: $View:ident,
577            SingleView: $SingleView:ident,
578        ) => {
579            mod $suite_name {
580                use cool_asserts::assert_matches;
581
582                #[allow(unused_imports)]
583                use crate::prelude::*;
584                #[allow(unused_imports)]
585                use crate::range::{$Range, RowRangeError, ColumnRangeError, RangeError};
586                use super::{TEST_GRID, ThreeByTwo};
587
588                #[test]
589                fn test_view() {
590                    let min: $Component = TEST_GRID.$get_root();
591                    let len: $Distance = TEST_GRID.$get_len();
592                    let max: $Component = min + len;
593
594                    let view = TEST_GRID.$get_view();
595
596                    // For instance, assert view.len() == TEST_GRID.num_rows()
597                    assert_eq!(view.len(), len);
598
599                    // For instance, assert view.range() == RowRange(...)
600                    assert_eq!(view.range(), $Range::span(min, len));
601
602                    // For instance, assert row_view.get(Column(-10)) = Error(...)
603                    assert_matches!(
604                        view.$get_single_view_from_view($Component(-10)),
605                        Err($RangeError::TooLow(m)) if m == min
606                    );
607
608                    assert_matches!(
609                        view.$get_single_view_from_view($Component(10)),
610                        Err($RangeError::TooHigh(m)) if m == max
611                    );
612
613                    // We have a set of more comprehensive SingleView tests later,
614                    // so for now we just assert that they're constructed & bounds
615                    // checked correctly
616                    assert_matches!(
617                        view.$get_single_view_from_view($Component(0)),
618                        Ok(single_view) => {
619                            assert_eq!(
620                                single_view.grid as *const ThreeByTwo<i16>,
621                                view.grid as *const ThreeByTwo<i16>
622                            );
623                            assert_eq!(single_view.index, $Component(0));
624                        }
625                    );
626                }
627
628                #[test]
629                fn test_view_iter() {
630                    let min: $Component = TEST_GRID.$get_root();
631                    let len: $Distance = TEST_GRID.$get_len();
632                    let max: $Component = min + len;
633
634                    let view = TEST_GRID.$get_view();
635                    let iter = view.iter();
636                    let range = $Range::span(min, len);
637
638                    for (single_view, index) in iter.zip(range) {
639                        assert_eq!(
640                            single_view.grid as *const ThreeByTwo<i16>,
641                            view.grid as *const ThreeByTwo<i16>
642                        );
643                        assert_eq!(single_view.index, index);
644                    }
645                }
646
647                #[test]
648                fn test_single_view() {
649                    let single_view = TEST_GRID.$get_single_view_from_grid($Component(0))
650                        .expect("Unexpected bounds error");
651
652                    assert_eq!(
653                        single_view.grid as *const ThreeByTwo<i16>,
654                        &TEST_GRID as *const ThreeByTwo<i16>
655                    );
656                    assert_eq!(single_view.index, $Component(0));
657
658                    single_view.$get_cell_from_single_view($Converse(0));
659
660                    assert_eq!(
661                        single_view.$get_cell_from_single_view($Converse(-10)),
662                        Err(RangeError::TooLow($Converse(-10)))
663                    );
664
665                    assert_eq!(
666                        single_view.$get_cell_from_single_view($Converse(10)),
667                        Err(RangeError::TooHigh($Converse(10)))
668                    );
669
670                    assert_eq!(single_view.$get_cell_from_single_view($Converse(0)), Ok(&3));
671                }
672            }
673        }
674    }
675
676    view_test_suite! {
677        test_row_views:
678        get_view: rows,
679        get_single_view: row,
680        get_single_view_from_view: row,
681        get_cell_from_single_view: column,
682        get_len: num_rows,
683        get_root: root_row,
684        Component: Row,
685        Distance: Rows,
686        Converse: Column,
687        Range: RowRange,
688        RangeError: RowRangeError,
689        ConverseRangeError: ColumnRangeError,
690        View: RowsView,
691        SingleView: RowView,
692    }
693
694    view_test_suite! {
695        test_column_views:
696        get_view: columns,
697        get_single_view: column,
698        get_single_view_from_view: column,
699        get_cell_from_single_view: row,
700        get_len: num_columns,
701        get_root: root_column,
702        Component: Column,
703        Distance: Columns,
704        Converse: Row,
705        Range: ColumnRange,
706        RangeError: ColumnRangeError,
707        ConverseRangeError: RowRangeError,
708        View: ColumnsView,
709        SingleView: ColumnView,
710    }
711    */
712}