From 8621c86922fd298d07081ae15228fbb42223bd54 Mon Sep 17 00:00:00 2001 From: "Deployment Bot (from Travis CI)" Date: Mon, 4 Dec 2023 03:32:15 +0000 Subject: [PATCH] Deploy dsharlet/array to github.com/dsharlet/array.git:gh-pages --- absl_8h_source.html | 103 + annotated.html | 118 ++ array_8h.html | 1747 +++++++++++++++++ array_8h_source.html | 246 +++ arrowdown.png | Bin 0 -> 246 bytes arrowright.png | Bin 0 -> 229 bytes bc_s.png | Bin 0 -> 676 bytes bdwn.png | Bin 0 -> 147 bytes classes.html | 118 ++ classnda_1_1array-members.html | 186 ++ classnda_1_1array.html | 1215 ++++++++++++ classnda_1_1array__ref-members.html | 168 ++ classnda_1_1array__ref.html | 813 ++++++++ classnda_1_1auto__allocator-members.html | 122 ++ classnda_1_1auto__allocator.html | 178 ++ classnda_1_1copy__shape__traits-members.html | 110 ++ classnda_1_1copy__shape__traits.html | 188 ++ classnda_1_1dim-members.html | 154 ++ classnda_1_1dim.html | 426 ++++ classnda_1_1dim.png | Bin 0 -> 759 bytes classnda_1_1index__iterator-members.html | 121 ++ classnda_1_1index__iterator.html | 209 ++ classnda_1_1interval-members.html | 135 ++ classnda_1_1interval.html | 482 +++++ classnda_1_1interval.png | Bin 0 -> 761 bytes classnda_1_1shape-members.html | 171 ++ classnda_1_1shape.html | 889 +++++++++ classnda_1_1shape__traits-members.html | 110 ++ classnda_1_1shape__traits.html | 211 ++ ...nels_00_01_x_stride_01_4_01_4-members.html | 110 ++ ..._01_channels_00_01_x_stride_01_4_01_4.html | 129 ++ ...shape_3_01_channels_01_4_01_4-members.html | 110 ++ ..._image__shape_3_01_channels_01_4_01_4.html | 129 ++ ..._01_rows_00_01_cols_01_4_01_4-members.html | 110 ++ ..._shape_3_01_rows_00_01_cols_01_4_01_4.html | 129 ++ ...a_1_1uninitialized__allocator-members.html | 117 ++ classnda_1_1uninitialized__allocator.html | 174 ++ classnda_1_1uninitialized__allocator.png | Bin 0 -> 655 bytes closed.png | Bin 0 -> 132 bytes dir_1db1952525b7159ee5ea1c5d1ec74f56.html | 105 + dir_717b3188b45e89f652d81ea10aa11b1d.html | 120 ++ dir_d44c64559bbebec7f509842c48db8b23.html | 105 + doc.png | Bin 0 -> 746 bytes doxygen-awesome.css | 1454 ++++++++++++++ doxygen.css | 1475 ++++++++++++++ doxygen.png | Bin 0 -> 3779 bytes dynsections.js | 97 + ein__reduce_8h.html | 468 +++++ ein__reduce_8h_source.html | 122 ++ files.html | 110 ++ folderclosed.png | Bin 0 -> 616 bytes folderopen.png | Bin 0 -> 597 bytes functions.html | 368 ++++ functions_func.html | 346 ++++ functions_type.html | 122 ++ hierarchy.html | 118 ++ image_8h.html | 403 ++++ image_8h_source.html | 123 ++ index.html | 154 ++ jquery.js | 68 + matrix_8h.html | 245 +++ matrix_8h_source.html | 114 ++ md_CONTRIBUTING.html | 100 + nav_f.png | Bin 0 -> 153 bytes nav_g.png | Bin 0 -> 95 bytes nav_h.png | Bin 0 -> 98 bytes open.png | Bin 0 -> 123 bytes pages.html | 97 + search/all_0.html | 26 + search/all_0.js | 15 + search/all_1.html | 26 + search/all_1.js | 6 + search/all_10.html | 26 + search/all_10.js | 5 + search/all_11.html | 26 + search/all_11.js | 4 + search/all_12.html | 26 + search/all_12.js | 4 + search/all_13.html | 26 + search/all_13.js | 4 + search/all_2.html | 26 + search/all_2.js | 13 + search/all_3.html | 26 + search/all_3.js | 13 + search/all_4.html | 26 + search/all_4.js | 10 + search/all_5.html | 26 + search/all_5.js | 16 + search/all_6.html | 26 + search/all_6.js | 5 + search/all_7.html | 26 + search/all_7.js | 4 + search/all_8.html | 26 + search/all_8.js | 21 + search/all_9.html | 26 + search/all_9.js | 20 + search/all_a.html | 26 + search/all_a.js | 9 + search/all_b.html | 26 + search/all_b.js | 4 + search/all_c.html | 26 + search/all_c.js | 13 + search/all_d.html | 26 + search/all_d.js | 19 + search/all_e.html | 26 + search/all_e.js | 6 + search/all_f.html | 26 + search/all_f.js | 7 + search/classes_0.html | 26 + search/classes_0.js | 6 + search/classes_1.html | 26 + search/classes_1.js | 4 + search/classes_2.html | 26 + search/classes_2.js | 4 + search/classes_3.html | 26 + search/classes_3.js | 5 + search/classes_4.html | 26 + search/classes_4.js | 8 + search/classes_5.html | 26 + search/classes_5.js | 4 + search/close.png | Bin 0 -> 273 bytes search/files_0.html | 26 + search/files_0.js | 4 + search/files_1.html | 26 + search/files_1.js | 4 + search/files_2.html | 26 + search/files_2.js | 4 + search/files_3.html | 26 + search/files_3.js | 4 + search/files_4.html | 26 + search/files_4.js | 4 + search/functions_0.html | 26 + search/functions_0.js | 6 + search/functions_1.html | 26 + search/functions_1.js | 5 + search/functions_2.html | 26 + search/functions_2.js | 11 + search/functions_3.html | 26 + search/functions_3.js | 6 + search/functions_4.html | 26 + search/functions_4.js | 9 + search/functions_5.html | 26 + search/functions_5.js | 13 + search/functions_6.html | 26 + search/functions_6.js | 5 + search/functions_7.html | 26 + search/functions_7.js | 14 + search/functions_8.html | 26 + search/functions_8.js | 17 + search/functions_9.html | 26 + search/functions_9.js | 9 + search/functions_a.html | 26 + search/functions_a.js | 13 + search/functions_b.html | 26 + search/functions_b.js | 10 + search/functions_c.html | 26 + search/functions_c.js | 6 + search/functions_d.html | 26 + search/functions_d.js | 4 + search/functions_e.html | 26 + search/functions_e.js | 4 + search/mag_sel.png | Bin 0 -> 563 bytes search/nomatches.html | 12 + search/pages_0.html | 26 + search/pages_0.js | 4 + search/pages_1.html | 26 + search/pages_1.js | 4 + search/search.css | 271 +++ search/search.js | 791 ++++++++ search/search_l.png | Bin 0 -> 604 bytes search/search_m.png | Bin 0 -> 158 bytes search/search_r.png | Bin 0 -> 612 bytes search/searchdata.js | 33 + search/typedefs_0.html | 26 + search/typedefs_0.js | 6 + search/typedefs_1.html | 26 + search/typedefs_1.js | 4 + search/typedefs_2.html | 26 + search/typedefs_2.js | 4 + search/typedefs_3.html | 26 + search/typedefs_3.js | 8 + search/typedefs_4.html | 26 + search/typedefs_4.js | 6 + search/typedefs_5.html | 26 + search/typedefs_5.js | 7 + search/typedefs_6.html | 26 + search/typedefs_6.js | 5 + search/typedefs_7.html | 26 + search/typedefs_7.js | 4 + search/typedefs_8.html | 26 + search/typedefs_8.js | 7 + search/typedefs_9.html | 26 + search/typedefs_9.js | 5 + search/typedefs_a.html | 26 + search/typedefs_a.js | 5 + search/variables_0.html | 26 + search/variables_0.js | 4 + search/variables_1.html | 26 + search/variables_1.js | 4 + search/variables_2.html | 26 + search/variables_2.js | 4 + splitbar.png | Bin 0 -> 314 bytes sync_off.png | Bin 0 -> 853 bytes sync_on.png | Bin 0 -> 845 bytes tab_a.png | Bin 0 -> 142 bytes tab_b.png | Bin 0 -> 169 bytes tab_h.png | Bin 0 -> 177 bytes tab_s.png | Bin 0 -> 184 bytes tabs.css | 60 + z__order_8h.html | 152 ++ z__order_8h_source.html | 105 + 211 files changed, 19040 insertions(+) create mode 100644 absl_8h_source.html create mode 100644 annotated.html create mode 100644 array_8h.html create mode 100644 array_8h_source.html create mode 100644 arrowdown.png create mode 100644 arrowright.png create mode 100644 bc_s.png create mode 100644 bdwn.png create mode 100644 classes.html create mode 100644 classnda_1_1array-members.html create mode 100644 classnda_1_1array.html create mode 100644 classnda_1_1array__ref-members.html create mode 100644 classnda_1_1array__ref.html create mode 100644 classnda_1_1auto__allocator-members.html create mode 100644 classnda_1_1auto__allocator.html create mode 100644 classnda_1_1copy__shape__traits-members.html create mode 100644 classnda_1_1copy__shape__traits.html create mode 100644 classnda_1_1dim-members.html create mode 100644 classnda_1_1dim.html create mode 100644 classnda_1_1dim.png create mode 100644 classnda_1_1index__iterator-members.html create mode 100644 classnda_1_1index__iterator.html create mode 100644 classnda_1_1interval-members.html create mode 100644 classnda_1_1interval.html create mode 100644 classnda_1_1interval.png create mode 100644 classnda_1_1shape-members.html create mode 100644 classnda_1_1shape.html create mode 100644 classnda_1_1shape__traits-members.html create mode 100644 classnda_1_1shape__traits.html create mode 100644 classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_00_01_x_stride_01_4_01_4-members.html create mode 100644 classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_00_01_x_stride_01_4_01_4.html create mode 100644 classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_01_4_01_4-members.html create mode 100644 classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_01_4_01_4.html create mode 100644 classnda_1_1shape__traits_3_01matrix__shape_3_01_rows_00_01_cols_01_4_01_4-members.html create mode 100644 classnda_1_1shape__traits_3_01matrix__shape_3_01_rows_00_01_cols_01_4_01_4.html create mode 100644 classnda_1_1uninitialized__allocator-members.html create mode 100644 classnda_1_1uninitialized__allocator.html create mode 100644 classnda_1_1uninitialized__allocator.png create mode 100644 closed.png create mode 100644 dir_1db1952525b7159ee5ea1c5d1ec74f56.html create mode 100644 dir_717b3188b45e89f652d81ea10aa11b1d.html create mode 100644 dir_d44c64559bbebec7f509842c48db8b23.html create mode 100644 doc.png create mode 100644 doxygen-awesome.css create mode 100644 doxygen.css create mode 100644 doxygen.png create mode 100644 dynsections.js create mode 100644 ein__reduce_8h.html create mode 100644 ein__reduce_8h_source.html create mode 100644 files.html create mode 100644 folderclosed.png create mode 100644 folderopen.png create mode 100644 functions.html create mode 100644 functions_func.html create mode 100644 functions_type.html create mode 100644 hierarchy.html create mode 100644 image_8h.html create mode 100644 image_8h_source.html create mode 100644 index.html create mode 100644 jquery.js create mode 100644 matrix_8h.html create mode 100644 matrix_8h_source.html create mode 100644 md_CONTRIBUTING.html create mode 100644 nav_f.png create mode 100644 nav_g.png create mode 100644 nav_h.png create mode 100644 open.png create mode 100644 pages.html create mode 100644 search/all_0.html create mode 100644 search/all_0.js create mode 100644 search/all_1.html create mode 100644 search/all_1.js create mode 100644 search/all_10.html create mode 100644 search/all_10.js create mode 100644 search/all_11.html create mode 100644 search/all_11.js create mode 100644 search/all_12.html create mode 100644 search/all_12.js create mode 100644 search/all_13.html create mode 100644 search/all_13.js create mode 100644 search/all_2.html create mode 100644 search/all_2.js create mode 100644 search/all_3.html create mode 100644 search/all_3.js create mode 100644 search/all_4.html create mode 100644 search/all_4.js create mode 100644 search/all_5.html create mode 100644 search/all_5.js create mode 100644 search/all_6.html create mode 100644 search/all_6.js create mode 100644 search/all_7.html create mode 100644 search/all_7.js create mode 100644 search/all_8.html create mode 100644 search/all_8.js create mode 100644 search/all_9.html create mode 100644 search/all_9.js create mode 100644 search/all_a.html create mode 100644 search/all_a.js create mode 100644 search/all_b.html create mode 100644 search/all_b.js create mode 100644 search/all_c.html create mode 100644 search/all_c.js create mode 100644 search/all_d.html create mode 100644 search/all_d.js create mode 100644 search/all_e.html create mode 100644 search/all_e.js create mode 100644 search/all_f.html create mode 100644 search/all_f.js create mode 100644 search/classes_0.html create mode 100644 search/classes_0.js create mode 100644 search/classes_1.html create mode 100644 search/classes_1.js create mode 100644 search/classes_2.html create mode 100644 search/classes_2.js create mode 100644 search/classes_3.html create mode 100644 search/classes_3.js create mode 100644 search/classes_4.html create mode 100644 search/classes_4.js create mode 100644 search/classes_5.html create mode 100644 search/classes_5.js create mode 100644 search/close.png create mode 100644 search/files_0.html create mode 100644 search/files_0.js create mode 100644 search/files_1.html create mode 100644 search/files_1.js create mode 100644 search/files_2.html create mode 100644 search/files_2.js create mode 100644 search/files_3.html create mode 100644 search/files_3.js create mode 100644 search/files_4.html create mode 100644 search/files_4.js create mode 100644 search/functions_0.html create mode 100644 search/functions_0.js create mode 100644 search/functions_1.html create mode 100644 search/functions_1.js create mode 100644 search/functions_2.html create mode 100644 search/functions_2.js create mode 100644 search/functions_3.html create mode 100644 search/functions_3.js create mode 100644 search/functions_4.html create mode 100644 search/functions_4.js create mode 100644 search/functions_5.html create mode 100644 search/functions_5.js create mode 100644 search/functions_6.html create mode 100644 search/functions_6.js create mode 100644 search/functions_7.html create mode 100644 search/functions_7.js create mode 100644 search/functions_8.html create mode 100644 search/functions_8.js create mode 100644 search/functions_9.html create mode 100644 search/functions_9.js create mode 100644 search/functions_a.html create mode 100644 search/functions_a.js create mode 100644 search/functions_b.html create mode 100644 search/functions_b.js create mode 100644 search/functions_c.html create mode 100644 search/functions_c.js create mode 100644 search/functions_d.html create mode 100644 search/functions_d.js create mode 100644 search/functions_e.html create mode 100644 search/functions_e.js create mode 100644 search/mag_sel.png create mode 100644 search/nomatches.html create mode 100644 search/pages_0.html create mode 100644 search/pages_0.js create mode 100644 search/pages_1.html create mode 100644 search/pages_1.js create mode 100644 search/search.css create mode 100644 search/search.js create mode 100644 search/search_l.png create mode 100644 search/search_m.png create mode 100644 search/search_r.png create mode 100644 search/searchdata.js create mode 100644 search/typedefs_0.html create mode 100644 search/typedefs_0.js create mode 100644 search/typedefs_1.html create mode 100644 search/typedefs_1.js create mode 100644 search/typedefs_2.html create mode 100644 search/typedefs_2.js create mode 100644 search/typedefs_3.html create mode 100644 search/typedefs_3.js create mode 100644 search/typedefs_4.html create mode 100644 search/typedefs_4.js create mode 100644 search/typedefs_5.html create mode 100644 search/typedefs_5.js create mode 100644 search/typedefs_6.html create mode 100644 search/typedefs_6.js create mode 100644 search/typedefs_7.html create mode 100644 search/typedefs_7.js create mode 100644 search/typedefs_8.html create mode 100644 search/typedefs_8.js create mode 100644 search/typedefs_9.html create mode 100644 search/typedefs_9.js create mode 100644 search/typedefs_a.html create mode 100644 search/typedefs_a.js create mode 100644 search/variables_0.html create mode 100644 search/variables_0.js create mode 100644 search/variables_1.html create mode 100644 search/variables_1.js create mode 100644 search/variables_2.html create mode 100644 search/variables_2.js create mode 100644 splitbar.png create mode 100644 sync_off.png create mode 100644 sync_on.png create mode 100644 tab_a.png create mode 100644 tab_b.png create mode 100644 tab_h.png create mode 100644 tab_s.png create mode 100644 tabs.css create mode 100644 z__order_8h.html create mode 100644 z__order_8h_source.html diff --git a/absl_8h_source.html b/absl_8h_source.html new file mode 100644 index 00000000..d28a556a --- /dev/null +++ b/absl_8h_source.html @@ -0,0 +1,103 @@ + + + + + + +array: absl/absl.h Source File + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
absl.h
+
+
+
1 #ifndef NDARRAY_ABSL_ABSL_H
2 #define NDARRAY_ABSL_ABSL_H
3 
4 #include "absl/strings/str_format.h"
5 #include "absl/strings/str_join.h"
6 #include "array/array.h"
7 
8 // Adds Abseil Stringify support (https://abseil.io/blog/20221115-stringify).
9 
10 namespace nda {
11 
12 // interval -> string as the half-open interval [begin, end).
13 //
14 // Stringifies only the values, not whether they are static or dynamic.
15 template <typename Sink, index_t Min, index_t Extent>
16 void AbslStringify(Sink& sink, const interval<Min, Extent>& i) {
17  absl::Format(&sink, "[%v, %v)", i.min(), i.min() + i.extent());
18 }
19 
20 // dim -> string as "dim(min, extent, stride)".
21 //
22 // Stringifies only the values, not whether they are static or dynamic.
23 template <typename Sink, index_t Min, index_t Extent, index_t Stride>
24 void AbslStringify(Sink& sink, const dim<Min, Extent, Stride>& d) {
25  if (internal::is_resolved(d.stride())) {
26  absl::Format(&sink, "dim(%v, %v, %v)", d.min(), d.extent(), d.stride());
27  } else {
28  absl::Format(&sink, "dim(%v, %v)", d.min(), d.extent());
29  }
30 }
31 
32 // shape -> string as "shape<`rank`>(dims...).
33 //
34 // Stringifies only the rank and each dim's values, not whether they are static
35 // or dynamic.
36 template <typename Sink, class... Dims>
37 void AbslStringify(Sink& sink, const shape<Dims...>& sh) {
38  absl::Format(&sink, "shape<%d>(%v)", sh.rank(), absl::StrJoin(sh.dims(), ", "));
39 }
40 
41 } // namespace nda
42 
43 #endif // NDARRAY_ABSL_ABSL_H
Main header for array library.
+
Definition: absl.h:10
+
+ + + + diff --git a/annotated.html b/annotated.html new file mode 100644 index 00000000..76667e1d --- /dev/null +++ b/annotated.html @@ -0,0 +1,118 @@ + + + + + + +array: Class List + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class List
+
+
+
Here are the classes, structs, unions and interfaces with brief descriptions:
+
+ + + + diff --git a/array_8h.html b/array_8h.html new file mode 100644 index 00000000..960ca2a6 --- /dev/null +++ b/array_8h.html @@ -0,0 +1,1747 @@ + + + + + + +array: include/array/array.h File Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
array.h File Reference
+
+
+ +

Main header for array library. +More...

+
#include <array>
+#include <cassert>
+#include <cstdio>
+#include <limits>
+#include <memory>
+#include <tuple>
+#include <type_traits>
+
+

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Classes

class  index_iterator
 
class  dim< Min_, Extent_, Stride_ >
 
class  interval< Min_, Extent_ >
 
class  dim< Min_, Extent_, Stride_ >
 
class  shape< Dims >
 
class  shape< Dims >
 
class  shape_traits< Shape >
 
class  copy_shape_traits< ShapeSrc, ShapeDst >
 
class  array_ref< T, Shape >
 
class  array< T, Shape, Alloc >
 
class  array_ref< T, Shape >
 
class  array< T, Shape, Alloc >
 
class  auto_allocator< T, N, Alignment, BaseAlloc >
 
class  uninitialized_allocator< BaseAlloc >
 
+ + + + + + + + + + + + + +

+Macros

+#define NDARRAY_INLINE   inline
 
+#define NDARRAY_UNIQUE   static
 
+#define NDARRAY_HOST_DEVICE
 
+#define NDARRAY_RESTRICT
 
+#define NDARRAY_PRINT_ERR(...)   fprintf(stderr, __VA_ARGS__)
 
+#define NDARRAY_INDEX_T_FMT   "%td"
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Typedefs

+using size_t = std::size_t
 
using index_t = std::ptrdiff_t
 
template<index_t Extent>
using fixed_interval = interval< dynamic, Extent >
 
template<index_t Extent, index_t Stride = dynamic>
using fixed_dim = dim< dynamic, Extent, Stride >
 
template<index_t Min = dynamic, index_t Extent = dynamic>
using dense_dim = dim< Min, Extent, 1 >
 
template<index_t Stride>
using strided_dim = dim< dynamic, dynamic, Stride >
 
template<index_t Min = dynamic, index_t Extent = dynamic>
using broadcast_dim = dim< Min, Extent, 0 >
 
template<size_t Rank>
using index_of_rank = internal::tuple_of_n< index_t, Rank >
 
template<size_t Rank>
using shape_of_rank = decltype(make_shape_from_tuple(internal::tuple_of_n< dim<>, Rank >()))
 
template<size_t Rank>
using dense_shape = decltype(internal::make_default_dense_shape< Rank >())
 
template<index_t... Extents>
using fixed_dense_shape = decltype(make_shape_from_tuple(internal::make_compact_dims< 1 >(dim< 0, Extents >()...)))
 
+template<class T , class Shape >
using const_array_ref = array_ref< const T, Shape >
 
template<class T , size_t Rank>
using array_ref_of_rank = array_ref< T, shape_of_rank< Rank >>
 
+template<class T , size_t Rank>
using const_array_ref_of_rank = array_ref_of_rank< const T, Rank >
 
template<class T , size_t Rank>
using dense_array_ref = array_ref< T, dense_shape< Rank >>
 
+template<class T , size_t Rank>
using const_dense_array_ref = dense_array_ref< const T, Rank >
 
template<class T , size_t Rank, class Alloc = std::allocator<T>>
using array_of_rank = array< T, shape_of_rank< Rank >, Alloc >
 
template<class T , size_t Rank, class Alloc = std::allocator<T>>
using dense_array = array< T, dense_shape< Rank >, Alloc >
 
template<class T , class = std::enable_if_t<std::is_trivial<T>::value>>
using uninitialized_std_allocator = uninitialized_allocator< std::allocator< T >>
 
template<class T , size_t N, size_t Alignment = sizeof(T), class = std::enable_if_t<std::is_trivial<T>::value>>
using uninitialized_auto_allocator = uninitialized_allocator< auto_allocator< T, N, Alignment >>
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

NDARRAY_INLINE NDARRAY_HOST_DEVICE interval range (index_t begin, index_t end)
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE interval r (index_t begin, index_t end)
 
template<index_t Extent>
NDARRAY_HOST_DEVICE fixed_interval< Extent > range (index_t begin)
 
+template<index_t Extent>
NDARRAY_HOST_DEVICE fixed_interval< Extent > r (index_t begin)
 
template<index_t Min, index_t Extent>
NDARRAY_HOST_DEVICE index_iterator begin (const interval< Min, Extent > &d)
 
+template<index_t Min, index_t Extent>
NDARRAY_HOST_DEVICE index_iterator end (const interval< Min, Extent > &d)
 
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t clamp (index_t x, index_t min, index_t max)
 
template<class Range >
NDARRAY_HOST_DEVICE index_t clamp (index_t x, const Range &r)
 
template<index_t InnerExtent, index_t Min, index_t Extent>
NDARRAY_HOST_DEVICE internal::split_result< InnerExtent > split (const interval< Min, Extent > &v)
 
+template<index_t InnerExtent, index_t Min, index_t Extent, index_t Stride>
NDARRAY_HOST_DEVICE internal::split_result< InnerExtent > split (const dim< Min, Extent, Stride > &v)
 
template<index_t Min, index_t Extent>
NDARRAY_HOST_DEVICE internal::split_result split (const interval< Min, Extent > &v, index_t inner_extent)
 
+template<index_t Min, index_t Extent, index_t Stride>
NDARRAY_HOST_DEVICE internal::split_result split (const dim< Min, Extent, Stride > &v, index_t inner_extent)
 
template<class... Dims>
NDARRAY_HOST_DEVICE auto make_shape (Dims...dims)
 
+template<class... Dims>
NDARRAY_HOST_DEVICE shape< Dims... > make_shape_from_tuple (const std::tuple< Dims... > &dims)
 
template<size_t... DimIndices, class... Dims, class = internal::enable_if_permutation<sizeof...(DimIndices), DimIndices...>>
NDARRAY_HOST_DEVICE auto transpose (const shape< Dims... > &shape)
 
template<size_t... DimIndices, class... Dims>
NDARRAY_HOST_DEVICE auto reorder (const shape< Dims... > &shape)
 
template<class Shape >
NDARRAY_HOST_DEVICE auto make_compact (const Shape &s)
 
template<class ShapeDst , class ShapeSrc , class = internal::enable_if_shapes_compatible<ShapeSrc, ShapeDst>>
NDARRAY_HOST_DEVICE bool is_compatible (const ShapeSrc &src)
 
template<class ShapeDst , class ShapeSrc , class = internal::enable_if_shapes_explicitly_compatible<ShapeDst, ShapeSrc>>
NDARRAY_HOST_DEVICE ShapeDst convert_shape (const ShapeSrc &src)
 
template<class ShapeDst , class ShapeSrc , class = internal::enable_if_shapes_explicitly_compatible<ShapeSrc, ShapeDst>>
NDARRAY_HOST_DEVICE bool is_explicitly_compatible (const ShapeSrc &src)
 
template<class Shape , class Fn , class = internal::enable_if_callable<Fn, typename Shape::index_type>>
NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_index_in_order (const Shape &shape, Fn &&fn)
 
+template<class Shape , class Ptr , class Fn , class = internal::enable_if_callable<Fn, typename std::remove_pointer<Ptr>::type&>>
NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_value_in_order (const Shape &shape, Ptr base, Fn &&fn)
 
template<class Shape , class ShapeA , class PtrA , class ShapeB , class PtrB , class Fn , class = internal::enable_if_callable<Fn, typename std::remove_pointer<PtrA>::type&, typename std::remove_pointer<PtrB>::type&>>
NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_value_in_order (const Shape &shape, const ShapeA &shape_a, PtrA base_a, const ShapeB &shape_b, PtrB base_b, Fn &&fn)
 
template<size_t... LoopOrder, class Shape , class Fn , class = internal::enable_if_callable<Fn, typename Shape::index_type>, std::enable_if_t<(sizeof...(LoopOrder)==0), int > = 0>
NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_index (const Shape &s, Fn &&fn)
 
+template<size_t... LoopOrder, class Shape , class Fn , class = internal::enable_if_applicable<Fn, typename Shape::index_type>, std::enable_if_t<(sizeof...(LoopOrder)==0), int > = 0>
NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_all_indices (const Shape &s, Fn &&fn)
 
template<class T , class Shape >
NDARRAY_HOST_DEVICE array_ref< T, Shape > make_array_ref (T *base, const Shape &shape)
 
template<class T , class Shape , class Alloc = std::allocator<T>, class = internal::enable_if_allocator<Alloc>>
auto make_array (const Shape &shape, const Alloc &alloc=Alloc())
 
+template<class T , class Shape , class Alloc = std::allocator<T>, class = internal::enable_if_allocator<Alloc>>
auto make_array (const Shape &shape, const T &value, const Alloc &alloc=Alloc())
 
template<class T , class Shape , class Alloc >
void swap (array< T, Shape, Alloc > &a, array< T, Shape, Alloc > &b)
 
template<class TSrc , class TDst , class ShapeSrc , class ShapeDst , class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
void copy (const array_ref< TSrc, ShapeSrc > &src, const array_ref< TDst, ShapeDst > &dst)
 
+template<class TSrc , class TDst , class ShapeSrc , class ShapeDst , class AllocDst , class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
void copy (const array_ref< TSrc, ShapeSrc > &src, array< TDst, ShapeDst, AllocDst > &dst)
 
+template<class TSrc , class TDst , class ShapeSrc , class ShapeDst , class AllocSrc , class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
void copy (const array< TSrc, ShapeSrc, AllocSrc > &src, const array_ref< TDst, ShapeDst > &dst)
 
+template<class TSrc , class TDst , class ShapeSrc , class ShapeDst , class AllocSrc , class AllocDst , class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
void copy (const array< TSrc, ShapeSrc, AllocSrc > &src, array< TDst, ShapeDst, AllocDst > &dst)
 
template<class T , class ShapeSrc , class Alloc = std::allocator<typename std::remove_const<T>::type>>
auto make_copy (const array_ref< T, ShapeSrc > &src, const Alloc &alloc=Alloc())
 
+template<class T , class ShapeSrc , class AllocSrc , class AllocDst = AllocSrc, class = internal::enable_if_allocator<AllocDst>>
auto make_copy (const array< T, ShapeSrc, AllocSrc > &src, const AllocDst &alloc=AllocDst())
 
template<class T , class ShapeSrc , class ShapeDst , class Alloc = std::allocator<typename std::remove_const<T>::type>, class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
auto make_copy (const array_ref< T, ShapeSrc > &src, const ShapeDst &shape, const Alloc &alloc=Alloc())
 
+template<class T , class ShapeSrc , class ShapeDst , class AllocSrc , class AllocDst = AllocSrc, class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
auto make_copy (const array< T, ShapeSrc, AllocSrc > &src, const ShapeDst &shape, const AllocDst &alloc=AllocDst())
 
template<class T , class Shape , class Alloc = std::allocator<typename std::remove_const<T>::type>>
auto make_compact_copy (const array_ref< T, Shape > &src, const Alloc &alloc=Alloc())
 
+template<class T , class Shape , class AllocSrc , class AllocDst = AllocSrc>
auto make_compact_copy (const array< T, Shape, AllocSrc > &src, const AllocDst &alloc=AllocDst())
 
template<class TSrc , class TDst , class ShapeSrc , class ShapeDst , class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
void move (const array_ref< TSrc, ShapeSrc > &src, const array_ref< TDst, ShapeDst > &dst)
 
+template<class TSrc , class TDst , class ShapeSrc , class ShapeDst , class AllocDst , class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
void move (const array_ref< TSrc, ShapeSrc > &src, array< TDst, ShapeDst, AllocDst > &dst)
 
+template<class TSrc , class TDst , class ShapeSrc , class ShapeDst , class AllocSrc , class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
void move (array< TSrc, ShapeSrc, AllocSrc > &src, const array_ref< TDst, ShapeDst > &dst)
 
+template<class TSrc , class TDst , class ShapeSrc , class ShapeDst , class AllocSrc , class AllocDst , class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
void move (array< TSrc, ShapeSrc, AllocSrc > &src, array< TDst, ShapeDst, AllocDst > &dst)
 
+template<class T , class Shape , class Alloc >
void move (array< T, Shape, Alloc > &&src, array< T, Shape, Alloc > &dst)
 
template<class T , class ShapeSrc , class ShapeDst , class Alloc = std::allocator<T>, class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
auto make_move (const array_ref< T, ShapeSrc > &src, const ShapeDst &shape, const Alloc &alloc=Alloc())
 
+template<class T , class ShapeSrc , class ShapeDst , class AllocSrc , class AllocDst = AllocSrc, class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
auto make_move (array< T, ShapeSrc, AllocSrc > &src, const ShapeDst &shape, const AllocDst &alloc=AllocDst())
 
+template<class T , class Shape , class Alloc >
auto make_move (array< T, Shape, Alloc > &&src, const Shape &shape, const Alloc &alloc=Alloc())
 
template<class T , class Shape , class Alloc = std::allocator<T>>
auto make_compact_move (const array_ref< T, Shape > &src, const Alloc &alloc=Alloc())
 
+template<class T , class Shape , class AllocSrc , class AllocDst = AllocSrc>
auto make_compact_move (array< T, Shape, AllocSrc > &src, const AllocDst &alloc=AllocDst())
 
+template<class T , class Shape , class Alloc >
auto make_compact_move (array< T, Shape, Alloc > &&src, const Alloc &alloc=Alloc())
 
template<class T , class Shape >
NDARRAY_HOST_DEVICE void fill (const array_ref< T, Shape > &dst, const T &value)
 
+template<class T , class Shape , class Alloc >
void fill (array< T, Shape, Alloc > &dst, const T &value)
 
template<class T , class Shape , class Generator , class = internal::enable_if_callable<Generator>>
NDARRAY_HOST_DEVICE void generate (const array_ref< T, Shape > &dst, Generator &&g)
 
+template<class T , class Shape , class Alloc , class Generator , class = internal::enable_if_callable<Generator>>
void generate (array< T, Shape, Alloc > &dst, Generator &&g)
 
template<typename T , typename Shape , class Fn >
NDARRAY_HOST_DEVICE void transform_index (const array_ref< T, Shape > &dst, Fn &&fn)
 
+template<typename T , typename Shape , class Fn >
void transform_index (array< T, Shape > &dst, Fn &&fn)
 
template<typename T , typename Shape , class Fn >
NDARRAY_HOST_DEVICE void transform_indices (const array_ref< T, Shape > &dst, Fn &&fn)
 
+template<typename T , typename Shape , class Fn >
void transform_indices (array< T, Shape > &dst, Fn &&fn)
 
template<class TA , class ShapeA , class TB , class ShapeB >
NDARRAY_HOST_DEVICE bool equal (const array_ref< TA, ShapeA > &a, const array_ref< TB, ShapeB > &b)
 
+template<class TA , class ShapeA , class TB , class ShapeB , class AllocB >
bool equal (const array_ref< TA, ShapeA > &a, const array< TB, ShapeB, AllocB > &b)
 
+template<class TA , class ShapeA , class AllocA , class TB , class ShapeB >
bool equal (const array< TA, ShapeA, AllocA > &a, const array_ref< TB, ShapeB > &b)
 
+template<class TA , class ShapeA , class AllocA , class TB , class ShapeB , class AllocB >
bool equal (const array< TA, ShapeA, AllocA > &a, const array< TB, ShapeB, AllocB > &b)
 
template<class NewShape , class T , class OldShape >
NDARRAY_HOST_DEVICE array_ref< T, NewShape > convert_shape (const array_ref< T, OldShape > &a)
 
+template<class NewShape , class T , class OldShape , class Allocator >
array_ref< T, NewShape > convert_shape (array< T, OldShape, Allocator > &a)
 
+template<class NewShape , class T , class OldShape , class Allocator >
const_array_ref< T, NewShape > convert_shape (const array< T, OldShape, Allocator > &a)
 
template<class U , class T , class Shape , class = std::enable_if_t<sizeof(T) == sizeof(U)>>
NDARRAY_HOST_DEVICE array_ref< U, Shape > reinterpret (const array_ref< T, Shape > &a)
 
+template<class U , class T , class Shape , class Alloc , class = std::enable_if_t<sizeof(T) == sizeof(U)>>
array_ref< U, Shape > reinterpret (array< T, Shape, Alloc > &a)
 
+template<class U , class T , class Shape , class Alloc , class = std::enable_if_t<sizeof(T) == sizeof(U)>>
const_array_ref< U, Shape > reinterpret (const array< T, Shape, Alloc > &a)
 
template<class U , class T , class Shape >
array_ref< U, Shape > reinterpret_const (const const_array_ref< T, Shape > &a)
 
template<class NewShape , class T , class OldShape >
NDARRAY_HOST_DEVICE array_ref< T, NewShape > reinterpret_shape (const array_ref< T, OldShape > &a, const NewShape &new_shape, index_t offset=0)
 
+template<class NewShape , class T , class OldShape , class Allocator >
array_ref< T, NewShape > reinterpret_shape (array< T, OldShape, Allocator > &a, const NewShape &new_shape, index_t offset=0)
 
+template<class NewShape , class T , class OldShape , class Allocator >
const_array_ref< T, NewShape > reinterpret_shape (const array< T, OldShape, Allocator > &a, const NewShape &new_shape, index_t offset=0)
 
template<typename NewShape , typename T , typename OldShape , typename Alloc >
array< T, NewShape, Alloc > move_reinterpret_shape (array< T, OldShape, Alloc > &&from, const NewShape &new_shape, index_t offset=0)
 
+template<typename NewShape , typename T , typename OldShape , typename Alloc >
array< T, NewShape, Alloc > move_reinterpret_shape (array< T, OldShape, Alloc > &&from, index_t offset=0)
 
template<size_t... DimIndices, class T , class OldShape , class = internal::enable_if_permutation<OldShape::rank(), DimIndices...>>
NDARRAY_HOST_DEVICE auto transpose (const array_ref< T, OldShape > &a)
 
+template<size_t... DimIndices, class T , class OldShape , class Allocator , class = internal::enable_if_permutation<OldShape::rank(), DimIndices...>>
auto transpose (array< T, OldShape, Allocator > &a)
 
+template<size_t... DimIndices, class T , class OldShape , class Allocator , class = internal::enable_if_permutation<OldShape::rank(), DimIndices...>>
auto transpose (const array< T, OldShape, Allocator > &a)
 
+template<size_t... DimIndices, class T , class OldShape >
NDARRAY_HOST_DEVICE auto reorder (const array_ref< T, OldShape > &a)
 
+template<size_t... DimIndices, class T , class OldShape , class Allocator >
auto reorder (array< T, OldShape, Allocator > &a)
 
+template<size_t... DimIndices, class T , class OldShape , class Allocator >
auto reorder (const array< T, OldShape, Allocator > &a)
 
+ + + + + + + + + +

+Variables

constexpr index_t dynamic = -9
 
constexpr index_t unresolved = std::numeric_limits<index_t>::min()
 
const interval< 0,-1 > all
 
+const interval< 0,-1 > _
 
+

Detailed Description

+

Main header for array library.

+

Typedef Documentation

+ +
+
+ + + + +
using index_t = std::ptrdiff_t
+
+

When NDARRAY_INT_INDICES is defined, array indices are int values, otherwise they are std::ptrdiff_t. std::ptrdiff_t is helpful for the compiler to optimize address arithmetic, because it has the same size as a pointer.

+ +
+
+ +
+
+ + + + +
using fixed_interval = interval<dynamic, Extent>
+
+

An alias of interval with a fixed extent and dynamic min. This is useful as the inner part of a split with a fixed extent.

+ +
+
+ +
+
+ + + + +
using fixed_dim = dim<dynamic, Extent, Stride>
+
+

Alias of dim where the min is not specified at compile time.

+ +
+
+ +
+
+ + + + +
using dense_dim = dim<Min, Extent, 1>
+
+

Alias of dim where the compile-time stride parameter is known to be one.

+ +
+
+ +
+
+ + + + +
using strided_dim = dim<dynamic, dynamic, Stride>
+
+

Alias of dim where only the stride parameter is specified at compile time.

+ +
+
+ +
+
+ + + + +
using broadcast_dim = dim<Min, Extent, 0>
+
+

Alias of dim where the compile-time stride parameter is known to be zero.

+ +
+
+ +
+
+ + + + +
using index_of_rank = internal::tuple_of_n<index_t, Rank>
+
+

Type of an index for an array of rank Rank. This will be std::tuple<...> with Rank index_t values.

+

For example, index_of_rank<3> is std::tuple<index_t, index_t, index_t>.

+ +
+
+ +
+
+ + + + +
using shape_of_rank = decltype(make_shape_from_tuple(internal::tuple_of_n<dim<>, Rank>()))
+
+

An arbitrary shape with the specified rank Rank. This shape is compatible with any other shape of the same rank.

+ +
+
+ +
+
+ + + + +
using dense_shape = decltype(internal::make_default_dense_shape<Rank>())
+
+

A shape where the innermost dimension is a dense_dim, and all other dimensions are arbitrary.

+ +
+
+ +
+
+ + + + +
using fixed_dense_shape = decltype(make_shape_from_tuple(internal::make_compact_dims<1>(dim<0, Extents>()...)))
+
+

A shape where all extents (and automatically computed compact strides) are constant.

+ +
+
+ +
+
+ + + + +
using array_ref_of_rank = array_ref<T, shape_of_rank<Rank>>
+
+

array_ref with an arbitrary shape of rank Rank.

+ +
+
+ +
+
+ + + + +
using dense_array_ref = array_ref<T, dense_shape<Rank>>
+
+

array_ref with a shape dense_shape<Rank>.

+ +
+
+ +
+
+ + + + +
using array_of_rank = array<T, shape_of_rank<Rank>, Alloc>
+
+

An array type with an arbitrary shape of rank Rank.

+ +
+
+ +
+
+ + + + +
using dense_array = array<T, dense_shape<Rank>, Alloc>
+
+

An array type with shape dense_shape<Rank>.

+ +
+
+ +
+
+ + + + +
using uninitialized_std_allocator = uninitialized_allocator<std::allocator<T>>
+
+

Allocator equivalent to std::allocator<T> that does not default construct values.

+ +
+
+ +
+
+ + + + +
using uninitialized_auto_allocator = uninitialized_allocator<auto_allocator<T, N, Alignment>>
+
+

Allocator equivalent to auto_allocator<T, N, Alignment> that does not default construct values.

+ +
+
+

Function Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + +
NDARRAY_INLINE NDARRAY_HOST_DEVICE interval nda::range (index_t begin,
index_t end 
)
+
+

Make an interval from a half-open range [begin, end).

+ +
+
+ +
+
+ + + + + + + + +
NDARRAY_HOST_DEVICE fixed_interval<Extent> nda::range (index_t begin)
+
+

Make an interval from a half-open range [begin, begin + Extent).

+ +
+
+ +
+
+ + + + + + + + +
NDARRAY_HOST_DEVICE index_iterator nda::begin (const interval< Min, Extent > & d)
+
+

Overloads of std::begin and std::end for an interval.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t nda::clamp (index_t x,
index_t min,
index_t max 
)
+
+

Clamp x to the interval [min, max].

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
NDARRAY_HOST_DEVICE index_t nda::clamp (index_t x,
const Range & r 
)
+
+

Clamp x to the range described by an object r with a min() and max() method.

+ +
+
+ +
+
+ + + + + + + + +
NDARRAY_HOST_DEVICE internal::split_result<InnerExtent> nda::split (const interval< Min, Extent > & v)
+
+

Split an interval v into an iteratable range of intervals by a compile-time constant InnerExtent. If InnerExtent does not divide v.extent(), the last interval will be shifted to overlap with the second-to-last iteration, to preserve the compile-time constant extent, which implies v.extent() must be larger InnerExtent.

+

Examples:

    +
  • split<4>(interval<>(0, 8)) produces the intervals [0, 4), [4, 8).
  • +
  • split<5>(interval<>(0, 12)) produces the intervals [0, 5), [5, 10), [7, 12). Note the last two intervals overlap.
  • +
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
NDARRAY_HOST_DEVICE internal::split_result nda::split (const interval< Min, Extent > & v,
index_t inner_extent 
)
+
+

Split an interval v into an iterable range of intervals by inner_extent. If inner_extent does not divide v.extent(), the last iteration will be clamped to the outer interval.

+

Examples:

    +
  • split(interval<>(0, 12), 5) produces the intervals [0, 5), [5, 10), [10, 12).
  • +
+ +
+
+ +
+
+ + + + + + + + +
NDARRAY_HOST_DEVICE auto nda::make_shape (Dims... dims)
+
+

Helper function to make a shape from a variadic list of dims....

+ +
+
+ +
+
+ + + + + + + + +
NDARRAY_HOST_DEVICE auto nda::transpose (const shape< Dims... > & shape)
+
+

Create a new shape using a list of DimIndices... to use as the dimensions of the shape. The new shape's i'th dimension will be the j'th dimension of shape where j is the i'th value of DimIndices.... If i is not in DimIndices..., then i and j are equal.

+

DimIndices... must be a permutation of [0, N) where N is the number of indices provided.

+

Examples:

    +
  • transpose<2, 0, 1>(s) == make_shape(s.dim<2>(), s.dim<0>(), s.dim<1>())
  • +
  • transpose<1, 0>(s) == make_shape(s.dim<1>(), s.dim<0>(), ...) where ... is all dimensions after dimension 1.
  • +
+ +
+
+ +
+
+ + + + + + + + +
NDARRAY_HOST_DEVICE auto nda::reorder (const shape< Dims... > & shape)
+
+

Create a new shape using a list of DimIndices... to use as the dimensions of the shape. The new shape's i'th dimension will be the j'th dimension of shape where j is the i'th value of DimIndices....

+

Examples:

    +
  • reorder<1, 2>(s) == make_shape(s.dim<1>(), s.dim<2>())
  • +
+ +
+
+ +
+
+ + + + + + + + +
NDARRAY_HOST_DEVICE auto nda::make_compact (const Shape & s)
+
+

Attempt to make both the compile-time and run-time strides of s compact such that there is no padding between dimensions. Only dynamic strides are potentially replaced with static strides, existing compile-time strides are not modified. Run-time strides are then populated using the shape::resolve algorithm.

+

For a shape without any existing constant strides, this will return an instance of dense_shape<Shape::rank()>.

+

The resulting shape may not have Shape::is_compact return true if the shape has existing non-compact compile-time constant strides.

+ +
+
+ +
+
+ + + + + + + + +
NDARRAY_HOST_DEVICE bool nda::is_compatible (const ShapeSrc & src)
+
+

Returns true if a shape src can be assigned to a shape of type ShapeDst without error.

+ +
+
+ +
+
+ + + + + + + + +
NDARRAY_HOST_DEVICE ShapeDst nda::convert_shape (const ShapeSrc & src)
+
+

Convert a shape src to shape type ShapeDst. This explicit conversion allows converting a low rank shape to a higher ranked shape where new dimensions have min 0 and extent 1, and it allows converting a high rank shape to a lower rank shape if the dimensions being sliced are trivial (they have extent one).

+ +
+
+ +
+
+ + + + + + + + +
NDARRAY_HOST_DEVICE bool nda::is_explicitly_compatible (const ShapeSrc & src)
+
+

Test if a shape src can be explicitly converted to a shape of type ShapeDst using convert_shape without error.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void nda::for_each_index_in_order (const Shape & shape,
Fn && fn 
)
+
+

Iterate over all indices in the shape, calling a function fn for each set of indices. The indices are in the same order as the dims in the shape. The first dim is the 'inner' loop of the iteration, and the last dim is the 'outer' loop.

+

These functions are typically used to implement shape_traits<> and copy_shape_traits<> objects. Use for_each_index, array_ref<>::for_each_value, or array<>::for_each_value instead.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void nda::for_each_value_in_order (const Shape & shape,
const ShapeA & shape_a,
PtrA base_a,
const ShapeB & shape_b,
PtrB base_b,
Fn && fn 
)
+
+

Similar to for_each_value_in_order, but iterates over two arrays simultaneously. shape defines the loop nest, while shape_a and shape_b define the memory layout of base_a and base_b.

+

The min and extent of arrays a and b must be contained in shape, otherwise values may be read out of bounds. No bounds checking is done in this function; only shape_a and shape_b's strides are considered.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_index (const Shape & s,
Fn && fn 
)
+
+

Iterate over all indices in the shape s, calling a function fn for each set of indices. for_all_indices calls fn with a list of arguments corresponding to each dim. for_each_index calls fn with an index tuple describing the indices.

+

If the LoopOrder... permutation is empty, the order of the loops is defined by shape_traits<Shape>, and the callable fn must accept a Shape::index_type in the case of for_each_index, or Shape::rank() index_t objects in the case of for_all_indices.

+

If the LoopOrder... permutation is not empty, the order of the loops is defined by this ordering. The first index of LoopOrder... is the innermost loop of the loop nest. The callable fn must accept an index_of_rank<sizeof...(LoopOprder)> in the case of for_each_index<>, or sizeof...(LoopOrder) index_t objects in the case of for_all_indices<>.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
NDARRAY_HOST_DEVICE array_ref<T, Shape> nda::make_array_ref (T * base,
const Shape & shape 
)
+
+

Make a new array_ref with shape shape and base pointer base.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
auto nda::make_array (const Shape & shape,
const Alloc & alloc = Alloc() 
)
+
+

Make a new array with shape shape, allocated using the allocator alloc.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void nda::swap (array< T, Shape, Alloc > & a,
array< T, Shape, Alloc > & b 
)
+
+

Swap the contents of two arrays.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void nda::copy (const array_ref< TSrc, ShapeSrc > & src,
const array_ref< TDst, ShapeDst > & dst 
)
+
+

Copy the contents of the src array or array_ref to the dst array or array_ref. The elements in the shape of dst will be copied, and must be in bounds of src.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
auto nda::make_copy (const array_ref< T, ShapeSrc > & src,
const Alloc & alloc = Alloc() 
)
+
+

Make a copy of the src array or array_ref with a new allocator alloc.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
auto nda::make_copy (const array_ref< T, ShapeSrc > & src,
const ShapeDst & shape,
const Alloc & alloc = Alloc() 
)
+
+

Make a copy of the src array or array_ref with a new shape shape.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
auto nda::make_compact_copy (const array_ref< T, Shape > & src,
const Alloc & alloc = Alloc() 
)
+
+

Make a copy of the src array or array_ref with a compact version of src's shape.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void nda::move (const array_ref< TSrc, ShapeSrc > & src,
const array_ref< TDst, ShapeDst > & dst 
)
+
+

Move the contents from the src array or array_ref to the dst array or array_ref. The interval of the shape of dst will be moved, and must be in bounds of src.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
auto nda::make_move (const array_ref< T, ShapeSrc > & src,
const ShapeDst & shape,
const Alloc & alloc = Alloc() 
)
+
+

Make a copy of the src array or array_ref with a new shape shape. The elements of src are moved to the result.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
auto nda::make_compact_move (const array_ref< T, Shape > & src,
const Alloc & alloc = Alloc() 
)
+
+

Make a copy of the src array or array_ref with a compact version of src's shape. The elements of src are moved to the result.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
NDARRAY_HOST_DEVICE void nda::fill (const array_ref< T, Shape > & dst,
const T & value 
)
+
+

Fill the dst array or array_ref by copy-assigning value.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
NDARRAY_HOST_DEVICE void nda::generate (const array_ref< T, Shape > & dst,
Generator && g 
)
+
+

Fill the dst array or array_ref with the result of calling a generator function g. The order in which g is called is the same as shape_traits<Shape>::for_each_value.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
NDARRAY_HOST_DEVICE void nda::transform_index (const array_ref< T, Shape > & dst,
Fn && fn 
)
+
+

Fill the dst array or array_ref with the result of calling a "pattern +function" fn, which takes a single shape::index_type argument. The order in which fn is called is the same as shape_traits<Shape>::for_each_index.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
NDARRAY_HOST_DEVICE void nda::transform_indices (const array_ref< T, Shape > & dst,
Fn && fn 
)
+
+

Fill the dst array or array_ref with the result of calling a "pattern +function" fn, which takes as as many index_t arguments as there are dimensions in dst. The order in which fn is called is the same as shape_traits<Shape>::for_each_index.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
NDARRAY_HOST_DEVICE bool nda::equal (const array_ref< TA, ShapeA > & a,
const array_ref< TB, ShapeB > & b 
)
+
+

Check if two array or array_refs have equal contents.

+ +
+
+ +
+
+ + + + + + + + +
NDARRAY_HOST_DEVICE array_ref<T, NewShape> nda::convert_shape (const array_ref< T, OldShape > & a)
+
+

Convert the shape of the array or array_ref a to a new type of shape NewShape. The new shape is copy constructed from a.shape().

+ +
+
+ +
+
+ + + + + + + + +
NDARRAY_HOST_DEVICE array_ref<U, Shape> nda::reinterpret (const array_ref< T, Shape > & a)
+
+

Reinterpret the array or array_ref a of type T to have a different type U. sizeof(T) must be equal to sizeof(U).

+ +
+
+ +
+
+ + + + + + + + +
array_ref<U, Shape> nda::reinterpret_const (const const_array_ref< T, Shape > & a)
+
+

Reinterpret the const_array_ref a of type T (aka array_ref<const T>) to have a different type U using const_cast.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
NDARRAY_HOST_DEVICE array_ref<T, NewShape> nda::reinterpret_shape (const array_ref< T, OldShape > & a,
const NewShape & new_shape,
index_t offset = 0 
)
+
+

Reinterpret the shape of the array or array_ref a to be a new shape new_shape, with a base pointer offset offset.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
array<T, NewShape, Alloc> nda::move_reinterpret_shape (array< T, OldShape, Alloc > && from,
const NewShape & new_shape,
index_t offset = 0 
)
+
+

Move an array from to a new array, reinterpreting the shape of the array to new_shape, with a base pointer offset offset. This is only available for trivial T, because it does not guarantee that newly accessible elements are constructed, or newly inaccessible elements are destructed.

+ +
+
+ +
+
+ + + + + + + + +
NDARRAY_HOST_DEVICE auto nda::transpose (const array_ref< T, OldShape > & a)
+
+

Reinterpret the shape of the array or array_ref a to be transposed or reordered using transpose<DimIndices...>(a.shape()) or reorder<DimIndices...>(a.shape()).

+ +
+
+

Variable Documentation

+ +
+
+ + + + +
constexpr index_t dynamic = -9
+
+

This value indicates a compile-time constant parameter is an unknown value, and to use the corresponding runtime value instead. If a compile-time constant value is not dynamic, it is said to be static. A runtime value is said to be 'compatible with' a compile-time constant value if the values are equal, or the compile-time constant value is dynamic.

+ +
+
+ +
+
+ + + + +
constexpr index_t unresolved = std::numeric_limits<index_t>::min()
+
+

This value indicates a runtime parameter is an unknown value, and may be replaced by a default value computed by the library.

+ +
+
+ +
+
+ + + + +
const interval<0, -1> all
+
+

Placeholder object representing an interval that indicates keep the whole dimension when used in an indexing expression.

+ +
+
+
+ + + + diff --git a/array_8h_source.html b/array_8h_source.html new file mode 100644 index 00000000..e465e061 --- /dev/null +++ b/array_8h_source.html @@ -0,0 +1,246 @@ + + + + + + +array: include/array/array.h Source File + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
array.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
19 #ifndef NDARRAY_ARRAY_H
20 #define NDARRAY_ARRAY_H
21 
22 #include <array>
23 // TODO(jiawen): CUDA *should* support assert on device. This might be due to the fact that we are
24 // not depending on the CUDA toolkit.
25 #if defined(__CUDA__)
26 #undef assert
27 #define assert(e)
28 #else
29 #include <cassert>
30 #endif
31 
32 #include <cstdio>
33 #include <limits>
34 #include <memory>
35 #include <tuple>
36 #include <type_traits>
37 
38 // Some things in this header are unbearably slow without optimization if they
39 // don't get inlined.
40 #if defined(__GNUC__)
41 #define NDARRAY_INLINE inline __attribute__((always_inline))
42 #elif defined(__clang__)
43 #if defined(__CUDA__)
44 #define NDARRAY_INLINE __forceinline__
45 #else
46 #define NDARRAY_INLINE inline __attribute__((always_inline))
47 #endif
48 #else
49 #define NDARRAY_INLINE inline
50 #endif
51 
52 // Many of the functions in this header are templates that are usually unique
53 // specializations, which are beneficial to inline. The compiler will inline
54 // functions it knows are used only once, but it can't know this unless the
55 // functions have internal linkage.
56 #define NDARRAY_UNIQUE static
57 
58 // Functions attributed with NDARRAY_HOST_DEVICE can run on both device and host mode on CUDA.
59 #if defined(__CUDA__)
60 #define NDARRAY_HOST_DEVICE __device__ __host__
61 #else
62 #define NDARRAY_HOST_DEVICE
63 #endif
64 
65 #if defined(__GNUC__) || defined(__clang__)
66 #define NDARRAY_RESTRICT __restrict__
67 #else
68 #define NDARRAY_RESTRICT
69 #endif
70 
71 #if defined(__CUDA__)
72 #define NDARRAY_PRINT_ERR(...) printf(__VA_ARGS__)
73 #else
74 #define NDARRAY_PRINT_ERR(...) fprintf(stderr, __VA_ARGS__)
75 #endif
76 
77 namespace nda {
78 
79 using size_t = std::size_t;
83 #ifdef NDARRAY_INT_INDICES
84 using index_t = int;
85 #define NDARRAY_INDEX_T_FMT "%d"
86 #else
87 using index_t = std::ptrdiff_t;
88 #define NDARRAY_INDEX_T_FMT "%td"
89 #endif
90 
96 // It would be better to use a more unreasonable value that would never be
97 // used in practice, or find a better way to express this pattern.
98 // (https://github.com/dsharlet/array/issues/9).
99 constexpr index_t dynamic = -9;
100 
103 constexpr index_t unresolved = std::numeric_limits<index_t>::min();
104 
105 namespace internal {
106 
107 // Workaround CUDA not supporting std::declval.
108 // https://stackoverflow.com/questions/31969644/compilation-error-with-nvcc-and-c11-need-minimal-failing-example
109 template <typename T>
110 NDARRAY_HOST_DEVICE typename std::add_rvalue_reference<T>::type declval() noexcept;
111 
112 NDARRAY_INLINE constexpr index_t abs(index_t x) { return x >= 0 ? x : -x; }
113 
114 NDARRAY_INLINE constexpr index_t is_static(index_t x) { return x != dynamic; }
115 NDARRAY_INLINE constexpr index_t is_dynamic(index_t x) { return x == dynamic; }
116 
117 NDARRAY_INLINE constexpr index_t is_resolved(index_t x) { return x != unresolved; }
118 NDARRAY_INLINE constexpr index_t is_unresolved(index_t x) { return x == unresolved; }
119 
120 constexpr bool is_dynamic(index_t a, index_t b) { return is_dynamic(a) || is_dynamic(b); }
121 
122 // Returns true if a and b are statically not equal, but they may still be
123 // dynamically not equal even if this returns false.
124 constexpr bool not_equal(index_t a, index_t b) { return is_static(a) && is_static(b) && a != b; }
125 
126 template <index_t A, index_t B>
127 using disable_if_not_equal = std::enable_if_t<!not_equal(A, B)>;
128 
129 // Math for (possibly) static values.
130 constexpr index_t static_abs(index_t x) { return is_dynamic(x) ? dynamic : abs(x); }
131 constexpr index_t static_add(index_t a, index_t b) { return is_dynamic(a, b) ? dynamic : a + b; }
132 constexpr index_t static_sub(index_t a, index_t b) { return is_dynamic(a, b) ? dynamic : a - b; }
133 constexpr index_t static_mul(index_t a, index_t b) { return is_dynamic(a, b) ? dynamic : a * b; }
134 constexpr index_t static_min(index_t a, index_t b) {
135  return is_dynamic(a, b) ? dynamic : (a < b ? a : b);
136 }
137 constexpr index_t static_max(index_t a, index_t b) {
138  return is_dynamic(a, b) ? dynamic : (a > b ? a : b);
139 }
140 
141 // A type that mimics a constexpr index_t with value Value, unless Value is
142 // dynamic, then mimics index_t.
143 template <index_t Value>
144 struct constexpr_index {
145 public:
146  // These asserts are really hard to debug
147  // https://github.com/dsharlet/array/issues/26
148  NDARRAY_HOST_DEVICE constexpr_index(index_t value = Value) { assert(value == Value); }
149  NDARRAY_HOST_DEVICE constexpr_index& operator=(index_t value) {
150  assert(value == Value);
151  return *this;
152  }
153  NDARRAY_HOST_DEVICE NDARRAY_INLINE operator index_t() const { return Value; }
154 };
155 
156 template <>
157 struct constexpr_index<dynamic> {
158  index_t value_;
159 
160 public:
161  NDARRAY_HOST_DEVICE constexpr_index(index_t value) : value_(value) {}
162  NDARRAY_HOST_DEVICE constexpr_index& operator=(index_t value) {
163  value_ = value;
164  return *this;
165  }
166  NDARRAY_INLINE NDARRAY_HOST_DEVICE operator index_t() const { return value_; }
167 };
168 
169 // Defined here to avoid pulling in <algorithm>.
170 template <typename T>
171 constexpr const T& max(const T& a, const T& b) {
172  return (a < b) ? b : a;
173 }
174 
175 template <typename T>
176 constexpr const T& min(const T& a, const T& b) {
177  return (b < a) ? b : a;
178 }
179 
180 } // namespace internal
181 
184  index_t i_;
185 
186 public:
188  index_iterator(index_t i) : i_(i) {}
189 
191  NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t operator*() const { return i_; }
192 
193  NDARRAY_INLINE NDARRAY_HOST_DEVICE bool operator==(const index_iterator& r) const {
194  return i_ == r.i_;
195  }
196  NDARRAY_INLINE NDARRAY_HOST_DEVICE bool operator!=(const index_iterator& r) const {
197  return i_ != r.i_;
198  }
199 
200  NDARRAY_INLINE NDARRAY_HOST_DEVICE index_iterator operator++(int) { return index_iterator(i_++); }
201  NDARRAY_INLINE NDARRAY_HOST_DEVICE index_iterator operator--(int) { return index_iterator(i_--); }
202  NDARRAY_INLINE NDARRAY_HOST_DEVICE index_iterator& operator++() {
203  ++i_;
204  return *this;
205  }
206  NDARRAY_INLINE NDARRAY_HOST_DEVICE index_iterator& operator--() {
207  --i_;
208  return *this;
209  }
210  NDARRAY_INLINE NDARRAY_HOST_DEVICE index_iterator& operator+=(index_t r) {
211  i_ += r;
212  return *this;
213  }
214  NDARRAY_INLINE NDARRAY_HOST_DEVICE index_iterator& operator-=(index_t r) {
215  i_ -= r;
216  return *this;
217  }
218  NDARRAY_INLINE NDARRAY_HOST_DEVICE index_iterator operator+(index_t r) {
219  return index_iterator(i_ + r);
220  }
221  NDARRAY_INLINE NDARRAY_HOST_DEVICE index_iterator operator-(index_t r) {
222  return index_iterator(i_ - r);
223  }
224  NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t operator-(const index_iterator& r) {
225  return i_ - r.i_;
226  }
227  NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t operator[](index_t n) const { return i_ + n; }
228 };
229 
230 template <index_t Min, index_t Extent, index_t Stride>
231 class dim;
232 
247 template <index_t Min_ = dynamic, index_t Extent_ = dynamic>
248 class interval {
249 protected:
250  internal::constexpr_index<Min_> min_;
251  internal::constexpr_index<Extent_> extent_;
252 
253 public:
254  static constexpr index_t Min = Min_;
255  static constexpr index_t Extent = Extent_;
256  static constexpr index_t Max = internal::static_sub(internal::static_add(Min, Extent), 1);
257 
265  NDARRAY_HOST_DEVICE interval(index_t min, index_t extent) : min_(min), extent_(extent) {}
266  NDARRAY_HOST_DEVICE interval(index_t min)
267  : interval(min, internal::is_static(Extent) ? Extent : 1) {}
268  NDARRAY_HOST_DEVICE interval() : interval(internal::is_static(Min) ? Min : 0) {}
269 
270  NDARRAY_HOST_DEVICE interval(const interval&) = default;
271  NDARRAY_HOST_DEVICE interval(interval&&) = default;
272  NDARRAY_HOST_DEVICE interval& operator=(const interval&) = default;
273  NDARRAY_HOST_DEVICE interval& operator=(interval&&) = default;
274 
278  template <index_t CopyMin, index_t CopyExtent,
279  class = internal::disable_if_not_equal<Min, CopyMin>,
280  class = internal::disable_if_not_equal<Extent, CopyExtent>>
281  NDARRAY_HOST_DEVICE interval(const interval<CopyMin, CopyExtent>& other)
282  : interval(other.min(), other.extent()) {}
283  template <index_t CopyMin, index_t CopyExtent,
284  class = internal::disable_if_not_equal<Min, CopyMin>,
285  class = internal::disable_if_not_equal<Extent, CopyExtent>>
286  NDARRAY_HOST_DEVICE interval& operator=(const interval<CopyMin, CopyExtent>& other) {
287  set_min(other.min());
288  set_extent(other.extent());
289  return *this;
290  }
291 
293  NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t min() const { return min_; }
294  NDARRAY_INLINE NDARRAY_HOST_DEVICE void set_min(index_t min) { min_ = min; }
296  NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t extent() const { return extent_; }
297  NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t size() const { return extent_; }
298  NDARRAY_INLINE NDARRAY_HOST_DEVICE void set_extent(index_t extent) { extent_ = extent; }
299 
301  NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t max() const { return min_ + extent_ - 1; }
302  NDARRAY_INLINE NDARRAY_HOST_DEVICE void set_max(index_t max) { set_extent(max - min_ + 1); }
303 
305  NDARRAY_INLINE NDARRAY_HOST_DEVICE bool is_in_range(index_t at) const {
306  return min_ <= at && at <= max();
307  }
310  template <index_t OtherMin, index_t OtherExtent>
311  NDARRAY_INLINE NDARRAY_HOST_DEVICE bool is_in_range(
312  const interval<OtherMin, OtherExtent>& at) const {
313  return min_ <= at.min() && at.max() <= max();
314  }
315  template <index_t OtherMin, index_t OtherExtent, index_t OtherStride>
316  NDARRAY_INLINE NDARRAY_HOST_DEVICE bool is_in_range(
317  const dim<OtherMin, OtherExtent, OtherStride>& at) const {
318  return min_ <= at.min() && at.max() <= max();
319  }
320 
322  NDARRAY_HOST_DEVICE index_iterator begin() const { return index_iterator(min_); }
324  NDARRAY_HOST_DEVICE index_iterator end() const { return index_iterator(max() + 1); }
325 
328  template <index_t OtherMin, index_t OtherExtent>
329  NDARRAY_HOST_DEVICE bool operator==(const interval<OtherMin, OtherExtent>& other) const {
330  return min_ == other.min() && extent_ == other.extent();
331  }
332  template <index_t OtherMin, index_t OtherExtent>
333  NDARRAY_HOST_DEVICE bool operator!=(const interval<OtherMin, OtherExtent>& other) const {
334  return !operator==(other);
335  }
336 };
337 
340 template <index_t Extent>
342 
344 NDARRAY_INLINE NDARRAY_HOST_DEVICE interval<> range(index_t begin, index_t end) {
345  return interval<>(begin, end - begin);
346 }
347 NDARRAY_INLINE NDARRAY_HOST_DEVICE interval<> r(index_t begin, index_t end) {
348  return interval<>(begin, end - begin);
349 }
350 
352 template <index_t Extent>
353 NDARRAY_HOST_DEVICE fixed_interval<Extent> range(index_t begin) {
354  return fixed_interval<Extent>(begin);
355 }
356 template <index_t Extent>
357 NDARRAY_HOST_DEVICE fixed_interval<Extent> r(index_t begin) {
358  return fixed_interval<Extent>(begin);
359 }
360 
363 const interval<0, -1> all, _;
364 
366 template <index_t Min, index_t Extent>
367 NDARRAY_HOST_DEVICE index_iterator begin(const interval<Min, Extent>& d) {
368  return d.begin();
369 }
370 template <index_t Min, index_t Extent>
371 NDARRAY_HOST_DEVICE index_iterator end(const interval<Min, Extent>& d) {
372  return d.end();
373 }
374 
376 NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t clamp(index_t x, index_t min, index_t max) {
377  return internal::min(internal::max(x, min), max);
378 }
379 
382 template <class Range>
383 NDARRAY_HOST_DEVICE index_t clamp(index_t x, const Range& r) {
384  return clamp(x, r.min(), r.max());
385 }
386 
395 template <index_t Min_ = dynamic, index_t Extent_ = dynamic, index_t Stride_ = dynamic>
396 class dim : protected interval<Min_, Extent_> {
397 public:
398  using base_range = interval<Min_, Extent_>;
399 
400 protected:
401  internal::constexpr_index<Stride_> stride_;
402 
403  using base_range::extent_;
404  using base_range::min_;
405 
406 public:
407  using base_range::Extent;
408  using base_range::Max;
409  using base_range::Min;
410 
411  static constexpr index_t Stride = Stride_;
412  static constexpr index_t DefaultStride = internal::is_static(Stride) ? Stride : unresolved;
413 
422  NDARRAY_HOST_DEVICE dim(index_t min, index_t extent, index_t stride = DefaultStride)
423  : base_range(min, extent), stride_(stride) {}
424  NDARRAY_HOST_DEVICE dim(index_t extent) : dim(internal::is_static(Min) ? Min : 0, extent) {}
425  NDARRAY_HOST_DEVICE dim() : dim(internal::is_static(Extent) ? Extent : 0) {}
426 
427  NDARRAY_HOST_DEVICE dim(const base_range& interval, index_t stride = DefaultStride)
428  : dim(interval.min(), interval.extent(), stride) {}
429  NDARRAY_HOST_DEVICE dim(const dim&) = default;
430  NDARRAY_HOST_DEVICE dim(dim&&) = default;
431  NDARRAY_HOST_DEVICE dim& operator=(const dim&) = default;
432  NDARRAY_HOST_DEVICE dim& operator=(dim&&) = default;
433 
438  template <index_t CopyMin, index_t CopyExtent, index_t CopyStride,
439  class = internal::disable_if_not_equal<Min, CopyMin>,
440  class = internal::disable_if_not_equal<Extent, CopyExtent>,
441  class = internal::disable_if_not_equal<Stride, CopyStride>>
442  NDARRAY_HOST_DEVICE dim(const dim<CopyMin, CopyExtent, CopyStride>& other)
443  : dim(other.min(), other.extent()) {
444  set_stride(other.stride());
445  }
446  template <index_t CopyMin, index_t CopyExtent, index_t CopyStride,
447  class = internal::disable_if_not_equal<Min, CopyMin>,
448  class = internal::disable_if_not_equal<Extent, CopyExtent>,
449  class = internal::disable_if_not_equal<Stride, CopyStride>>
450  NDARRAY_HOST_DEVICE dim& operator=(const dim<CopyMin, CopyExtent, CopyStride>& other) {
451  set_min(other.min());
452  set_extent(other.extent());
453  set_stride(other.stride());
454  return *this;
455  }
456 
457  using base_range::begin;
458  using base_range::end;
459  using base_range::extent;
460  using base_range::size;
461  using base_range::is_in_range;
462  using base_range::max;
463  using base_range::min;
464  using base_range::set_extent;
465  using base_range::set_max;
466  using base_range::set_min;
467 
470  NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t stride() const { return stride_; }
471  NDARRAY_INLINE NDARRAY_HOST_DEVICE void set_stride(index_t stride) {
472  if (internal::is_static(Stride_)) {
473  assert(internal::is_unresolved(stride) || stride == Stride_);
474  } else {
475  stride_ = stride;
476  }
477  }
478 
480  NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t flat_offset(index_t at) const {
481  return (at - min_) * stride_;
482  }
483 
486  template <index_t OtherMin, index_t OtherExtent, index_t OtherStride>
487  NDARRAY_HOST_DEVICE bool operator==(const dim<OtherMin, OtherExtent, OtherStride>& other) const {
488  return min_ == other.min() && extent_ == other.extent() && stride_ == other.stride();
489  }
490  template <index_t OtherMin, index_t OtherExtent, index_t OtherStride>
491  NDARRAY_HOST_DEVICE bool operator!=(const dim<OtherMin, OtherExtent, OtherStride>& other) const {
492  return !operator==(other);
493  }
494 };
495 
497 template <index_t Extent, index_t Stride = dynamic>
499 
502 template <index_t Min = dynamic, index_t Extent = dynamic>
504 
507 template <index_t Stride>
509 
512 template <index_t Min = dynamic, index_t Extent = dynamic>
514 
515 namespace internal {
516 
517 // An iterator for a range of intervals.
518 // This is like a random access iterator in that it can move forward in constant time, but
519 // but unlike a random access iterator, it cannot be moved in reverse.
520 template <index_t InnerExtent = dynamic>
521 class split_iterator {
523  index_t outer_max;
524 
525 public:
526  NDARRAY_HOST_DEVICE split_iterator(const fixed_interval<InnerExtent>& i, index_t outer_max)
527  : i(i), outer_max(outer_max) {}
528 
529  NDARRAY_HOST_DEVICE bool operator==(const split_iterator& r) const {
530  return i.min() == r.i.min();
531  }
532  NDARRAY_HOST_DEVICE bool operator!=(const split_iterator& r) const {
533  return i.min() != r.i.min();
534  }
535 
536  NDARRAY_HOST_DEVICE fixed_interval<InnerExtent> operator*() const { return i; }
537  NDARRAY_HOST_DEVICE const fixed_interval<InnerExtent>* operator->() const { return &i; }
538 
539  NDARRAY_HOST_DEVICE split_iterator& operator+=(index_t n) {
540  assert(n >= 0);
541  if (is_static(InnerExtent)) {
542  // When the extent of the inner split is a compile-time constant,
543  // we can't shrink the out of bounds interval. Instead, shift the min,
544  // assuming the outer dimension is bigger than the inner extent.
545  i.set_min(i.min() + InnerExtent * n);
546  // Only shift the min when this straddles the end of the buffer,
547  // so the iterator can advance to the end (one past the max).
548  if (i.min() <= outer_max && i.max() > outer_max) { i.set_min(outer_max - InnerExtent + 1); }
549  } else {
550  // When the extent of the inner split is not a compile-time constant,
551  // we can just modify the extent.
552  i.set_min(i.min() + i.extent() * n);
553  index_t max = min(i.max(), outer_max);
554  i.set_extent(max - i.min() + 1);
555  }
556  return *this;
557  }
558  NDARRAY_HOST_DEVICE split_iterator operator+(index_t n) const {
559  split_iterator<InnerExtent> result(*this);
560  return result += n;
561  }
562  NDARRAY_HOST_DEVICE split_iterator& operator++() {
563  return *this += 1;
564  }
565  NDARRAY_HOST_DEVICE split_iterator operator++(int) {
566  split_iterator<InnerExtent> result(*this);
567  *this += 1;
568  return result;
569  }
570 
571  NDARRAY_HOST_DEVICE index_t operator-(const split_iterator& r) const {
572  return r.i.extent() > 0 ? (i.max() - r.i.min() + r.i.extent() - i.extent()) / r.i.extent() : 0;
573  }
574 
575  NDARRAY_HOST_DEVICE fixed_interval<InnerExtent> operator[](index_t n) const {
576  split_iterator result(*this);
577  result += n;
578  return *result;
579  }
580 };
581 
582 template <index_t InnerExtent = dynamic>
583 class split_result {
584 public:
585  using iterator = split_iterator<InnerExtent>;
586 
587 private:
588  iterator begin_;
589  iterator end_;
590 
591 public:
592  NDARRAY_HOST_DEVICE split_result(iterator begin, iterator end) : begin_(begin), end_(end) {}
593 
594  NDARRAY_HOST_DEVICE iterator begin() const { return begin_; }
595  NDARRAY_HOST_DEVICE iterator end() const { return end_; }
596 
597  NDARRAY_HOST_DEVICE index_t size() const { return end_ - begin_; }
598  NDARRAY_HOST_DEVICE iterator operator[](index_t i) const { return begin_ + i; }
599 };
600 
601 } // namespace internal
602 
613 template <index_t InnerExtent, index_t Min, index_t Extent>
614 NDARRAY_HOST_DEVICE internal::split_result<InnerExtent> split(
615  const interval<Min, Extent>& v) {
616  assert(v.extent() >= InnerExtent);
617  return {{fixed_interval<InnerExtent>(v.min()), v.max()},
618  {fixed_interval<InnerExtent>(v.max() + 1), v.max()}};
619 }
620 template <index_t InnerExtent, index_t Min, index_t Extent, index_t Stride>
621 NDARRAY_HOST_DEVICE internal::split_result<InnerExtent> split(
622  const dim<Min, Extent, Stride>& v) {
623  return split<InnerExtent>(interval<Min, Extent>(v.min(), v.extent()));
624 }
625 
633 // TODO: This probably doesn't need to be templated, but it might help
634 // avoid some conversion messes. dim<Min, Extent> probably can't implicitly
635 // convert to interval<>.
636 template <index_t Min, index_t Extent>
637 NDARRAY_HOST_DEVICE internal::split_result<> split(
638  const interval<Min, Extent>& v, index_t inner_extent) {
639  return {{interval<>(v.min(), internal::min(inner_extent, v.extent())), v.max()},
640  {interval<>(v.max() + 1, 0), v.max()}};
641 }
642 template <index_t Min, index_t Extent, index_t Stride>
643 NDARRAY_HOST_DEVICE internal::split_result<> split(
644  const dim<Min, Extent, Stride>& v, index_t inner_extent) {
645  return split(interval<Min, Extent>(v.min(), v.extent()), inner_extent);
646 }
647 
648 namespace internal {
649 
650 using std::index_sequence;
651 using std::make_index_sequence;
652 
653 // Call `fn` with the elements of tuple `args` unwrapped from the tuple.
654 // TODO: When we assume C++17, this can be replaced by std::apply.
655 template <class Fn, class Args, size_t... Is>
656 NDARRAY_INLINE NDARRAY_HOST_DEVICE auto apply(Fn&& fn, const Args& args, index_sequence<Is...>)
657  -> decltype(fn(std::get<Is>(args)...)) {
658  return fn(std::get<Is>(args)...);
659 }
660 template <class Fn, class Args>
661 NDARRAY_INLINE NDARRAY_HOST_DEVICE auto apply(Fn&& fn, const Args& args)
662  -> decltype(internal::apply(fn, args, make_index_sequence<std::tuple_size<Args>::value>())) {
663  return internal::apply(fn, args, make_index_sequence<std::tuple_size<Args>::value>());
664 }
665 
666 template <class Fn, class... Args>
667 using enable_if_callable = decltype(internal::declval<Fn>()(internal::declval<Args>()...));
668 template <class Fn, class Args>
669 using enable_if_applicable =
670  decltype(internal::apply(internal::declval<Fn>(), internal::declval<Args>()));
671 
672 // Some variadic reduction helpers.
673 NDARRAY_INLINE constexpr index_t sum() { return 0; }
674 NDARRAY_INLINE constexpr index_t sum(index_t x0) { return x0; }
675 NDARRAY_INLINE constexpr index_t sum(index_t x0, index_t x1) { return x0 + x1; }
676 NDARRAY_INLINE constexpr index_t sum(index_t x0, index_t x1, index_t x2) { return x0 + x1 + x2; }
677 template <class... Rest>
678 NDARRAY_INLINE constexpr index_t sum(index_t x0, index_t x1, index_t x2, index_t x3, Rest... rest) {
679  return x0 + x1 + x2 + x3 + sum(rest...);
680 }
681 
682 NDARRAY_INLINE constexpr int product() { return 1; }
683 template <class T, class... Rest>
684 NDARRAY_INLINE constexpr T product(T first, Rest... rest) {
685  return first * product(rest...);
686 }
687 
688 NDARRAY_INLINE constexpr index_t variadic_min() { return std::numeric_limits<index_t>::max(); }
689 template <class... Rest>
690 NDARRAY_INLINE constexpr index_t variadic_min(index_t first, Rest... rest) {
691  return min(first, variadic_min(rest...));
692 }
693 
694 NDARRAY_INLINE constexpr index_t variadic_max() { return std::numeric_limits<index_t>::min(); }
695 template <class... Rest>
696 NDARRAY_INLINE constexpr index_t variadic_max(index_t first, Rest... rest) {
697  return max(first, variadic_max(rest...));
698 }
699 
700 // Computes the product of the extents of the dims.
701 template <class Tuple, size_t... Is>
702 NDARRAY_HOST_DEVICE index_t product(const Tuple& t, index_sequence<Is...>) {
703  return product(std::get<Is>(t)...);
704 }
705 
706 // Returns true if all of bools are true.
707 template <class... Bools>
708 constexpr bool all(Bools... bools) {
709  return sum((bools ? 0 : 1)...) == 0;
710 }
711 template <class... Bools>
712 constexpr bool any(Bools... bools) {
713  return sum((bools ? 1 : 0)...) != 0;
714 }
715 
716 // Computes the sum of the offsets of a list of dims and indices.
717 template <class Dims, class Indices, size_t... Is>
718 NDARRAY_HOST_DEVICE index_t flat_offset(
719  const Dims& dims, const Indices& indices, index_sequence<Is...>) {
720  return sum(std::get<Is>(dims).flat_offset(std::get<Is>(indices))...);
721 }
722 
723 // Computes one more than the sum of the offsets of the last index in every dim.
724 template <class Dims, size_t... Is>
725 NDARRAY_HOST_DEVICE index_t flat_min(const Dims& dims, index_sequence<Is...>) {
726  return sum((std::get<Is>(dims).extent() - 1) * min<index_t>(0, std::get<Is>(dims).stride())...);
727 }
728 
729 template <class Dims, size_t... Is>
730 NDARRAY_HOST_DEVICE index_t flat_max(const Dims& dims, index_sequence<Is...>) {
731  return sum((std::get<Is>(dims).extent() - 1) *
732  internal::max<index_t>(0, std::get<Is>(dims).stride())...);
733 }
734 
735 // Make dims with the interval of the first parameter and the stride
736 // of the second parameter.
737 template <index_t DimMin, index_t DimExtent, index_t DimStride>
738 NDARRAY_HOST_DEVICE auto range_with_stride(index_t x, const dim<DimMin, DimExtent, DimStride>& d) {
739  return dim<dynamic, 1, DimStride>(x, 1, d.stride());
740 }
741 template <index_t CropMin, index_t CropExtent, index_t DimMin, index_t DimExtent, index_t Stride>
742 NDARRAY_HOST_DEVICE auto range_with_stride(
744  return dim<CropMin, CropExtent, Stride>(x.min(), x.extent(), d.stride());
745 }
746 template <index_t CropMin, index_t CropExtent, index_t CropStride, index_t DimMin,
747  index_t DimExtent, index_t Stride>
748 NDARRAY_HOST_DEVICE auto range_with_stride(
750  return dim<CropMin, CropExtent, Stride>(x.min(), x.extent(), d.stride());
751 }
752 template <index_t Min, index_t Extent, index_t Stride>
753 NDARRAY_HOST_DEVICE auto range_with_stride(const decltype(_)&, const dim<Min, Extent, Stride>& d) {
754  return d;
755 }
756 
757 template <class Intervals, class Dims, size_t... Is>
758 NDARRAY_HOST_DEVICE auto intervals_with_strides(
759  const Intervals& intervals, const Dims& dims, index_sequence<Is...>) {
760  return std::make_tuple(range_with_stride(std::get<Is>(intervals), std::get<Is>(dims))...);
761 }
762 
763 // Make a tuple of dims corresponding to elements in intervals that are not slices.
764 template <class Dim>
765 NDARRAY_HOST_DEVICE std::tuple<> skip_slices_impl(const Dim& d, index_t) {
766  return std::tuple<>();
767 }
768 template <class Dim, index_t Min, index_t Extent>
769 NDARRAY_HOST_DEVICE std::tuple<Dim> skip_slices_impl(const Dim& d, const interval<Min, Extent>&) {
770  return std::tuple<Dim>(d);
771 }
772 template <class Dim, index_t Min, index_t Extent, index_t Stride>
773 NDARRAY_HOST_DEVICE std::tuple<Dim> skip_slices_impl(
774  const Dim& d, const dim<Min, Extent, Stride>&) {
775  return std::tuple<Dim>(d);
776 }
777 
778 template <class Dims, class Intervals, size_t... Is>
779 NDARRAY_HOST_DEVICE auto skip_slices(
780  const Dims& dims, const Intervals& intervals, index_sequence<Is...>) {
781  return std::tuple_cat(skip_slices_impl(std::get<Is>(dims), std::get<Is>(intervals))...);
782 }
783 
784 // Checks if all indices are in interval of each corresponding dim.
785 template <class Dims, class Indices, size_t... Is>
786 NDARRAY_HOST_DEVICE bool is_in_range(
787  const Dims& dims, const Indices& indices, index_sequence<Is...>) {
788  return all(std::get<Is>(dims).is_in_range(std::get<Is>(indices))...);
789 }
790 
791 // Get the mins of a series of intervals.
792 template <class Dim>
793 NDARRAY_HOST_DEVICE index_t min_of_range(index_t x, const Dim&) {
794  return x;
795 }
796 template <index_t Min, index_t Extent, class Dim>
797 NDARRAY_HOST_DEVICE index_t min_of_range(const interval<Min, Extent>& x, const Dim&) {
798  return x.min();
799 }
800 template <index_t Min, index_t Extent, index_t Stride, class Dim>
801 NDARRAY_HOST_DEVICE index_t min_of_range(const dim<Min, Extent, Stride>& x, const Dim&) {
802  return x.min();
803 }
804 template <class Dim>
805 NDARRAY_HOST_DEVICE index_t min_of_range(const decltype(_)&, const Dim& dim) {
806  return dim.min();
807 }
808 
809 template <class Intervals, class Dims, size_t... Is>
810 NDARRAY_HOST_DEVICE auto mins_of_intervals(
811  const Intervals& intervals, const Dims& dims, index_sequence<Is...>) {
812  return std::make_tuple(min_of_range(std::get<Is>(intervals), std::get<Is>(dims))...);
813 }
814 
815 template <class... Dims, size_t... Is>
816 NDARRAY_HOST_DEVICE auto mins(const std::tuple<Dims...>& dims, index_sequence<Is...>) {
817  return std::make_tuple(std::get<Is>(dims).min()...);
818 }
819 
820 template <class... Dims, size_t... Is>
821 NDARRAY_HOST_DEVICE auto extents(const std::tuple<Dims...>& dims, index_sequence<Is...>) {
822  return std::make_tuple(std::get<Is>(dims).extent()...);
823 }
824 
825 template <class... Dims, size_t... Is>
826 NDARRAY_HOST_DEVICE auto strides(const std::tuple<Dims...>& dims, index_sequence<Is...>) {
827  return std::make_tuple(std::get<Is>(dims).stride()...);
828 }
829 
830 template <class... Dims, size_t... Is>
831 NDARRAY_HOST_DEVICE auto maxs(const std::tuple<Dims...>& dims, index_sequence<Is...>) {
832  return std::make_tuple(std::get<Is>(dims).max()...);
833 }
834 
835 // The following series of functions implements the algorithm for
836 // automatically determining what unknown dynamic strides should be.
837 
838 // A proposed stride is "OK" w.r.t. `dim` if the proposed
839 // stride does not intersect the dim.
840 template <class Dim>
841 NDARRAY_HOST_DEVICE bool is_stride_ok(index_t stride, index_t extent, const Dim& dim) {
842  if (is_unresolved(dim.stride())) {
843  // If the dimension has an unknown stride, it's OK, we're
844  // resolving the current dim first.
845  return true;
846  }
847  if (extent == 1 && abs(stride) == abs(dim.stride()) && dim.extent() > 1) {
848  // If a dimension is extent 1, avoid giving this dimension the same stride
849  // as another dimension with extent greater than 1. This doesn't affect the
850  // results of most programs (because the stride only ever multiplied with
851  // zero), but it makes the strides less objectionable to asserts in some
852  // other libraries that make extra assumptions about images, and may be
853  // easier to understand.
854  return false;
855  }
856  if (dim.extent() * abs(dim.stride()) <= stride) {
857  // The dim is completely inside the proposed stride.
858  return true;
859  }
860  index_t flat_extent = extent * stride;
861  if (abs(dim.stride()) >= flat_extent) {
862  // The dim is completely outside the proposed stride.
863  return true;
864  }
865  return false;
866 }
867 
868 // Replace strides that are not OK with values that cannot be the
869 // smallest stride.
870 template <class... Dims>
871 NDARRAY_HOST_DEVICE index_t filter_stride(index_t stride, index_t extent, const Dims&... dims) {
872  if (all(is_stride_ok(stride, extent, dims)...)) {
873  return stride;
874  } else {
875  return std::numeric_limits<index_t>::max();
876  }
877 }
878 
879 // The candidate stride for some other dimension is the minimum stride it
880 // could have without intersecting this dim.
881 template <class Dim>
882 NDARRAY_HOST_DEVICE index_t candidate_stride(const Dim& dim) {
883  if (is_unresolved(dim.stride())) {
884  return std::numeric_limits<index_t>::max();
885  } else {
886  return max<index_t>(1, abs(dim.stride()) * dim.extent());
887  }
888 }
889 
890 // Find the best stride (the smallest) out of all possible candidate strides.
891 template <class Dims, size_t... Is>
892 NDARRAY_HOST_DEVICE index_t find_stride(index_t extent, const Dims& dims, index_sequence<Is...>) {
893  return variadic_min(filter_stride(1, extent, std::get<Is>(dims)...),
894  filter_stride(candidate_stride(std::get<Is>(dims)), extent, std::get<Is>(dims)...)...);
895 }
896 
897 // Replace unknown dynamic strides for each dimension, starting with the first dimension.
898 template <class AllDims>
899 NDARRAY_HOST_DEVICE void resolve_unknown_strides(AllDims& all_dims) {}
900 template <class AllDims, class Dim0, class... Dims>
901 NDARRAY_HOST_DEVICE void resolve_unknown_strides(AllDims& all_dims, Dim0& dim0, Dims&... dims) {
902  if (is_unresolved(dim0.stride())) {
903  constexpr size_t rank = std::tuple_size<AllDims>::value;
904  dim0.set_stride(find_stride(dim0.extent(), all_dims, make_index_sequence<rank>()));
905  }
906  resolve_unknown_strides(all_dims, dims...);
907 }
908 
909 template <class Dims, size_t... Is>
910 NDARRAY_HOST_DEVICE void resolve_unknown_strides(Dims& dims, index_sequence<Is...>) {
911  resolve_unknown_strides(dims, std::get<Is>(dims)...);
912 }
913 
914 template <class Dims, size_t... Is>
915 NDARRAY_HOST_DEVICE bool is_resolved(const Dims& dims, index_sequence<Is...>) {
916  return all(is_resolved(std::get<Is>(dims).stride())...);
917 }
918 
919 // A helper to transform an array to a tuple.
920 template <class T, class Tuple, size_t... Is>
921 NDARRAY_HOST_DEVICE std::array<T, sizeof...(Is)> tuple_to_array(
922  const Tuple& t, index_sequence<Is...>) {
923  return {{std::get<Is>(t)...}};
924 }
925 
926 template <class T, class... Ts>
927 NDARRAY_HOST_DEVICE std::array<T, sizeof...(Ts)> tuple_to_array(const std::tuple<Ts...>& t) {
928  return tuple_to_array<T>(t, make_index_sequence<sizeof...(Ts)>());
929 }
930 
931 template <class T, size_t N, size_t... Is>
932 NDARRAY_HOST_DEVICE auto array_to_tuple(const std::array<T, N>& a, index_sequence<Is...>) {
933  return std::make_tuple(a[Is]...);
934 }
935 template <class T, size_t N>
936 NDARRAY_HOST_DEVICE auto array_to_tuple(const std::array<T, N>& a) {
937  return array_to_tuple(a, make_index_sequence<N>());
938 }
939 
940 template <class T, size_t N>
941 using tuple_of_n = decltype(array_to_tuple(internal::declval<std::array<T, N>>()));
942 
943 // A helper to check if a parameter pack is entirely implicitly convertible to
944 // any type Ts, for use with std::enable_if
945 template <class T, class... Args>
946 struct all_of_any_type : std::false_type {};
947 template <class T>
948 struct all_of_any_type<T> : std::true_type {};
949 template <class... Ts, class Arg, class... Args>
950 struct all_of_any_type<std::tuple<Ts...>, Arg, Args...> {
951  static constexpr bool value = any(std::is_constructible<Ts, Arg>::value...) &&
952  all_of_any_type<std::tuple<Ts...>, Args...>::value;
953 };
954 
955 // Wrapper for checking if a parameter pack is entirely implicitly convertible
956 // to one type T.
957 template <class T, class... Args>
958 using all_of_type = all_of_any_type<std::tuple<T>, Args...>;
959 
960 template <size_t I, class T, class... Us, std::enable_if_t<(I < sizeof...(Us)), int> = 0>
961 NDARRAY_HOST_DEVICE auto convert_dim(const std::tuple<Us...>& u) {
962  return std::get<I>(u);
963 }
964 template <size_t I, class T, class... Us, std::enable_if_t<(I >= sizeof...(Us)), int> = 0>
965 NDARRAY_HOST_DEVICE auto convert_dim(const std::tuple<Us...>& u) {
966  // For dims beyond the rank of U, make a dimension of type T_I with extent 1.
967  return decltype(std::get<I>(internal::declval<T>()))(1);
968 }
969 
970 template <class T, class U, size_t... Is>
971 NDARRAY_HOST_DEVICE T convert_dims(const U& u, internal::index_sequence<Is...>) {
972  return std::make_tuple(convert_dim<Is, T>(u)...);
973 }
974 
975 // Check that the dimensions in src_dims are either copied to the dst shape (not sliced),
976 // or are trivial slices (they are extent 1).
977 template <size_t DstRank, class SrcDims, size_t... Is>
978 NDARRAY_HOST_DEVICE bool is_trivial_slice(
979  const SrcDims& src_dims, internal::index_sequence<Is...>) {
980  return all((Is < DstRank || std::get<Is>(src_dims).extent() == 1)...);
981 }
982 
983 constexpr index_t factorial(index_t x) { return x == 1 ? 1 : x * factorial(x - 1); }
984 
985 // The errors that result from not satisfying this check are probably hell,
986 // but it would be pretty tricky to check that all of [0, Rank) is in `Is...`
987 template <size_t Rank, size_t... Is>
988 using enable_if_permutation = std::enable_if_t<sizeof...(Is) == Rank && all(Is < Rank...) &&
989  product((Is + 2)...) == factorial(Rank + 1)>;
990 
991 template <class DimDst, class DimSrc>
992 NDARRAY_HOST_DEVICE void assert_dim_compatible(size_t dim_index, const DimSrc& src) {
993  bool compatible = true;
994  if (is_static(DimDst::Min) && src.min() != DimDst::Min) {
995  NDARRAY_PRINT_ERR("Error converting dim %zu: expected static min " NDARRAY_INDEX_T_FMT
996  ", got " NDARRAY_INDEX_T_FMT "\n",
997  dim_index, DimDst::Min, src.min());
998  compatible = false;
999  }
1000  if (is_static(DimDst::Extent) && src.extent() != DimDst::Extent) {
1001  NDARRAY_PRINT_ERR("Error converting dim %zu: expected static extent " NDARRAY_INDEX_T_FMT
1002  ", got " NDARRAY_INDEX_T_FMT "\n",
1003  dim_index, DimDst::Extent, src.extent());
1004  compatible = false;
1005  }
1006  if (is_static(DimDst::Stride) && is_resolved(src.stride()) && src.stride() != DimDst::Stride) {
1007  NDARRAY_PRINT_ERR("Error converting dim %zu: expected static stride " NDARRAY_INDEX_T_FMT
1008  ", got " NDARRAY_INDEX_T_FMT "\n",
1009  dim_index, DimDst::Stride, src.stride());
1010  compatible = false;
1011  }
1012  assert(compatible);
1013  (void)compatible;
1014 }
1015 
1016 template <class DimsDst, class DimsSrc, size_t... Is>
1017 NDARRAY_HOST_DEVICE void assert_dims_compatible(const DimsSrc& src, index_sequence<Is...>) {
1018  // This is ugly, in C++17, we'd use a fold expression over the comma operator (f(), ...).
1019  int unused[] = {(assert_dim_compatible<typename std::tuple_element<Is, DimsDst>::type>(
1020  Is, nda::dim<>(std::get<Is>(src))),
1021  0)...};
1022  (void)unused;
1023 }
1024 
1025 template <class DimsDst, class DimsSrc>
1026 NDARRAY_HOST_DEVICE const DimsSrc& assert_dims_compatible(const DimsSrc& src) {
1027 #ifndef NDEBUG
1028  assert_dims_compatible<DimsDst>(src, make_index_sequence<std::tuple_size<DimsDst>::value>());
1029 #endif
1030  return src;
1031 }
1032 
1033 } // namespace internal
1034 
1035 template <class... Dims>
1036 class shape;
1037 
1039 template <class... Dims>
1040 NDARRAY_HOST_DEVICE auto make_shape(Dims... dims) {
1041  return shape<Dims...>(dims...);
1042 }
1043 
1044 template <class... Dims>
1045 NDARRAY_HOST_DEVICE shape<Dims...> make_shape_from_tuple(const std::tuple<Dims...>& dims) {
1046  return shape<Dims...>(dims);
1047 }
1048 
1053 template <size_t Rank>
1054 using index_of_rank = internal::tuple_of_n<index_t, Rank>;
1055 
1063 template <class... Dims>
1064 class shape {
1065 public:
1067  using dims_type = std::tuple<Dims...>;
1068 
1070  static constexpr size_t rank() { return std::tuple_size<dims_type>::value; }
1071 
1073  static constexpr bool is_scalar() { return rank() == 0; }
1074 
1077 
1078  using size_type = size_t;
1079 
1080  // We use this a lot here. Make an alias for it.
1081  using dim_indices = decltype(internal::make_index_sequence<std::tuple_size<dims_type>::value>());
1082 
1083 private:
1084  dims_type dims_;
1085 
1086  // TODO: This should use std::is_constructible<dims_type, std::tuple<OtherDims...>>
1087  // but it is broken on some compilers (https://github.com/dsharlet/array/issues/20).
1088  template <class... OtherDims>
1089  using enable_if_dims_compatible = std::enable_if_t<sizeof...(OtherDims) == rank()>;
1090 
1091  template <class... Args>
1092  using enable_if_same_rank = std::enable_if_t<(sizeof...(Args) == rank())>;
1093 
1094  template <class... Args>
1095  using enable_if_all_indices =
1096  std::enable_if_t<sizeof...(Args) == rank() && internal::all_of_type<index_t, Args...>::value>;
1097 
1098  template <class... Args>
1099  using enable_if_any_slices =
1100  std::enable_if_t<sizeof...(Args) == rank() &&
1101  internal::all_of_any_type<std::tuple<interval<>, dim<>>, Args...>::value &&
1102  !internal::all_of_type<index_t, Args...>::value>;
1103 
1104  template <class... Args>
1105  using enable_if_any_slices_or_indices =
1106  std::enable_if_t<sizeof...(Args) == rank() &&
1107  internal::all_of_any_type<std::tuple<interval<>, dim<>>, Args...>::value>;
1108 
1109  template <size_t Dim>
1110  using enable_if_dim = std::enable_if_t<(Dim < rank())>;
1111 
1112 public:
1113  NDARRAY_HOST_DEVICE shape() {}
1114  // TODO: This is a bit messy, but necessary to avoid ambiguous default
1115  // constructors when Dims is empty.
1116  template <size_t N = sizeof...(Dims), class = std::enable_if_t<(N > 0)>>
1117  NDARRAY_HOST_DEVICE shape(const Dims&... dims)
1118  : dims_(internal::assert_dims_compatible<dims_type>(std::make_tuple(dims...))) {}
1119  NDARRAY_HOST_DEVICE shape(const shape&) = default;
1120  NDARRAY_HOST_DEVICE shape(shape&&) = default;
1121  NDARRAY_HOST_DEVICE shape& operator=(const shape&) = default;
1122  NDARRAY_HOST_DEVICE shape& operator=(shape&&) = default;
1123 
1127  template <class... OtherDims, class = enable_if_dims_compatible<OtherDims...>>
1128  NDARRAY_HOST_DEVICE shape(const std::tuple<OtherDims...>& other)
1129  : dims_(internal::assert_dims_compatible<dims_type>(other)) {}
1130  template <class... OtherDims, class = enable_if_dims_compatible<OtherDims...>>
1131  NDARRAY_HOST_DEVICE shape(OtherDims... other_dims) : shape(std::make_tuple(other_dims...)) {}
1132  template <class... OtherDims, class = enable_if_dims_compatible<OtherDims...>>
1133  NDARRAY_HOST_DEVICE shape(const shape<OtherDims...>& other)
1134  : dims_(internal::assert_dims_compatible<dims_type>(other.dims())) {}
1135  template <class... OtherDims, class = enable_if_dims_compatible<OtherDims...>>
1136  NDARRAY_HOST_DEVICE shape& operator=(const shape<OtherDims...>& other) {
1137  dims_ = internal::assert_dims_compatible<dims_type>(other.dims());
1138  return *this;
1139  }
1140 
1141  // We cannot have an dims_type constructor because it will be
1142  // ambiguous with the Dims... constructor for 1D shapes.
1143 
1154  NDARRAY_HOST_DEVICE void resolve() { internal::resolve_unknown_strides(dims_, dim_indices()); }
1155 
1157  NDARRAY_HOST_DEVICE bool is_resolved() const {
1158  return internal::is_resolved(dims_, dim_indices());
1159  }
1160 
1162  template <class... Args, class = enable_if_any_slices_or_indices<Args...>>
1163  NDARRAY_HOST_DEVICE bool is_in_range(const std::tuple<Args...>& args) const {
1164  return internal::is_in_range(dims_, args, dim_indices());
1165  }
1166  template <class... Args, class = enable_if_any_slices_or_indices<Args...>>
1167  NDARRAY_HOST_DEVICE bool is_in_range(Args... args) const {
1168  return internal::is_in_range(dims_, std::make_tuple(args...), dim_indices());
1169  }
1170 
1172  NDARRAY_HOST_DEVICE index_t operator[](const index_type& indices) const {
1173  return internal::flat_offset(dims_, indices, dim_indices());
1174  }
1175  template <class... Args, class = enable_if_all_indices<Args...>>
1176  NDARRAY_HOST_DEVICE index_t operator()(Args... indices) const {
1177  return internal::flat_offset(dims_, std::make_tuple(indices...), dim_indices());
1178  }
1179 
1183  template <class... Args, class = enable_if_any_slices<Args...>>
1184  NDARRAY_HOST_DEVICE auto operator[](const std::tuple<Args...>& args) const {
1185  auto new_dims = internal::intervals_with_strides(args, dims_, dim_indices());
1186  auto new_dims_no_slices = internal::skip_slices(new_dims, args, dim_indices());
1187  return make_shape_from_tuple(new_dims_no_slices);
1188  }
1189  template <class... Args, class = enable_if_any_slices<Args...>>
1190  NDARRAY_HOST_DEVICE auto operator()(Args... args) const {
1191  return operator[](std::make_tuple(args...));
1192  }
1193 
1195  template <size_t D, class = enable_if_dim<D>>
1196  NDARRAY_HOST_DEVICE auto& dim() {
1197  return std::get<D>(dims_);
1198  }
1199  template <size_t D, class = enable_if_dim<D>>
1200  NDARRAY_HOST_DEVICE const auto& dim() const {
1201  return std::get<D>(dims_);
1202  }
1203 
1207  NDARRAY_HOST_DEVICE const nda::dim<> dim(size_t d) const {
1208  assert(d < rank());
1209  return internal::tuple_to_array<nda::dim<>>(dims_)[d];
1210  }
1211 
1213  NDARRAY_HOST_DEVICE dims_type& dims() { return dims_; }
1214  NDARRAY_HOST_DEVICE const dims_type& dims() const { return dims_; }
1215 
1216  NDARRAY_HOST_DEVICE index_type min() const { return internal::mins(dims_, dim_indices()); }
1217  NDARRAY_HOST_DEVICE index_type max() const { return internal::maxs(dims_, dim_indices()); }
1218  NDARRAY_HOST_DEVICE index_type extent() const { return internal::extents(dims_, dim_indices()); }
1219  NDARRAY_HOST_DEVICE index_type stride() const { return internal::strides(dims_, dim_indices()); }
1220 
1224  NDARRAY_HOST_DEVICE index_t flat_min() const { return internal::flat_min(dims_, dim_indices()); }
1225  NDARRAY_HOST_DEVICE index_t flat_max() const { return internal::flat_max(dims_, dim_indices()); }
1226  NDARRAY_HOST_DEVICE size_type flat_extent() const {
1227  index_t e = flat_max() - flat_min() + 1;
1228  return e < 0 ? 0 : static_cast<size_type>(e);
1229  }
1230 
1232  NDARRAY_HOST_DEVICE size_type size() const {
1233  index_t s = internal::product(extent(), dim_indices());
1234  return s < 0 ? 0 : static_cast<size_type>(s);
1235  }
1236 
1238  NDARRAY_HOST_DEVICE bool empty() const { return size() == 0; }
1239 
1243  NDARRAY_HOST_DEVICE bool is_compact() const { return flat_extent() <= size(); }
1244 
1249  NDARRAY_HOST_DEVICE bool is_one_to_one() const {
1250  // TODO: https://github.com/dsharlet/array/issues/2
1251  return flat_extent() >= size();
1252  }
1253 
1257  template <typename OtherShape>
1258  NDARRAY_HOST_DEVICE bool is_subset_of(const OtherShape& other, index_t offset) const {
1259  // TODO: https://github.com/dsharlet/array/issues/2
1260  return flat_min() >= other.flat_min() + offset && flat_max() <= other.flat_max() + offset;
1261  }
1262 
1265  NDARRAY_HOST_DEVICE auto& i() { return dim<0>(); }
1266  NDARRAY_HOST_DEVICE const auto& i() const { return dim<0>(); }
1267  NDARRAY_HOST_DEVICE auto& j() { return dim<1>(); }
1268  NDARRAY_HOST_DEVICE const auto& j() const { return dim<1>(); }
1269  NDARRAY_HOST_DEVICE auto& k() { return dim<2>(); }
1270  NDARRAY_HOST_DEVICE const auto& k() const { return dim<2>(); }
1271 
1274  NDARRAY_HOST_DEVICE auto& x() { return dim<0>(); }
1275  NDARRAY_HOST_DEVICE const auto& x() const { return dim<0>(); }
1276  NDARRAY_HOST_DEVICE auto& y() { return dim<1>(); }
1277  NDARRAY_HOST_DEVICE const auto& y() const { return dim<1>(); }
1278  NDARRAY_HOST_DEVICE auto& z() { return dim<2>(); }
1279  NDARRAY_HOST_DEVICE const auto& z() const { return dim<2>(); }
1280  NDARRAY_HOST_DEVICE auto& c() { return dim<2>(); }
1281  NDARRAY_HOST_DEVICE const auto& c() const { return dim<2>(); }
1282  NDARRAY_HOST_DEVICE auto& w() { return dim<3>(); }
1283  NDARRAY_HOST_DEVICE const auto& w() const { return dim<3>(); }
1284 
1287  NDARRAY_HOST_DEVICE index_t width() const { return x().extent(); }
1288  NDARRAY_HOST_DEVICE index_t height() const { return y().extent(); }
1289  NDARRAY_HOST_DEVICE index_t channels() const { return c().extent(); }
1290 
1293  NDARRAY_HOST_DEVICE index_t rows() const { return i().extent(); }
1294  NDARRAY_HOST_DEVICE index_t columns() const { return j().extent(); }
1295 
1298  template <class... OtherDims, class = enable_if_same_rank<OtherDims...>>
1299  NDARRAY_HOST_DEVICE bool operator==(const shape<OtherDims...>& other) const {
1300  return dims_ == other.dims();
1301  }
1302  template <class... OtherDims, class = enable_if_same_rank<OtherDims...>>
1303  NDARRAY_HOST_DEVICE bool operator!=(const shape<OtherDims...>& other) const {
1304  return dims_ != other.dims();
1305  }
1306 };
1307 
1308 namespace internal {
1309 
1310 template <size_t... DimIndices, class Shape, size_t... Extras>
1311 NDARRAY_HOST_DEVICE auto transpose_impl(const Shape& shape, index_sequence<Extras...>) {
1312  return make_shape(
1313  shape.template dim<DimIndices>()..., shape.template dim<sizeof...(DimIndices) + Extras>()...);
1314 }
1315 
1316 } // namespace internal
1317 
1330 template <size_t... DimIndices, class... Dims,
1331  class = internal::enable_if_permutation<sizeof...(DimIndices), DimIndices...>>
1332 NDARRAY_HOST_DEVICE auto transpose(const shape<Dims...>& shape) {
1333  return internal::transpose_impl<DimIndices...>(
1334  shape, internal::make_index_sequence<sizeof...(Dims) - sizeof...(DimIndices)>());
1335 }
1336 
1343 template <size_t... DimIndices, class... Dims>
1344 NDARRAY_HOST_DEVICE auto reorder(const shape<Dims...>& shape) {
1345  return make_shape(shape.template dim<DimIndices>()...);
1346 }
1347 
1348 namespace internal {
1349 
1350 template <class Fn, class Idx>
1351 NDARRAY_INLINE NDARRAY_HOST_DEVICE void for_each_index_in_order_impl(Fn&& fn, const Idx& idx) {
1352  fn(idx);
1353 }
1354 
1355 // These multiple dim at a time overloads help reduce pre-optimization
1356 // code size.
1357 template <class Fn, class OuterIdx, class Dim0>
1358 NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_index_in_order_impl(
1359  Fn&& fn, const OuterIdx& idx, const Dim0& dim0) {
1360  for (index_t i : dim0) {
1361  fn(std::tuple_cat(std::tuple<index_t>(i), idx));
1362  }
1363 }
1364 
1365 template <class Fn, class OuterIdx, class Dim0, class Dim1>
1366 NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_index_in_order_impl(
1367  Fn&& fn, const OuterIdx& idx, const Dim0& dim0, const Dim1& dim1) {
1368  for (index_t i : dim0) {
1369  for (index_t j : dim1) {
1370  fn(std::tuple_cat(std::tuple<index_t, index_t>(j, i), idx));
1371  }
1372  }
1373 }
1374 
1375 template <class Fn, class OuterIdx, class Dim0, class... Dims>
1376 NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_index_in_order_impl(
1377  Fn&& fn, const OuterIdx& idx, const Dim0& dim0, const Dims&... dims) {
1378  for (index_t i : dim0) {
1379  for_each_index_in_order_impl(fn, std::tuple_cat(std::tuple<index_t>(i), idx), dims...);
1380  }
1381 }
1382 
1383 template <class Fn, class OuterIdx, class Dim0, class Dim1, class... Dims>
1384 NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_index_in_order_impl(
1385  Fn&& fn, const OuterIdx& idx, const Dim0& dim0, const Dim1& dim1, const Dims&... dims) {
1386  for (index_t i : dim0) {
1387  for (index_t j : dim1) {
1388  for_each_index_in_order_impl(
1389  fn, std::tuple_cat(std::tuple<index_t, index_t>(j, i), idx), dims...);
1390  }
1391  }
1392 }
1393 
1394 template <class Dims, class Fn, size_t... Is>
1395 NDARRAY_INLINE NDARRAY_HOST_DEVICE void for_each_index_in_order(
1396  Fn&& fn, const Dims& dims, index_sequence<Is...>) {
1397  // We need to reverse the order of the dims so the last dim is
1398  // iterated innermost.
1399  for_each_index_in_order_impl(fn, std::tuple<>(), std::get<sizeof...(Is) - 1 - Is>(dims)...);
1400 }
1401 
1402 template <typename TSrc, typename TDst>
1403 NDARRAY_INLINE NDARRAY_HOST_DEVICE void move_assign(TSrc& src, TDst& dst) {
1404  dst = std::move(src);
1405 }
1406 
1407 template <typename TSrc, typename TDst>
1408 NDARRAY_INLINE NDARRAY_HOST_DEVICE void copy_assign(const TSrc& src, TDst& dst) {
1409  dst = src;
1410 }
1411 
1412 template <size_t D, class Ptr0>
1413 NDARRAY_INLINE NDARRAY_HOST_DEVICE void advance(Ptr0& ptr0) {
1414  std::get<0>(ptr0) += std::get<D>(std::get<1>(ptr0));
1415 }
1416 template <size_t D, class Ptr0, class Ptr1>
1417 NDARRAY_INLINE NDARRAY_HOST_DEVICE void advance(Ptr0& ptr0, Ptr1& ptr1) {
1418  std::get<0>(ptr0) += std::get<D>(std::get<1>(ptr0));
1419  std::get<0>(ptr1) += std::get<D>(std::get<1>(ptr1));
1420 }
1421 // If we ever need other than 1- or 2-way for_each_value, add a variadic
1422 // version of advance.
1423 
1424 template <class Fn, class Ptr0, class... Ptrs>
1425 NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_value_in_order_inner_dense(
1426  index_t extent, Fn&& fn, Ptr0 NDARRAY_RESTRICT ptr0, Ptrs NDARRAY_RESTRICT... ptrs) {
1427  Ptr0 end = ptr0 + extent;
1428  while (ptr0 < end) {
1429  fn(*ptr0++, *ptrs++...);
1430  }
1431 }
1432 
1433 template <size_t, class ExtentType, class Fn, class... Ptrs>
1434 NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_value_in_order_impl(
1435  std::true_type, const ExtentType& extent, Fn&& fn, Ptrs... ptrs) {
1436  index_t extent_d = std::get<0>(extent);
1437  if (all(std::get<0>(std::get<1>(ptrs)) == 1 ...)) {
1438  for_each_value_in_order_inner_dense(extent_d, fn, std::get<0>(ptrs)...);
1439  } else {
1440  for (index_t i = 0; i < extent_d; i++) {
1441  fn(*std::get<0>(ptrs)...);
1442  advance<0>(ptrs...);
1443  }
1444  }
1445 }
1446 
1447 template <size_t D, class ExtentType, class Fn, class... Ptrs>
1448 NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_value_in_order_impl(
1449  std::false_type, const ExtentType& extent, Fn&& fn, Ptrs... ptrs) {
1450  index_t extent_d = std::get<D>(extent);
1451  for (index_t i = 0; i < extent_d; i++) {
1452  using is_inner_loop = std::conditional_t<D == 1, std::true_type, std::false_type>;
1453  for_each_value_in_order_impl<D - 1>(is_inner_loop(), extent, fn, ptrs...);
1454  advance<D>(ptrs...);
1455  }
1456 }
1457 
1458 template <size_t D, class ExtentType, class Fn, class... Ptrs,
1459  std::enable_if_t<(D < std::tuple_size<ExtentType>::value), int> = 0>
1460 NDARRAY_INLINE NDARRAY_HOST_DEVICE void for_each_value_in_order(
1461  const ExtentType& extent, Fn&& fn, Ptrs... ptrs) {
1462  using is_inner_loop = std::conditional_t<D == 0, std::true_type, std::false_type>;
1463  for_each_value_in_order_impl<D>(is_inner_loop(), extent, fn, ptrs...);
1464 }
1465 
1466 // Scalar buffers are a special case. The enable_if here (and above) are a workaround for a bug in
1467 // old versions of GCC that causes this overload to be ambiguous.
1468 template <size_t D, class Fn, class... Ptrs, std::enable_if_t<(D == -1), int> = 0>
1469 NDARRAY_INLINE NDARRAY_HOST_DEVICE void for_each_value_in_order(
1470  const std::tuple<>& extent, Fn&& fn, Ptrs... ptrs) {
1471  fn(*std::get<0>(ptrs)...);
1472 }
1473 
1474 template <size_t Rank>
1475 NDARRAY_HOST_DEVICE auto make_default_dense_shape() {
1476  // The inner dimension is a dense_dim, unless the shape is rank 0.
1477  using inner_dim = std::conditional_t<(Rank > 0), std::tuple<dense_dim<>>, std::tuple<>>;
1478  return make_shape_from_tuple(
1479  std::tuple_cat(inner_dim(), tuple_of_n<dim<>, max<size_t>(1, Rank) - 1>()));
1480 }
1481 
1482 template <index_t CurrentStride>
1483 NDARRAY_HOST_DEVICE std::tuple<> make_compact_dims() {
1484  return std::tuple<>();
1485 }
1486 
1487 template <index_t CurrentStride, index_t Min, index_t Extent, index_t Stride, class... Dims>
1488 NDARRAY_HOST_DEVICE auto make_compact_dims(
1489  const dim<Min, Extent, Stride>& dim0, const Dims&... dims) {
1490 
1491  // If we know the extent of this dimension, we can also provide
1492  // a constant stride for the next dimension.
1493  constexpr index_t NextStride = static_mul(CurrentStride, Extent);
1494  // Give this dimension the current stride if we don't have one already,
1495  // and don't give it a runtime stride. If CurrentStride is static, that
1496  // will be the stride. If not, it will be dynamic, and resolved later.
1497  constexpr index_t NewStride = is_static(Stride) ? Stride : CurrentStride;
1498  return std::tuple_cat(std::make_tuple(dim<Min, Extent, NewStride>(dim0.min(), dim0.extent())),
1499  make_compact_dims<NextStride>(dims...));
1500 }
1501 
1502 template <class Dims, size_t... Is>
1503 NDARRAY_HOST_DEVICE auto make_compact_dims(const Dims& dims, index_sequence<Is...>) {
1504  // Currently, the algorithm is:
1505  // - If any dimension has a static stride greater than one, don't give any
1506  // static strides.
1507  // - If all dimensions are dynamic, use 1 as the next stride.
1508  // - If a dimension has static stride 1, use its Extent as the next stride.
1509  // This is very conservative, but the only thing I can figure out how to
1510  // express as constexpr with C++14 that doesn't risk doing dumb things.
1511  constexpr index_t MinStride =
1512  variadic_max(std::tuple_element<Is, Dims>::type::Stride == 1
1513  ? static_abs(std::tuple_element<Is, Dims>::type::Extent)
1514  : dynamic...);
1515  constexpr bool AnyStrideGreaterThanOne = any((std::tuple_element<Is, Dims>::type::Stride > 1)...);
1516  constexpr bool AllDynamic = all(is_dynamic(std::tuple_element<Is, Dims>::type::Stride)...);
1517  constexpr index_t NextStride = AnyStrideGreaterThanOne ? dynamic : (AllDynamic ? 1 : MinStride);
1518  return make_compact_dims<NextStride>(std::get<Is>(dims)...);
1519 }
1520 
1521 template <index_t Min, index_t Extent, index_t Stride, class DimSrc>
1522 NDARRAY_HOST_DEVICE bool is_dim_compatible(const dim<Min, Extent, Stride>&, const DimSrc& src) {
1523  return (is_dynamic(Min) || src.min() == Min) && (is_dynamic(Extent) || src.extent() == Extent) &&
1524  (is_dynamic(Stride) || src.stride() == Stride);
1525 }
1526 
1527 template <class... DimsDst, class ShapeSrc, size_t... Is>
1528 NDARRAY_HOST_DEVICE bool is_shape_compatible(
1529  const shape<DimsDst...>&, const ShapeSrc& src, index_sequence<Is...>) {
1530  return all(is_dim_compatible(DimsDst(), src.template dim<Is>())...);
1531 }
1532 
1533 template <class DimA, class DimB>
1534 NDARRAY_HOST_DEVICE auto clamp_dims(const DimA& a, const DimB& b) {
1535  constexpr index_t Min = static_max(DimA::Min, DimB::Min);
1536  constexpr index_t Max = static_min(DimA::Max, DimB::Max);
1537  constexpr index_t Extent = static_add(static_sub(Max, Min), 1);
1538  index_t min = internal::max(a.min(), b.min());
1539  index_t max = internal::min(a.max(), b.max());
1540  index_t extent = max - min + 1;
1541  return dim<Min, Extent, DimA::Stride>(min, extent, a.stride());
1542 }
1543 
1544 template <class DimsA, class DimsB, size_t... Is>
1545 NDARRAY_HOST_DEVICE auto clamp(const DimsA& a, const DimsB& b, index_sequence<Is...>) {
1546  return make_shape(clamp_dims(std::get<Is>(a), std::get<Is>(b))...);
1547 }
1548 
1549 // Return where the index I appears in Is...
1550 template <size_t I>
1551 constexpr size_t index_of() {
1552  // This constant is just something that would be absurd to use as a tuple
1553  // index, but has headroom so we can add to it without overflow.
1554  return 10000;
1555 }
1556 template <size_t I, size_t I0, size_t... Is>
1557 constexpr size_t index_of() {
1558  return I == I0 ? 0 : 1 + index_of<I, Is...>();
1559 }
1560 
1561 // Similar to std::get, but returns a one-element tuple if I is
1562 // in bounds, or an empty tuple if not.
1563 template <size_t I, class T, std::enable_if_t<(I < std::tuple_size<T>::value), int> = 0>
1564 NDARRAY_INLINE NDARRAY_HOST_DEVICE auto get_or_empty(const T& t) {
1565  return std::make_tuple(std::get<I>(t));
1566 }
1567 template <size_t I, class T, std::enable_if_t<(I >= std::tuple_size<T>::value), int> = 0>
1568 NDARRAY_INLINE NDARRAY_HOST_DEVICE std::tuple<> get_or_empty(const T& t) {
1569  return std::tuple<>();
1570 }
1571 
1572 // Perform the inverse of a shuffle with indices Is...
1573 template <size_t... Is, class T, size_t... Js>
1574 NDARRAY_HOST_DEVICE auto unshuffle(const T& t, index_sequence<Js...>) {
1575  return std::tuple_cat(get_or_empty<index_of<Js, Is...>()>(t)...);
1576 }
1577 template <size_t... Is, class... Ts>
1578 NDARRAY_HOST_DEVICE auto unshuffle(const std::tuple<Ts...>& t) {
1579  return unshuffle<Is...>(t, make_index_sequence<variadic_max(Is...) + 1>());
1580 }
1581 
1582 template <class ShapeDst, class ShapeSrc>
1583 using enable_if_shapes_compatible =
1584  std::enable_if_t<std::is_constructible<ShapeDst, ShapeSrc>::value>;
1585 
1586 template <class ShapeDst, class ShapeSrc>
1587 using enable_if_shapes_explicitly_compatible =
1588  std::enable_if_t<(ShapeSrc::rank() <= ShapeSrc::rank())>;
1589 
1590 template <class ShapeDst, class ShapeSrc>
1591 using enable_if_shapes_copy_compatible = std::enable_if_t<(ShapeDst::rank() == ShapeSrc::rank())>;
1592 
1593 template <class Alloc>
1594 using enable_if_allocator = decltype(internal::declval<Alloc>().allocate(0));
1595 
1596 } // namespace internal
1597 
1600 template <size_t Rank>
1601 using shape_of_rank = decltype(make_shape_from_tuple(internal::tuple_of_n<dim<>, Rank>()));
1602 
1605 template <size_t Rank>
1606 using dense_shape = decltype(internal::make_default_dense_shape<Rank>());
1607 
1619 template <class Shape>
1620 NDARRAY_HOST_DEVICE auto make_compact(const Shape& s) {
1621  auto static_compact =
1622  make_shape_from_tuple(internal::make_compact_dims(s.dims(), typename Shape::dim_indices()));
1623  static_compact.resolve();
1624  return static_compact;
1625 }
1626 
1628 template <index_t... Extents>
1629 using fixed_dense_shape =
1630  decltype(make_shape_from_tuple(internal::make_compact_dims<1>(dim<0, Extents>()...)));
1631 
1634 template <class ShapeDst, class ShapeSrc,
1635  class = internal::enable_if_shapes_compatible<ShapeSrc, ShapeDst>>
1636 NDARRAY_HOST_DEVICE bool is_compatible(const ShapeSrc& src) {
1637  return internal::is_shape_compatible(ShapeDst(), src, typename ShapeSrc::dim_indices());
1638 }
1639 
1645 // TODO: Consider enabling this kind of conversion implicitly. It is hard to
1646 // do without constructor overload ambiguity problems, and I'm also not sure
1647 // it's a good idea.
1648 template <class ShapeDst, class ShapeSrc,
1649  class = internal::enable_if_shapes_explicitly_compatible<ShapeDst, ShapeSrc>>
1650 NDARRAY_HOST_DEVICE ShapeDst convert_shape(const ShapeSrc& src) {
1651  assert(
1652  internal::is_trivial_slice<ShapeDst::rank()>(src.dims(), typename ShapeSrc::dim_indices()));
1653  return internal::convert_dims<typename ShapeDst::dims_type>(
1654  src.dims(), typename ShapeDst::dim_indices());
1655 }
1656 
1659 template <class ShapeDst, class ShapeSrc,
1660  class = internal::enable_if_shapes_explicitly_compatible<ShapeSrc, ShapeDst>>
1661 NDARRAY_HOST_DEVICE bool is_explicitly_compatible(const ShapeSrc& src) {
1662  return internal::is_shape_compatible(ShapeDst(), src, typename ShapeSrc::dim_indices());
1663 }
1664 
1673 template <class Shape, class Fn,
1674  class = internal::enable_if_callable<Fn, typename Shape::index_type>>
1675 NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_index_in_order(const Shape& shape, Fn&& fn) {
1676  internal::for_each_index_in_order(fn, shape.dims(), typename Shape::dim_indices());
1677 }
1678 template <class Shape, class Ptr, class Fn,
1679  class = internal::enable_if_callable<Fn, typename std::remove_pointer<Ptr>::type&>>
1680 NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_value_in_order(
1681  const Shape& shape, Ptr base, Fn&& fn) {
1682  // TODO: This is losing compile-time constant extents and strides info
1683  // (https://github.com/dsharlet/array/issues/1).
1684  auto base_and_stride = std::make_pair(base, shape.stride());
1685  internal::for_each_value_in_order<Shape::rank() - 1>(shape.extent(), fn, base_and_stride);
1686 }
1687 
1696 template <class Shape, class ShapeA, class PtrA, class ShapeB, class PtrB, class Fn,
1697  class = internal::enable_if_callable<Fn, typename std::remove_pointer<PtrA>::type&,
1698  typename std::remove_pointer<PtrB>::type&>>
1699 NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_value_in_order(const Shape& shape,
1700  const ShapeA& shape_a, PtrA base_a, const ShapeB& shape_b, PtrB base_b, Fn&& fn) {
1701  base_a += shape_a[shape.min()];
1702  base_b += shape_b[shape.min()];
1703  // TODO: This is losing compile-time constant extents and strides info
1704  // (https://github.com/dsharlet/array/issues/1).
1705  auto a = std::make_pair(base_a, shape_a.stride());
1706  auto b = std::make_pair(base_b, shape_b.stride());
1707  internal::for_each_value_in_order<Shape::rank() - 1>(shape.extent(), fn, a, b);
1708 }
1709 
1710 namespace internal {
1711 
1712 NDARRAY_INLINE NDARRAY_HOST_DEVICE bool can_fuse(const dim<>& inner, const dim<>& outer) {
1713  return inner.stride() * inner.extent() == outer.stride();
1714 }
1715 
1716 NDARRAY_INLINE NDARRAY_HOST_DEVICE dim<> fuse(const dim<>& inner, const dim<>& outer) {
1717  assert(can_fuse(inner, outer));
1718  return dim<>(
1719  inner.min() + outer.min() * inner.extent(), inner.extent() * outer.extent(), inner.stride());
1720 }
1721 
1722 struct copy_dims {
1723  dim<> src;
1724  dim<> dst;
1725 };
1726 
1727 inline bool operator<(const dim<>& l, const dim<>& r) { return l.stride() < r.stride(); }
1728 
1729 inline bool operator<(const copy_dims& l, const copy_dims& r) {
1730  return l.dst.stride() < r.dst.stride();
1731 }
1732 
1733 // We need a sort that only needs to deal with very small lists,
1734 // and extra complexity here is costly in code size/compile time.
1735 // This is a rare job for bubble sort!
1736 template <class Iterator>
1737 NDARRAY_HOST_DEVICE void bubble_sort(Iterator begin, Iterator end) {
1738  for (Iterator i = begin; i != end; ++i) {
1739  for (Iterator j = i; j != end; ++j) {
1740  if (*j < *i) { std::swap(*i, *j); }
1741  }
1742  }
1743 }
1744 
1745 // Sort the dims such that strides are increasing from dim 0, and contiguous
1746 // dimensions are fused.
1747 template <class Shape>
1748 NDARRAY_HOST_DEVICE shape_of_rank<Shape::rank()> dynamic_optimize_shape(const Shape& shape) {
1749  auto dims = internal::tuple_to_array<dim<>>(shape.dims());
1750 
1751  // Sort the dims by stride.
1752  bubble_sort(dims.begin(), dims.end());
1753 
1754  // Find dimensions that are contiguous and fuse them.
1755  size_t rank = dims.size();
1756  for (size_t i = 0; i + 1 < rank;) {
1757  if (can_fuse(dims[i], dims[i + 1])) {
1758  dims[i] = fuse(dims[i], dims[i + 1]);
1759  for (size_t j = i + 1; j + 1 < rank; j++) {
1760  dims[j] = dims[j + 1];
1761  }
1762  rank--;
1763  } else {
1764  i++;
1765  }
1766  }
1767 
1768  // Unfortunately, we can't make the rank of the resulting shape smaller. Fill
1769  // the end of the array with size 1 dimensions.
1770  for (size_t i = rank; i < dims.size(); i++) {
1771  dims[i] = dim<>(0, 1, 0);
1772  }
1773 
1774  return shape_of_rank<Shape::rank()>(array_to_tuple(dims));
1775 }
1776 
1777 // Optimize a src and dst shape. The dst shape is made dense, and contiguous
1778 // dimensions are fused.
1779 template <class ShapeSrc, class ShapeDst,
1780  class = enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
1781 NDARRAY_HOST_DEVICE auto dynamic_optimize_copy_shapes(const ShapeSrc& src, const ShapeDst& dst) {
1782  constexpr size_t rank = ShapeSrc::rank();
1783  static_assert(rank == ShapeDst::rank(), "copy shapes must have same rank.");
1784  auto src_dims = internal::tuple_to_array<dim<>>(src.dims());
1785  auto dst_dims = internal::tuple_to_array<dim<>>(dst.dims());
1786 
1787  std::array<copy_dims, rank> dims;
1788  for (size_t i = 0; i < rank; i++) {
1789  dims[i] = {src_dims[i], dst_dims[i]};
1790  }
1791 
1792  // Sort the dims by the dst stride.
1793  bubble_sort(dims.begin(), dims.end());
1794 
1795  // Find dimensions that are contiguous and fuse them.
1796  size_t new_rank = dims.size();
1797  for (size_t i = 0; i + 1 < new_rank;) {
1798  if (dims[i].src.extent() == dims[i].dst.extent() && can_fuse(dims[i].src, dims[i + 1].src) &&
1799  can_fuse(dims[i].dst, dims[i + 1].dst)) {
1800  dims[i].src = fuse(dims[i].src, dims[i + 1].src);
1801  dims[i].dst = fuse(dims[i].dst, dims[i + 1].dst);
1802  for (size_t j = i + 1; j + 1 < new_rank; j++) {
1803  dims[j] = dims[j + 1];
1804  }
1805  new_rank--;
1806  } else {
1807  i++;
1808  }
1809  }
1810 
1811  // Unfortunately, we can't make the rank of the resulting shape dynamic. Fill
1812  // the end of the array with size 1 dimensions.
1813  for (size_t i = new_rank; i < dims.size(); i++) {
1814  dims[i] = {dim<>(0, 1, 0), dim<>(0, 1, 0)};
1815  }
1816 
1817  for (size_t i = 0; i < dims.size(); i++) {
1818  src_dims[i] = dims[i].src;
1819  dst_dims[i] = dims[i].dst;
1820  }
1821 
1822  return std::make_pair(
1823  shape_of_rank<rank>(array_to_tuple(src_dims)), shape_of_rank<rank>(array_to_tuple(dst_dims)));
1824 }
1825 
1826 template <class Shape>
1827 NDARRAY_HOST_DEVICE auto optimize_shape(const Shape& shape) {
1828  // In the general case, dynamically optimize the shape.
1829  return dynamic_optimize_shape(shape);
1830 }
1831 
1832 template <class Dim0>
1833 NDARRAY_HOST_DEVICE auto optimize_shape(const shape<Dim0>& shape) {
1834  // Nothing to do for rank 1 shapes.
1835  return shape;
1836 }
1837 
1838 template <class ShapeSrc, class ShapeDst>
1839 NDARRAY_HOST_DEVICE auto optimize_copy_shapes(const ShapeSrc& src, const ShapeDst& dst) {
1840  return dynamic_optimize_copy_shapes(src, dst);
1841 }
1842 
1843 template <class Dim0Src, class Dim0Dst>
1844 NDARRAY_HOST_DEVICE auto optimize_copy_shapes(
1845  const shape<Dim0Src>& src, const shape<Dim0Dst>& dst) {
1846  // Nothing to do for rank 1 shapes.
1847  return std::make_pair(src, dst);
1848 }
1849 
1850 template <class T>
1851 NDARRAY_HOST_DEVICE T* pointer_add(T* x, index_t offset) {
1852  return x != nullptr ? x + offset : x;
1853 }
1854 
1855 } // namespace internal
1856 
1858 template <class Shape>
1860 public:
1861  using shape_type = Shape;
1862 
1865  template <class Fn>
1866  NDARRAY_HOST_DEVICE static void for_each_index(const Shape& shape, Fn&& fn) {
1867  for_each_index_in_order(shape, fn);
1868  }
1869 
1873  template <class Ptr, class Fn>
1874  NDARRAY_HOST_DEVICE static void for_each_value(const Shape& shape, Ptr base, Fn&& fn) {
1875  auto opt_shape = internal::optimize_shape(shape);
1876  for_each_value_in_order(opt_shape, base, fn);
1877  }
1878 };
1879 
1882 template <class ShapeSrc, class ShapeDst>
1884 public:
1885  using src_shape_type = ShapeSrc;
1886  using dst_shape_type = ShapeDst;
1887 
1892  template <class Fn, class TSrc, class TDst>
1893  NDARRAY_HOST_DEVICE static void for_each_value(
1894  const ShapeSrc& shape_src, TSrc src, const ShapeDst& shape_dst, TDst dst, Fn&& fn) {
1895  // For this function, we don't care about the order in which the callback is
1896  // called. Optimize the shapes for memory access order.
1897  auto opt_shape = internal::optimize_copy_shapes(shape_src, shape_dst);
1898  const auto& opt_shape_src = opt_shape.first;
1899  const auto& opt_shape_dst = opt_shape.second;
1900 
1901  for_each_value_in_order(opt_shape_dst, opt_shape_src, src, opt_shape_dst, dst, fn);
1902  }
1903 };
1904 
1921 template <size_t... LoopOrder, class Shape, class Fn,
1922  class = internal::enable_if_callable<Fn, typename Shape::index_type>,
1923  std::enable_if_t<(sizeof...(LoopOrder) == 0), int> = 0>
1924 NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_index(const Shape& s, Fn&& fn) {
1926 }
1927 template <size_t... LoopOrder, class Shape, class Fn,
1928  class = internal::enable_if_applicable<Fn, typename Shape::index_type>,
1929  std::enable_if_t<(sizeof...(LoopOrder) == 0), int> = 0>
1930 NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_all_indices(const Shape& s, Fn&& fn) {
1931  using index_type = typename Shape::index_type;
1932  for_each_index(s, [fn = std::move(fn)](const index_type& i) { internal::apply(fn, i); });
1933 }
1934 template <size_t... LoopOrder, class Shape, class Fn,
1935  class = internal::enable_if_callable<Fn, index_of_rank<sizeof...(LoopOrder)>>,
1936  std::enable_if_t<(sizeof...(LoopOrder) != 0), int> = 0>
1937 NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_index(const Shape& s, Fn&& fn) {
1938  using index_type = index_of_rank<sizeof...(LoopOrder)>;
1939  for_each_index_in_order(reorder<LoopOrder...>(s),
1940  [fn = std::move(fn)](const index_type& i) { fn(internal::unshuffle<LoopOrder...>(i)); });
1941 }
1942 template <size_t... LoopOrder, class Shape, class Fn,
1943  class = internal::enable_if_callable<Fn, decltype(LoopOrder)...>,
1944  std::enable_if_t<(sizeof...(LoopOrder) != 0), int> = 0>
1945 NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_all_indices(const Shape& s, Fn&& fn) {
1946  using index_type = index_of_rank<sizeof...(LoopOrder)>;
1947  for_each_index_in_order(reorder<LoopOrder...>(s), [fn = std::move(fn)](const index_type& i) {
1948  internal::apply(fn, internal::unshuffle<LoopOrder...>(i));
1949  });
1950 }
1951 
1952 template <class T, class Shape>
1954 template <class T, class Shape, class Alloc>
1955 class array;
1956 
1957 template <class T, class Shape>
1959 
1961 template <class T, class Shape>
1962 NDARRAY_HOST_DEVICE array_ref<T, Shape> make_array_ref(T* base, const Shape& shape) {
1963  return {base, shape};
1964 }
1965 
1966 namespace internal {
1967 
1968 template <class T, class Shape>
1969 NDARRAY_HOST_DEVICE array_ref<T, Shape> make_array_ref_no_resolve(T* base, const Shape& shape) {
1970  return {base, shape, std::false_type()};
1971 }
1972 
1973 template <class T, class Shape, class... Args>
1974 NDARRAY_HOST_DEVICE auto make_array_ref_at(
1975  T base, const Shape& shape, const std::tuple<Args...>& args) {
1976  auto new_shape = shape[args];
1977  auto new_mins = mins_of_intervals(args, shape.dims(), make_index_sequence<sizeof...(Args)>());
1978  auto old_min_offset = shape[new_mins];
1979  return make_array_ref_no_resolve(internal::pointer_add(base, old_min_offset), new_shape);
1980 }
1981 
1982 } // namespace internal
1983 
1987 template <class T, class Shape>
1988 class array_ref {
1989 public:
1991  using value_type = T;
1992  using reference = value_type&;
1993  using const_reference = const value_type&;
1994  using pointer = value_type*;
1996  using shape_type = Shape;
1997  using index_type = typename Shape::index_type;
1999  using size_type = size_t;
2000 
2002  static constexpr size_t rank() { return Shape::rank(); }
2003 
2005  static constexpr bool is_scalar() { return Shape::is_scalar(); }
2006 
2007 private:
2008  template <class OtherShape>
2009  using enable_if_shape_compatible = internal::enable_if_shapes_compatible<Shape, OtherShape>;
2010 
2011  template <class... Args>
2012  using enable_if_all_indices =
2013  std::enable_if_t<sizeof...(Args) == rank() && internal::all_of_type<index_t, Args...>::value>;
2014 
2015  template <class... Args>
2016  using enable_if_any_slices =
2017  std::enable_if_t<sizeof...(Args) == rank() &&
2018  internal::all_of_any_type<std::tuple<interval<>, dim<>>, Args...>::value &&
2019  !internal::all_of_type<index_t, Args...>::value>;
2020 
2021  template <size_t Dim>
2022  using enable_if_dim = std::enable_if_t < Dim<rank()>;
2023 
2024  pointer base_;
2025  Shape shape_;
2026 
2027 public:
2030  NDARRAY_HOST_DEVICE array_ref(pointer base = nullptr, const Shape& shape = Shape())
2031  : base_(base), shape_(shape) {
2032  shape_.resolve();
2033  }
2034 
2035  NDARRAY_HOST_DEVICE array_ref(pointer base, const Shape& shape, std::false_type /*resolve*/)
2036  : base_(base), shape_(shape) {}
2037 
2039  NDARRAY_HOST_DEVICE array_ref(const array_ref& other) = default;
2040  NDARRAY_HOST_DEVICE array_ref(array_ref&& other) = default;
2041  NDARRAY_HOST_DEVICE array_ref& operator=(const array_ref& other) = default;
2042  NDARRAY_HOST_DEVICE array_ref& operator=(array_ref&& other) = default;
2043 
2045  template <class OtherShape, class = enable_if_shape_compatible<OtherShape>>
2046  NDARRAY_HOST_DEVICE array_ref(const array_ref<T, OtherShape>& other)
2047  : array_ref(other.base(), other.shape(), std::false_type()) {}
2048  template <class OtherShape, class = enable_if_shape_compatible<OtherShape>>
2049  NDARRAY_HOST_DEVICE array_ref& operator=(const array_ref<T, OtherShape>& other) {
2050  base_ = other.base();
2051  shape_ = other.shape();
2052  return *this;
2053  }
2054 
2056  NDARRAY_HOST_DEVICE reference operator[](const index_type& indices) const {
2057  return base_[shape_[indices]];
2058  }
2059  template <class... Args, class = enable_if_all_indices<Args...>>
2060  NDARRAY_HOST_DEVICE reference operator()(Args... indices) const {
2061  return base_[shape_(indices...)];
2062  }
2063 
2068  template <class... Args, class = enable_if_any_slices<Args...>>
2069  NDARRAY_HOST_DEVICE auto operator[](const std::tuple<Args...>& args) const {
2070  return internal::make_array_ref_at(base_, shape_, args);
2071  }
2072  template <class... Args, class = enable_if_any_slices<Args...>>
2073  NDARRAY_HOST_DEVICE auto operator()(Args... args) const {
2074  return internal::make_array_ref_at(base_, shape_, std::make_tuple(args...));
2075  }
2076 
2080  template <class Fn, class = internal::enable_if_callable<Fn, reference>>
2081  NDARRAY_HOST_DEVICE void for_each_value(Fn&& fn) const {
2082  shape_traits_type::for_each_value(shape_, base_, fn);
2083  }
2084 
2086  NDARRAY_HOST_DEVICE pointer base() const { return base_; }
2087 
2090  NDARRAY_HOST_DEVICE pointer data() const {
2091  return internal::pointer_add(base_, shape_.flat_min());
2092  }
2093 
2095  NDARRAY_HOST_DEVICE Shape& shape() { return shape_; }
2096  NDARRAY_HOST_DEVICE const Shape& shape() const { return shape_; }
2097 
2098  template <size_t D, class = enable_if_dim<D>>
2099  NDARRAY_HOST_DEVICE auto& dim() {
2100  return shape_.template dim<D>();
2101  }
2102  template <size_t D, class = enable_if_dim<D>>
2103  NDARRAY_HOST_DEVICE const auto& dim() const {
2104  return shape_.template dim<D>();
2105  }
2106  const nda::dim<> dim(size_t d) const { return shape_.dim(d); }
2107  NDARRAY_HOST_DEVICE size_type size() const { return shape_.size(); }
2108  NDARRAY_HOST_DEVICE bool empty() const { return base() != nullptr ? shape_.empty() : true; }
2109  NDARRAY_HOST_DEVICE bool is_compact() const { return shape_.is_compact(); }
2110 
2113  NDARRAY_HOST_DEVICE auto& i() { return shape_.i(); }
2114  NDARRAY_HOST_DEVICE const auto& i() const { return shape_.i(); }
2115  NDARRAY_HOST_DEVICE auto& j() { return shape_.j(); }
2116  NDARRAY_HOST_DEVICE const auto& j() const { return shape_.j(); }
2117  NDARRAY_HOST_DEVICE auto& k() { return shape_.k(); }
2118  NDARRAY_HOST_DEVICE const auto& k() const { return shape_.k(); }
2119 
2122  NDARRAY_HOST_DEVICE auto& x() { return shape_.x(); }
2123  NDARRAY_HOST_DEVICE const auto& x() const { return shape_.x(); }
2124  NDARRAY_HOST_DEVICE auto& y() { return shape_.y(); }
2125  NDARRAY_HOST_DEVICE const auto& y() const { return shape_.y(); }
2126  NDARRAY_HOST_DEVICE auto& z() { return shape_.z(); }
2127  NDARRAY_HOST_DEVICE const auto& z() const { return shape_.z(); }
2128  NDARRAY_HOST_DEVICE auto& c() { return shape_.c(); }
2129  NDARRAY_HOST_DEVICE const auto& c() const { return shape_.c(); }
2130  NDARRAY_HOST_DEVICE auto& w() { return shape_.w(); }
2131  NDARRAY_HOST_DEVICE const auto& w() const { return shape_.w(); }
2132 
2135  NDARRAY_HOST_DEVICE index_t width() const { return shape_.width(); }
2136  NDARRAY_HOST_DEVICE index_t height() const { return shape_.height(); }
2137  NDARRAY_HOST_DEVICE index_t channels() const { return shape_.channels(); }
2138 
2141  NDARRAY_HOST_DEVICE index_t rows() const { return shape_.rows(); }
2142  NDARRAY_HOST_DEVICE index_t columns() const { return shape_.columns(); }
2143 
2147  // TODO: Maybe this should just check for equality of the shape and pointer,
2148  // and let the free function equal serve this purpose.
2149  NDARRAY_HOST_DEVICE bool operator!=(const array_ref& other) const {
2150  if (shape_ != other.shape_) { return true; }
2151 
2152  // TODO: This currently calls operator!= on all elements of the array_ref,
2153  // even after we find a non-equal element
2154  // (https://github.com/dsharlet/array/issues/4).
2155  bool result = false;
2157  shape_, base_, other.shape_, other.base_, [&](const_reference a, const_reference b) {
2158  if (a != b) { result = true; }
2159  });
2160  return result;
2161  }
2162  NDARRAY_HOST_DEVICE bool operator==(const array_ref& other) const { return !operator!=(other); }
2163 
2164  NDARRAY_HOST_DEVICE const array_ref<T, Shape>& ref() const { return *this; }
2165 
2167  NDARRAY_HOST_DEVICE const const_array_ref<T, Shape> cref() const {
2168  return const_array_ref<T, Shape>(base_, shape_);
2169  }
2170  NDARRAY_HOST_DEVICE operator const_array_ref<T, Shape>() const { return cref(); }
2171 
2173  template <std::size_t R = rank(), typename = std::enable_if_t<R == 0>>
2174  NDARRAY_HOST_DEVICE operator reference() const {
2175  return *base_;
2176  }
2177 
2180  NDARRAY_HOST_DEVICE void set_shape(const Shape& new_shape, index_t offset = 0) {
2181  assert(new_shape.is_resolved());
2182  assert(new_shape.is_subset_of(shape_, -offset));
2183  shape_ = new_shape;
2184  base_ = internal::pointer_add(base_, offset);
2185  }
2186 };
2187 
2189 template <class T, size_t Rank>
2191 template <class T, size_t Rank>
2193 
2195 template <class T, size_t Rank>
2197 template <class T, size_t Rank>
2199 
2201 template <class T, class Shape, class Alloc = std::allocator<T>>
2202 class array {
2203 public:
2205  using allocator_type = Alloc;
2206  using alloc_traits = std::allocator_traits<Alloc>;
2207 
2209  using value_type = T;
2210  using reference = value_type&;
2211  using const_reference = const value_type&;
2212  using pointer = typename alloc_traits::pointer;
2213  using const_pointer = typename alloc_traits::const_pointer;
2214 
2216  using shape_type = Shape;
2217  using index_type = typename Shape::index_type;
2220  using size_type = size_t;
2221 
2223  static constexpr size_t rank() { return Shape::rank(); }
2224 
2226  static constexpr bool is_scalar() { return Shape::is_scalar(); }
2227 
2228 private:
2229  template <class... Args>
2230  using enable_if_all_indices =
2231  std::enable_if_t<sizeof...(Args) == rank() && internal::all_of_type<index_t, Args...>::value>;
2232 
2233  template <class... Args>
2234  using enable_if_any_slices =
2235  std::enable_if_t<sizeof...(Args) == rank() &&
2236  internal::all_of_any_type<std::tuple<interval<>, dim<>>, Args...>::value &&
2237  !internal::all_of_type<index_t, Args...>::value>;
2238 
2239  template <size_t Dim>
2240  using enable_if_dim = std::enable_if_t < Dim<rank()>;
2241 
2242  Alloc alloc_;
2243  pointer buffer_;
2244  size_type buffer_size_;
2245  pointer base_;
2246  Shape shape_;
2247 
2248  // After allocate the array is allocated but uninitialized.
2249  void allocate() {
2250  assert(!buffer_);
2251  shape_.resolve();
2252  size_type flat_extent = shape_.flat_extent();
2253  if (flat_extent > 0) {
2254  buffer_size_ = flat_extent;
2255  buffer_ = alloc_traits::allocate(alloc_, buffer_size_);
2256  }
2257  base_ = buffer_ - shape_.flat_min();
2258  }
2259 
2260  // Call the constructor on all of the elements of the array.
2261  void construct() {
2262  assert(base_ || shape_.empty());
2263  for_each_value([&](T& x) { alloc_traits::construct(alloc_, &x); });
2264  }
2265  void construct(const T& init) {
2266  assert(base_ || shape_.empty());
2267  for_each_value([&](T& x) { alloc_traits::construct(alloc_, &x, init); });
2268  }
2269  void copy_construct(const array& other) {
2270  assert(base_ || shape_.empty());
2271  assert(shape_ == other.shape_);
2272  copy_shape_traits_type::for_each_value(other.shape_, other.base_, shape_, base_,
2273  [&](const_reference src, reference dst) { alloc_traits::construct(alloc_, &dst, src); });
2274  }
2275  void move_construct(array& other) {
2276  assert(base_ || shape_.empty());
2277  assert(shape_ == other.shape_);
2278  copy_shape_traits_type::for_each_value(
2279  other.shape_, other.base_, shape_, base_, [&](reference src, reference dst) {
2280  alloc_traits::construct(alloc_, &dst, std::move(src));
2281  });
2282  }
2283 
2284  // Call the dstructor on every element.
2285  void destroy() {
2286  assert(base_ || shape_.empty());
2287  for_each_value([&](T& x) { alloc_traits::destroy(alloc_, &x); });
2288  }
2289 
2290  void deallocate() {
2291  if (base_) {
2292  destroy();
2293  base_ = nullptr;
2294  shape_ = Shape();
2295  alloc_traits::deallocate(alloc_, buffer_, buffer_size_);
2296  buffer_ = nullptr;
2297  }
2298  }
2299 
2300  static Alloc get_allocator_for_move(array& other, std::true_type) {
2301  return std::move(other.alloc_);
2302  }
2303  static Alloc get_allocator_for_move(array& other, std::false_type) { return Alloc(); }
2304  static Alloc get_allocator_for_move(array& other) {
2305  return get_allocator_for_move(
2306  other, typename alloc_traits::propagate_on_container_move_assignment());
2307  }
2308 
2309  void swap_except_allocator(array& other) {
2310  using std::swap;
2311  swap(buffer_, other.buffer_);
2312  swap(buffer_size_, other.buffer_size_);
2313  swap(base_, other.base_);
2314  swap(shape_, other.shape_);
2315  }
2316 
2317 public:
2321  array() : array(Shape()) {}
2322  explicit array(const Alloc& alloc) : array(Shape(), alloc) {}
2323 
2326  array(const Shape& shape, const T& value, const Alloc& alloc) : array(alloc) {
2327  assign(shape, value);
2328  }
2329  array(const Shape& shape, const T& value) : array() { assign(shape, value); }
2330 
2333  explicit array(const Shape& shape, const Alloc& alloc)
2334  : alloc_(alloc), buffer_(nullptr), buffer_size_(0), base_(nullptr), shape_(shape) {
2335  allocate();
2336  construct();
2337  }
2338  explicit array(const Shape& shape)
2339  : buffer_(nullptr), buffer_size_(0), base_(nullptr), shape_(shape) {
2340  allocate();
2341  construct();
2342  }
2343 
2346  array(const array& other)
2347  : alloc_(alloc_traits::select_on_container_copy_construction(other.get_allocator())),
2348  buffer_(nullptr), buffer_size_(0), base_(nullptr) {
2349  assign(other);
2350  }
2351 
2354  array(const array& other, const Alloc& alloc) : array(alloc) { assign(other); }
2355 
2361  array(array&& other)
2362  : alloc_(get_allocator_for_move(other)), buffer_(nullptr), buffer_size_(0), base_(nullptr) {
2363  using std::swap;
2364  // If we already took other's allocator, it might be in an undefined state.
2365  // Just assume we can swap in that case.
2366  if (typename alloc_traits::propagate_on_container_move_assignment() ||
2367  alloc_ == other.get_allocator()) {
2368  swap_except_allocator(other);
2369  } else {
2370  shape_ = other.shape_;
2371  allocate();
2372  move_construct(other);
2373  }
2374  }
2375 
2381  array(array&& other, const Alloc& alloc)
2382  : alloc_(alloc), buffer_(nullptr), buffer_size_(0), base_(nullptr) {
2383  using std::swap;
2384  if (alloc_ == other.get_allocator()) {
2385  swap_except_allocator(other);
2386  } else {
2387  shape_ = other.shape_;
2388  allocate();
2389  move_construct(other);
2390  }
2391  }
2392 
2393  ~array() { deallocate(); }
2394 
2395  // Let's choose not to provide array(const array_ref&) constructors. This is
2396  // a deep copy that may be unintentional, perhaps it is better to require
2397  // being explicit via `make_copy`.
2398 
2403  array& operator=(const array& other) {
2404  if (base_ == other.base_) {
2405  if (base_) {
2406  assert(shape_ == other.shape_);
2407  } else {
2408  shape_ = other.shape_;
2409  assert(shape_.empty());
2410  }
2411  return *this;
2412  }
2413 
2414  if (alloc_traits::propagate_on_container_copy_assignment::value) {
2415  if (alloc_ != other.get_allocator()) { deallocate(); }
2416  alloc_ = other.get_allocator();
2417  }
2418 
2419  assign(other);
2420  return *this;
2421  }
2422 
2427  array& operator=(array&& other) {
2428  using std::swap;
2429  if (base_ == other.base_) {
2430  if (base_) {
2431  assert(shape_ == other.shape_);
2432  } else {
2433  swap(shape_, other.shape_);
2434  assert(shape_.empty());
2435  }
2436  return *this;
2437  }
2438 
2439  if (std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value) {
2440  swap(alloc_, other.alloc_);
2441  swap_except_allocator(other);
2442  } else if (alloc_ == other.get_allocator()) {
2443  swap_except_allocator(other);
2444  } else {
2445  assign(std::move(other));
2446  }
2447  return *this;
2448  }
2449 
2453  void assign(const array& other) {
2454  if (base_ == other.base_) {
2455  if (base_) {
2456  assert(shape_ == other.shape_);
2457  } else {
2458  shape_ = other.shape_;
2459  assert(shape_.empty());
2460  }
2461  return;
2462  }
2463  if (base_ && shape_ == other.shape_) {
2464  destroy();
2465  } else {
2466  deallocate();
2467  shape_ = other.shape_;
2468  allocate();
2469  }
2470  copy_construct(other);
2471  }
2472  void assign(array&& other) {
2473  if (base_ == other.base_) {
2474  if (base_) {
2475  assert(shape_ == other.shape_);
2476  } else {
2477  shape_ = other.shape_;
2478  assert(shape_.empty());
2479  }
2480  return;
2481  }
2482  if (base_ && shape_ == other.shape_) {
2483  destroy();
2484  } else {
2485  deallocate();
2486  shape_ = other.shape_;
2487  allocate();
2488  }
2489  move_construct(other);
2490  }
2491 
2494  void assign(Shape shape, const T& value) {
2495  shape.resolve();
2496  if (shape_ == shape) {
2497  destroy();
2498  } else {
2499  deallocate();
2500  shape_ = shape;
2501  allocate();
2502  }
2503  construct(value);
2504  }
2505 
2507  const Alloc& get_allocator() const { return alloc_; }
2508 
2510  reference operator[](const index_type& indices) { return base_[shape_[indices]]; }
2511  const_reference operator[](const index_type& indices) const { return base_[shape_[indices]]; }
2512  template <class... Args, class = enable_if_all_indices<Args...>>
2513  reference operator()(Args... indices) {
2514  return base_[shape_(indices...)];
2515  }
2516  template <class... Args, class = enable_if_all_indices<Args...>>
2517  const_reference operator()(Args... indices) const {
2518  return base_[shape_(indices...)];
2519  }
2520 
2524  template <class... Args, class = enable_if_any_slices<Args...>>
2525  auto operator[](const std::tuple<Args...>& args) {
2526  return internal::make_array_ref_at(base_, shape_, args);
2527  }
2528  template <class... Args, class = enable_if_any_slices<Args...>>
2529  auto operator()(Args... args) {
2530  return internal::make_array_ref_at(base_, shape_, std::make_tuple(args...));
2531  }
2532  template <class... Args, class = enable_if_any_slices<Args...>>
2533  auto operator[](const std::tuple<Args...>& args) const {
2534  return internal::make_array_ref_at(base_, shape_, args);
2535  }
2536  template <class... Args, class = enable_if_any_slices<Args...>>
2537  auto operator()(Args... args) const {
2538  return internal::make_array_ref_at(base_, shape_, std::make_tuple(args...));
2539  }
2540 
2543  template <class Fn, class = internal::enable_if_callable<Fn, reference>>
2544  void for_each_value(Fn&& fn) {
2545  shape_traits_type::for_each_value(shape_, base_, fn);
2546  }
2547  template <class Fn, class = internal::enable_if_callable<Fn, const_reference>>
2548  void for_each_value(Fn&& fn) const {
2549  shape_traits_type::for_each_value(shape_, base_, fn);
2550  }
2551 
2553  pointer base() { return base_; }
2554  const_pointer base() const { return base_; }
2555 
2558  pointer data() { return internal::pointer_add(base_, shape_.flat_min()); }
2559  const_pointer data() const { return internal::pointer_add(base_, shape_.flat_min()); }
2560 
2562  const Shape& shape() const { return shape_; }
2563 
2564  template <size_t D, class = enable_if_dim<D>>
2565  const auto& dim() const {
2566  return shape_.template dim<D>();
2567  }
2568  const nda::dim<> dim(size_t d) const { return shape_.dim(d); }
2569  size_type size() const { return shape_.size(); }
2570  bool empty() const { return shape_.empty(); }
2571  bool is_compact() const { return shape_.is_compact(); }
2572 
2577  void clear() {
2578  deallocate();
2579  shape_ = Shape();
2580  allocate();
2581  construct();
2582  }
2583 
2586  void reshape(Shape new_shape) {
2587  new_shape.resolve();
2588  if (shape_ == new_shape) { return; }
2589 
2590  // Allocate an array with the new shape.
2591  array new_array(new_shape);
2592 
2593  // Move the common elements to the new array.
2594  Shape intersection =
2595  internal::clamp(new_shape.dims(), shape_.dims(), typename Shape::dim_indices());
2596  pointer intersection_base =
2597  internal::pointer_add(new_array.base_, new_shape[intersection.min()]);
2598  copy_shape_traits_type::for_each_value(
2599  shape_, base_, intersection, intersection_base, internal::move_assign<T, T>);
2600 
2601  *this = std::move(new_array);
2602  }
2603 
2608  void set_shape(const Shape& new_shape, index_t offset = 0) {
2609  static_assert(std::is_trivial<value_type>::value, "set_shape is broken for non-trivial types.");
2610  assert(new_shape.is_resolved());
2611  assert(new_shape.is_subset_of(shape_, -offset));
2612  shape_ = new_shape;
2613  base_ = internal::pointer_add(base_, offset);
2614  }
2615 
2618  const auto& i() const { return shape_.i(); }
2619  const auto& j() const { return shape_.j(); }
2620  const auto& k() const { return shape_.k(); }
2621 
2624  const auto& x() const { return shape_.x(); }
2625  const auto& y() const { return shape_.y(); }
2626  const auto& z() const { return shape_.z(); }
2627  const auto& c() const { return shape_.c(); }
2628  const auto& w() const { return shape_.w(); }
2629 
2632  index_t width() const { return shape_.width(); }
2633  index_t height() const { return shape_.height(); }
2634  index_t channels() const { return shape_.channels(); }
2635 
2638  index_t rows() const { return shape_.rows(); }
2639  index_t columns() const { return shape_.columns(); }
2640 
2644  bool operator!=(const array& other) const { return cref() != other.cref(); }
2645  bool operator==(const array& other) const { return cref() == other.cref(); }
2646 
2649  void swap(array& other) {
2650  using std::swap;
2651 
2652  if (alloc_traits::propagate_on_container_swap::value) {
2653  swap(alloc_, other.alloc_);
2654  swap_except_allocator(other);
2655  } else {
2656  // TODO: If the shapes are equal, we could swap each element without the
2657  // temporary allocation.
2658  array temp(std::move(other));
2659  other = std::move(*this);
2660  *this = std::move(temp);
2661  }
2662  }
2663 
2665  array_ref<T, Shape> ref() { return array_ref<T, Shape>(base_, shape_); }
2666  const_array_ref<T, Shape> cref() const { return const_array_ref<T, Shape>(base_, shape_); }
2667  const_array_ref<T, Shape> ref() const { return cref(); }
2668  operator array_ref<T, Shape>() { return ref(); }
2669  operator const_array_ref<T, Shape>() const { return cref(); }
2670 
2672  template <std::size_t R = rank(), typename = std::enable_if_t<R == 0>>
2673  operator reference() {
2674  return *base_;
2675  }
2676  template <std::size_t R = rank(), typename = std::enable_if_t<R == 0>>
2677  operator const_reference() const {
2678  return *base_;
2679  }
2680 
2681  // We can't shadow T or Alloc here.
2682  template <typename NewShape, typename T2, typename OldShape, typename Alloc2>
2684  array<T2, OldShape, Alloc2>&& from, const NewShape& new_shape, index_t offset);
2685  template <typename NewShape, typename T2, typename OldShape, typename Alloc2>
2686  friend array<T2, NewShape, Alloc2> move_reinterpret_shape(
2687  array<T2, OldShape, Alloc2>&& from, index_t offset);
2688 };
2689 
2691 template <class T, size_t Rank, class Alloc = std::allocator<T>>
2693 
2695 template <class T, size_t Rank, class Alloc = std::allocator<T>>
2697 
2699 template <class T, class Shape, class Alloc = std::allocator<T>,
2700  class = internal::enable_if_allocator<Alloc>>
2701 auto make_array(const Shape& shape, const Alloc& alloc = Alloc()) {
2702  return array<T, Shape, Alloc>(shape, alloc);
2703 }
2704 template <class T, class Shape, class Alloc = std::allocator<T>,
2705  class = internal::enable_if_allocator<Alloc>>
2706 auto make_array(const Shape& shape, const T& value, const Alloc& alloc = Alloc()) {
2707  return array<T, Shape, Alloc>(shape, value, alloc);
2708 }
2709 
2711 template <class T, class Shape, class Alloc>
2713  a.swap(b);
2714 }
2715 
2719 template <class TSrc, class TDst, class ShapeSrc, class ShapeDst,
2720  class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
2722  if (dst.shape().empty()) { return; }
2723 
2724  assert(src.shape().is_in_range(dst.shape().min()) && src.shape().is_in_range(dst.shape().max()));
2725 
2727  src.shape(), src.base(), dst.shape(), dst.base(), internal::copy_assign<TSrc, TDst>);
2728 }
2729 template <class TSrc, class TDst, class ShapeSrc, class ShapeDst, class AllocDst,
2730  class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
2732  copy(src, dst.ref());
2733 }
2734 template <class TSrc, class TDst, class ShapeSrc, class ShapeDst, class AllocSrc,
2735  class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
2736 void copy(const array<TSrc, ShapeSrc, AllocSrc>& src, const array_ref<TDst, ShapeDst>& dst) {
2737  copy(src.cref(), dst);
2738 }
2739 template <class TSrc, class TDst, class ShapeSrc, class ShapeDst, class AllocSrc, class AllocDst,
2740  class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
2742  copy(src.cref(), dst.ref());
2743 }
2744 
2746 template <class T, class ShapeSrc,
2747  class Alloc = std::allocator<typename std::remove_const<T>::type>>
2748 auto make_copy(const array_ref<T, ShapeSrc>& src, const Alloc& alloc = Alloc()) {
2749  array<typename std::allocator_traits<Alloc>::value_type, ShapeSrc, Alloc> dst(src.shape(), alloc);
2750  copy(src, dst);
2751  return dst;
2752 }
2753 template <class T, class ShapeSrc, class AllocSrc, class AllocDst = AllocSrc,
2754  class = internal::enable_if_allocator<AllocDst>>
2755 auto make_copy(const array<T, ShapeSrc, AllocSrc>& src, const AllocDst& alloc = AllocDst()) {
2756  return make_copy(src.cref(), alloc);
2757 }
2758 
2760 template <class T, class ShapeSrc, class ShapeDst,
2761  class Alloc = std::allocator<typename std::remove_const<T>::type>,
2762  class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
2764  const array_ref<T, ShapeSrc>& src, const ShapeDst& shape, const Alloc& alloc = Alloc()) {
2765  array<typename std::allocator_traits<Alloc>::value_type, ShapeDst, Alloc> dst(shape, alloc);
2766  copy(src, dst);
2767  return dst;
2768 }
2769 template <class T, class ShapeSrc, class ShapeDst, class AllocSrc, class AllocDst = AllocSrc,
2770  class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
2771 auto make_copy(const array<T, ShapeSrc, AllocSrc>& src, const ShapeDst& shape,
2772  const AllocDst& alloc = AllocDst()) {
2773  return make_copy(src.cref(), shape, alloc);
2774 }
2775 
2778 template <class T, class Shape, class Alloc = std::allocator<typename std::remove_const<T>::type>>
2779 auto make_compact_copy(const array_ref<T, Shape>& src, const Alloc& alloc = Alloc()) {
2780  return make_copy(src, make_compact(src.shape()), alloc);
2781 }
2782 template <class T, class Shape, class AllocSrc, class AllocDst = AllocSrc>
2783 auto make_compact_copy(const array<T, Shape, AllocSrc>& src, const AllocDst& alloc = AllocDst()) {
2784  return make_compact_copy(src.cref(), alloc);
2785 }
2786 
2790 template <class TSrc, class TDst, class ShapeSrc, class ShapeDst,
2791  class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
2793  if (dst.shape().empty()) { return; }
2794 
2795  assert(src.shape().is_in_range(dst.shape().min()) && src.shape().is_in_range(dst.shape().max()));
2796 
2798  src.shape(), src.base(), dst.shape(), dst.base(), internal::move_assign<TSrc, TDst>);
2799 }
2800 template <class TSrc, class TDst, class ShapeSrc, class ShapeDst, class AllocDst,
2801  class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
2803  move(src, dst.ref());
2804 }
2805 template <class TSrc, class TDst, class ShapeSrc, class ShapeDst, class AllocSrc,
2806  class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
2808  move(src.ref(), dst);
2809 }
2810 template <class TSrc, class TDst, class ShapeSrc, class ShapeDst, class AllocSrc, class AllocDst,
2811  class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
2813  move(src.ref(), dst.ref());
2814 }
2815 template <class T, class Shape, class Alloc>
2817  dst = std::move(src);
2818 }
2819 
2822 template <class T, class ShapeSrc, class ShapeDst, class Alloc = std::allocator<T>,
2823  class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
2825  const array_ref<T, ShapeSrc>& src, const ShapeDst& shape, const Alloc& alloc = Alloc()) {
2826  array<typename std::allocator_traits<Alloc>::value_type, ShapeDst, Alloc> dst(shape, alloc);
2827  move(src, dst);
2828  return dst;
2829 }
2830 template <class T, class ShapeSrc, class ShapeDst, class AllocSrc, class AllocDst = AllocSrc,
2831  class = internal::enable_if_shapes_copy_compatible<ShapeDst, ShapeSrc>>
2832 auto make_move(
2833  array<T, ShapeSrc, AllocSrc>& src, const ShapeDst& shape, const AllocDst& alloc = AllocDst()) {
2834  return make_move(src.ref(), shape, alloc);
2835 }
2836 template <class T, class Shape, class Alloc>
2837 auto make_move(array<T, Shape, Alloc>&& src, const Shape& shape, const Alloc& alloc = Alloc()) {
2838  if (src.shape() == shape && alloc == src.get_allocator()) {
2839  return src;
2840  } else {
2841  return make_move(src.ref(), shape, alloc);
2842  }
2843 }
2844 
2847 template <class T, class Shape, class Alloc = std::allocator<T>>
2848 auto make_compact_move(const array_ref<T, Shape>& src, const Alloc& alloc = Alloc()) {
2849  return make_move(src, make_compact(src.shape()), alloc);
2850 }
2851 template <class T, class Shape, class AllocSrc, class AllocDst = AllocSrc>
2852 auto make_compact_move(array<T, Shape, AllocSrc>& src, const AllocDst& alloc = AllocDst()) {
2853  return make_compact_move(src.ref(), alloc);
2854 }
2855 template <class T, class Shape, class Alloc>
2856 auto make_compact_move(array<T, Shape, Alloc>&& src, const Alloc& alloc = Alloc()) {
2857  return make_move(src, make_compact(src.shape()), alloc);
2858 }
2859 
2861 template <class T, class Shape>
2862 NDARRAY_HOST_DEVICE void fill(const array_ref<T, Shape>& dst, const T& value) {
2863  dst.for_each_value([value](T& i) { i = value; });
2864 }
2865 template <class T, class Shape, class Alloc>
2866 void fill(array<T, Shape, Alloc>& dst, const T& value) {
2867  fill(dst.ref(), value);
2868 }
2869 
2873 template <class T, class Shape, class Generator, class = internal::enable_if_callable<Generator>>
2874 NDARRAY_HOST_DEVICE void generate(const array_ref<T, Shape>& dst, Generator&& g) {
2875  dst.for_each_value([g = std::move(g)](T& i) { i = g(); });
2876 }
2877 template <class T, class Shape, class Alloc, class Generator,
2878  class = internal::enable_if_callable<Generator>>
2879 void generate(array<T, Shape, Alloc>& dst, Generator&& g) {
2880  generate(dst.ref(), g);
2881 }
2882 
2886 template <typename T, typename Shape, class Fn>
2887 NDARRAY_HOST_DEVICE void transform_index(const array_ref<T, Shape>& dst, Fn&& fn) {
2888  using index_type = typename Shape::index_type;
2890  dst.shape(), [&, fn = std::move(fn)](const index_type& idx) { dst[idx] = fn(idx); });
2891 }
2892 template <typename T, typename Shape, class Fn>
2893 void transform_index(array<T, Shape>& dst, Fn&& fn) {
2894  transform_index(dst.ref(), fn);
2895 }
2896 
2900 template <typename T, typename Shape, class Fn>
2901 NDARRAY_HOST_DEVICE void transform_indices(const array_ref<T, Shape>& dst, Fn&& fn) {
2902  using index_type = typename Shape::index_type;
2904  dst, [fn = std::move(fn)](const index_type& idx) { return internal::apply(fn, idx); });
2905 }
2906 template <typename T, typename Shape, class Fn>
2907 void transform_indices(array<T, Shape>& dst, Fn&& fn) {
2908  transform_indices(dst.ref(), fn);
2909 }
2910 
2912 template <class TA, class ShapeA, class TB, class ShapeB>
2913 NDARRAY_HOST_DEVICE bool equal(const array_ref<TA, ShapeA>& a, const array_ref<TB, ShapeB>& b) {
2914  if (a.shape().min() != b.shape().min() || a.shape().extent() != b.shape().extent()) {
2915  return false;
2916  }
2917 
2918  bool result = true;
2920  a.shape(), a.base(), b.shape(), b.base(), [&](const TA& a, const TB& b) {
2921  if (a != b) { result = false; }
2922  });
2923  return result;
2924 }
2925 template <class TA, class ShapeA, class TB, class ShapeB, class AllocB>
2926 bool equal(const array_ref<TA, ShapeA>& a, const array<TB, ShapeB, AllocB>& b) {
2927  return equal(a, b.ref());
2928 }
2929 template <class TA, class ShapeA, class AllocA, class TB, class ShapeB>
2930 bool equal(const array<TA, ShapeA, AllocA>& a, const array_ref<TB, ShapeB>& b) {
2931  return equal(a.ref(), b);
2932 }
2933 template <class TA, class ShapeA, class AllocA, class TB, class ShapeB, class AllocB>
2935  return equal(a.ref(), b.ref());
2936 }
2937 
2940 template <class NewShape, class T, class OldShape>
2942  return array_ref<T, NewShape>(a.base(), convert_shape<NewShape>(a.shape()));
2943 }
2944 template <class NewShape, class T, class OldShape, class Allocator>
2946  return convert_shape<NewShape>(a.ref());
2947 }
2948 template <class NewShape, class T, class OldShape, class Allocator>
2950  return convert_shape<NewShape>(a.cref());
2951 }
2952 
2955 template <class U, class T, class Shape, class = std::enable_if_t<sizeof(T) == sizeof(U)>>
2956 NDARRAY_HOST_DEVICE array_ref<U, Shape> reinterpret(const array_ref<T, Shape>& a) {
2957  return array_ref<U, Shape>(reinterpret_cast<U*>(a.base()), a.shape());
2958 }
2959 template <class U, class T, class Shape, class Alloc,
2960  class = std::enable_if_t<sizeof(T) == sizeof(U)>>
2962  return reinterpret<U>(a.ref());
2963 }
2964 template <class U, class T, class Shape, class Alloc,
2965  class = std::enable_if_t<sizeof(T) == sizeof(U)>>
2967  return reinterpret<const U>(a.cref());
2968 }
2969 
2972 template <class U, class T, class Shape>
2974  return array_ref<U, Shape>(const_cast<U*>(a.base()), a.shape());
2975 }
2976 
2979 template <class NewShape, class T, class OldShape>
2981  const array_ref<T, OldShape>& a, const NewShape& new_shape, index_t offset = 0) {
2982  array_ref<T, NewShape> result(a.base() + offset, new_shape);
2983  assert(result.shape().is_subset_of(a.shape(), -offset));
2984  return result;
2985 }
2986 template <class NewShape, class T, class OldShape, class Allocator>
2988  array<T, OldShape, Allocator>& a, const NewShape& new_shape, index_t offset = 0) {
2989  return reinterpret_shape(a.ref(), new_shape, offset);
2990 }
2991 template <class NewShape, class T, class OldShape, class Allocator>
2993  const array<T, OldShape, Allocator>& a, const NewShape& new_shape, index_t offset = 0) {
2994  return reinterpret_shape(a.cref(), new_shape, offset);
2995 }
2996 
3001 template <typename NewShape, typename T, typename OldShape, typename Alloc>
3003  array<T, OldShape, Alloc>&& from, const NewShape& new_shape, index_t offset = 0) {
3004  // TODO: Use enable_if to implement this check. It is difficult to do due to
3005  // the friend declaration.
3006  static_assert(
3007  std::is_trivial<T>::value, "move_reinterpret_shape is broken for non-trivial types.");
3008  assert(new_shape.is_subset_of(from.shape(), offset));
3010  assert(result.alloc_ == from.get_allocator());
3011 
3012  using std::swap;
3013  swap(result.buffer_, from.buffer_);
3014  swap(result.buffer_size_, from.buffer_size_);
3015  swap(result.base_, from.base_);
3016  result.shape_ = new_shape;
3017  from.shape_ = OldShape();
3018  result.base_ += offset;
3019 
3020  return result;
3021 }
3022 template <typename NewShape, typename T, typename OldShape, typename Alloc>
3024  array<T, OldShape, Alloc>&& from, index_t offset = 0) {
3025  NewShape new_shape = convert_shape<NewShape>(from.shape());
3026  return move_reinterpret_shape(std::move(from), new_shape, offset);
3027 }
3028 
3032 template <size_t... DimIndices, class T, class OldShape,
3033  class = internal::enable_if_permutation<OldShape::rank(), DimIndices...>>
3034 NDARRAY_HOST_DEVICE auto transpose(const array_ref<T, OldShape>& a) {
3035  return reinterpret_shape(a, transpose<DimIndices...>(a.shape()));
3036 }
3037 template <size_t... DimIndices, class T, class OldShape, class Allocator,
3038  class = internal::enable_if_permutation<OldShape::rank(), DimIndices...>>
3040  return reinterpret_shape(a, transpose<DimIndices...>(a.shape()));
3041 }
3042 template <size_t... DimIndices, class T, class OldShape, class Allocator,
3043  class = internal::enable_if_permutation<OldShape::rank(), DimIndices...>>
3045  return reinterpret_shape(a, transpose<DimIndices...>(a.shape()));
3046 }
3047 template <size_t... DimIndices, class T, class OldShape>
3048 NDARRAY_HOST_DEVICE auto reorder(const array_ref<T, OldShape>& a) {
3049  return reinterpret_shape(a, reorder<DimIndices...>(a.shape()));
3050 }
3051 template <size_t... DimIndices, class T, class OldShape, class Allocator>
3053  return reinterpret_shape(a, reorder<DimIndices...>(a.shape()));
3054 }
3055 template <size_t... DimIndices, class T, class OldShape, class Allocator>
3056 auto reorder(const array<T, OldShape, Allocator>& a) {
3057  return reinterpret_shape(a, reorder<DimIndices...>(a.shape()));
3058 }
3059 
3064 template <class T, size_t N, size_t Alignment = alignof(T), class BaseAlloc = std::allocator<T>>
3066  alignas(Alignment) char buffer[N * sizeof(T)];
3067  bool allocated;
3068  BaseAlloc alloc;
3069 
3070 public:
3071  using value_type = T;
3072 
3073  using propagate_on_container_copy_assignment = std::false_type;
3074  using propagate_on_container_move_assignment = std::false_type;
3075  using propagate_on_container_swap = std::false_type;
3076 
3077  static auto_allocator select_on_container_copy_construction(const auto_allocator&) {
3078  return auto_allocator();
3079  }
3080 
3081  auto_allocator() : allocated(false) {}
3082  template <class U, size_t U_N, size_t U_A, class U_BaseAlloc>
3083  constexpr auto_allocator(const auto_allocator<U, U_N, U_A, U_BaseAlloc>&) noexcept
3084  : allocated(false) {}
3085  // These constructors/assignment operators are workarounds for a C++
3086  // STL implementation not respecting the propagate typedefs or the
3087  // 'select_on_...' function. (https://github.com/dsharlet/array/issues/7)
3088  auto_allocator(const auto_allocator& copy) noexcept : allocated(false), alloc(copy.alloc) {}
3089  auto_allocator(auto_allocator&& move) noexcept : allocated(false), alloc(std::move(move.alloc)) {}
3090  auto_allocator& operator=(const auto_allocator& copy) {
3091  alloc = copy.alloc;
3092  return *this;
3093  }
3094  auto_allocator& operator=(auto_allocator&& move) {
3095  alloc = std::move(move.alloc);
3096  return *this;
3097  }
3098 
3099  value_type* allocate(size_t n) {
3100  if (!allocated && n <= N) {
3101  allocated = true;
3102  return reinterpret_cast<value_type*>(&buffer[0]);
3103  } else {
3104  return std::allocator_traits<BaseAlloc>::allocate(alloc, n);
3105  }
3106  }
3107  void deallocate(value_type* ptr, size_t n) noexcept {
3108  if (ptr == reinterpret_cast<value_type*>(&buffer[0])) {
3109  assert(allocated);
3110  allocated = false;
3111  } else {
3112  std::allocator_traits<BaseAlloc>::deallocate(alloc, ptr, n);
3113  }
3114  }
3115 
3116  template <class U, size_t U_N, size_t U_A>
3117  friend bool operator==(const auto_allocator& a, const auto_allocator<U, U_N, U_A>& b) {
3118  if (a.allocated || b.allocated) {
3119  return &a.buffer[0] == &b.buffer[0];
3120  } else {
3121  return a.alloc == b.alloc;
3122  }
3123  }
3124 
3125  template <class U, size_t U_N, size_t U_A>
3126  friend bool operator!=(const auto_allocator& a, const auto_allocator<U, U_N, U_A>& b) {
3127  return !(a == b);
3128  }
3129 };
3130 
3135 template <class BaseAlloc>
3136 class uninitialized_allocator : public BaseAlloc {
3137 public:
3138  using value_type = typename std::allocator_traits<BaseAlloc>::value_type;
3139 
3140  using propagate_on_container_copy_assignment =
3141  typename std::allocator_traits<BaseAlloc>::propagate_on_container_copy_assignment;
3142  using propagate_on_container_move_assignment =
3143  typename std::allocator_traits<BaseAlloc>::propagate_on_container_move_assignment;
3144  using propagate_on_container_swap =
3145  typename std::allocator_traits<BaseAlloc>::propagate_on_container_swap;
3146  static uninitialized_allocator select_on_container_copy_construction(
3147  const uninitialized_allocator& alloc) {
3148  return std::allocator_traits<BaseAlloc>::select_on_container_copy_construction(alloc);
3149  }
3150 
3151  value_type* allocate(size_t n) { return std::allocator_traits<BaseAlloc>::allocate(*this, n); }
3152  void deallocate(value_type* p, size_t n) noexcept {
3153  return std::allocator_traits<BaseAlloc>::deallocate(*this, p, n);
3154  }
3155 
3156  // TODO: Consider adding an enable_if to this to disable it for
3157  // non-trivial value_types.
3158  template <class... Args>
3159  NDARRAY_INLINE void construct(value_type* ptr, Args&&... args) {
3160  // Skip default construction.
3161  if (sizeof...(Args) > 0) {
3162  std::allocator_traits<BaseAlloc>::construct(*this, ptr, std::forward<Args>(args)...);
3163  }
3164  }
3165 
3166  template <class OtherBaseAlloc>
3167  friend bool operator==(
3169  return static_cast<const BaseAlloc&>(a) == static_cast<const OtherBaseAlloc&>(b);
3170  }
3171  template <class OtherBaseAlloc>
3172  friend bool operator!=(
3174  return static_cast<const BaseAlloc&>(a) != static_cast<const OtherBaseAlloc&>(b);
3175  }
3176 };
3177 
3180 template <class T, class = std::enable_if_t<std::is_trivial<T>::value>>
3182 
3185 template <class T, size_t N, size_t Alignment = sizeof(T),
3186  class = std::enable_if_t<std::is_trivial<T>::value>>
3188 
3189 } // namespace nda
3190 
3191 #endif // NDARRAY_ARRAY_H
NDARRAY_HOST_DEVICE Shape & shape()
Definition: array.h:2095
+
decltype(make_shape_from_tuple(internal::tuple_of_n< dim<>, Rank >())) shape_of_rank
Definition: array.h:1601
+
index_iterator(index_t i)
Definition: array.h:188
+
NDARRAY_HOST_DEVICE bool is_one_to_one() const
Definition: array.h:1249
+
void swap(array< T, Shape, Alloc > &a, array< T, Shape, Alloc > &b)
Definition: array.h:2712
+
NDARRAY_INLINE NDARRAY_HOST_DEVICE bool is_in_range(index_t at) const
Definition: array.h:305
+
NDARRAY_HOST_DEVICE auto operator[](const std::tuple< Args... > &args) const
Definition: array.h:1184
+
NDARRAY_HOST_DEVICE ShapeDst convert_shape(const ShapeSrc &src)
Definition: array.h:1650
+
array(const Shape &shape, const Alloc &alloc)
Definition: array.h:2333
+
const auto & i() const
Definition: array.h:2618
+
Definition: array.h:3136
+
constexpr index_t dynamic
Definition: array.h:99
+
NDARRAY_HOST_DEVICE reference operator[](const index_type &indices) const
Definition: array.h:2056
+
void copy(const array_ref< TSrc, ShapeSrc > &src, const array_ref< TDst, ShapeDst > &dst)
Definition: array.h:2721
+
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t flat_offset(index_t at) const
Definition: array.h:480
+
NDARRAY_HOST_DEVICE internal::split_result< InnerExtent > split(const interval< Min, Extent > &v)
Definition: array.h:614
+
index_of_rank< rank()> index_type
Definition: array.h:1076
+
Definition: array.h:1036
+
pointer data()
Definition: array.h:2558
+
NDARRAY_HOST_DEVICE array_ref< T, Shape > make_array_ref(T *base, const Shape &shape)
Definition: array.h:1962
+
static NDARRAY_HOST_DEVICE void for_each_value(const ShapeSrc &shape_src, TSrc src, const ShapeDst &shape_dst, TDst dst, Fn &&fn)
Definition: array.h:1893
+
NDARRAY_HOST_DEVICE void generate(const array_ref< T, Shape > &dst, Generator &&g)
Definition: array.h:2874
+
NDARRAY_HOST_DEVICE pointer data() const
Definition: array.h:2090
+
NDARRAY_HOST_DEVICE index_t flat_min() const
Definition: array.h:1224
+
auto make_copy(const array_ref< T, ShapeSrc > &src, const Alloc &alloc=Alloc())
Definition: array.h:2748
+
NDARRAY_HOST_DEVICE const const_array_ref< T, Shape > cref() const
Definition: array.h:2167
+
NDARRAY_HOST_DEVICE bool operator!=(const array_ref &other) const
Definition: array.h:2149
+
auto make_array(const Shape &shape, const Alloc &alloc=Alloc())
Definition: array.h:2701
+
NDARRAY_HOST_DEVICE void for_each_value(Fn &&fn) const
Definition: array.h:2081
+
static NDARRAY_HOST_DEVICE void for_each_value(const Shape &shape, Ptr base, Fn &&fn)
Definition: array.h:1874
+
constexpr index_t unresolved
Definition: array.h:103
+
NDARRAY_HOST_DEVICE bool is_compatible(const ShapeSrc &src)
Definition: array.h:1636
+
NDARRAY_HOST_DEVICE void resolve()
Definition: array.h:1154
+
void clear()
Definition: array.h:2577
+
const interval< 0,-1 > all
Definition: array.h:363
+
void set_shape(const Shape &new_shape, index_t offset=0)
Definition: array.h:2608
+
Definition: array.h:1953
+
void swap(array &other)
Definition: array.h:2649
+
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t stride() const
Definition: array.h:470
+
Shape shape_type
Definition: array.h:2216
+
void assign(const array &other)
Definition: array.h:2453
+
Definition: array.h:1955
+
decltype(make_shape_from_tuple(internal::make_compact_dims< 1 >(dim< 0, Extents >()...))) fixed_dense_shape
Definition: array.h:1630
+
NDARRAY_HOST_DEVICE pointer base() const
Definition: array.h:2086
+
NDARRAY_INLINE NDARRAY_HOST_DEVICE interval range(index_t begin, index_t end)
Definition: array.h:344
+
NDARRAY_HOST_DEVICE interval(const interval< CopyMin, CopyExtent > &other)
Definition: array.h:281
+
NDARRAY_HOST_DEVICE auto & dim()
Definition: array.h:1196
+
array()
Definition: array.h:2321
+
void for_each_value(Fn &&fn)
Definition: array.h:2544
+
NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_index(const Shape &s, Fn &&fn)
Definition: array.h:1924
+
NDARRAY_HOST_DEVICE auto operator[](const std::tuple< Args... > &args) const
Definition: array.h:2069
+
NDARRAY_HOST_DEVICE void transform_indices(const array_ref< T, Shape > &dst, Fn &&fn)
Definition: array.h:2901
+
NDARRAY_HOST_DEVICE index_t rows() const
Definition: array.h:2141
+
NDARRAY_HOST_DEVICE auto & x()
Definition: array.h:1274
+
array(const array &other, const Alloc &alloc)
Definition: array.h:2354
+
index_t rows() const
Definition: array.h:2638
+
static constexpr bool is_scalar()
Definition: array.h:1073
+
static constexpr size_t rank()
Definition: array.h:2002
+
static constexpr bool is_scalar()
Definition: array.h:2226
+
Definition: absl.h:10
+
NDARRAY_HOST_DEVICE auto & i()
Definition: array.h:1265
+
NDARRAY_HOST_DEVICE auto reorder(const shape< Dims... > &shape)
Definition: array.h:1344
+
NDARRAY_HOST_DEVICE bool operator==(const shape< OtherDims... > &other) const
Definition: array.h:1299
+
Definition: array.h:1883
+
NDARRAY_HOST_DEVICE size_type size() const
Definition: array.h:1232
+
Definition: array.h:1859
+
NDARRAY_HOST_DEVICE dim(const dim< CopyMin, CopyExtent, CopyStride > &other)
Definition: array.h:442
+
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t clamp(index_t x, index_t min, index_t max)
Definition: array.h:376
+
void move(const array_ref< TSrc, ShapeSrc > &src, const array_ref< TDst, ShapeDst > &dst)
Definition: array.h:2792
+
std::tuple< Dims... > dims_type
Definition: array.h:1067
+
NDARRAY_HOST_DEVICE bool empty() const
Definition: array.h:1238
+
array_ref< U, Shape > reinterpret_const(const const_array_ref< T, Shape > &a)
Definition: array.h:2973
+
reference operator[](const index_type &indices)
Definition: array.h:2510
+
NDARRAY_HOST_DEVICE index_t width() const
Definition: array.h:2135
+
NDARRAY_HOST_DEVICE auto make_shape(Dims...dims)
Definition: array.h:1040
+
Alloc allocator_type
Definition: array.h:2205
+
T value_type
Definition: array.h:2209
+
T value_type
Definition: array.h:1991
+
NDARRAY_HOST_DEVICE array_ref(const array_ref< T, OtherShape > &other)
Definition: array.h:2046
+
NDARRAY_HOST_DEVICE bool is_subset_of(const OtherShape &other, index_t offset) const
Definition: array.h:1258
+
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t max() const
Definition: array.h:301
+
array< T, NewShape, Alloc > move_reinterpret_shape(array< T, OldShape, Alloc > &&from, const NewShape &new_shape, index_t offset=0)
Definition: array.h:3002
+
array(const Shape &shape, const T &value, const Alloc &alloc)
Definition: array.h:2326
+
array(array &&other)
Definition: array.h:2361
+
NDARRAY_HOST_DEVICE index_iterator begin() const
Definition: array.h:322
+
NDARRAY_HOST_DEVICE auto & i()
Definition: array.h:2113
+
NDARRAY_HOST_DEVICE interval(index_t min, index_t extent)
Definition: array.h:265
+
static constexpr bool is_scalar()
Definition: array.h:2005
+
internal::tuple_of_n< index_t, Rank > index_of_rank
Definition: array.h:1054
+
NDARRAY_HOST_DEVICE array_ref< T, NewShape > reinterpret_shape(const array_ref< T, OldShape > &a, const NewShape &new_shape, index_t offset=0)
Definition: array.h:2980
+
auto make_move(const array_ref< T, ShapeSrc > &src, const ShapeDst &shape, const Alloc &alloc=Alloc())
Definition: array.h:2824
+
NDARRAY_HOST_DEVICE bool operator==(const dim< OtherMin, OtherExtent, OtherStride > &other) const
Definition: array.h:487
+
NDARRAY_HOST_DEVICE index_iterator begin(const interval< Min, Extent > &d)
Definition: array.h:367
+
Shape shape_type
Definition: array.h:1996
+
NDARRAY_HOST_DEVICE auto & x()
Definition: array.h:2122
+
NDARRAY_HOST_DEVICE bool is_resolved() const
Definition: array.h:1157
+
NDARRAY_HOST_DEVICE bool is_compact() const
Definition: array.h:1243
+
auto make_compact_move(const array_ref< T, Shape > &src, const Alloc &alloc=Alloc())
Definition: array.h:2848
+
void assign(Shape shape, const T &value)
Definition: array.h:2494
+
NDARRAY_HOST_DEVICE const nda::dim dim(size_t d) const
Definition: array.h:1207
+
Definition: array.h:183
+
const auto & x() const
Definition: array.h:2624
+
const Alloc & get_allocator() const
Definition: array.h:2507
+
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t operator*() const
Definition: array.h:191
+
NDARRAY_HOST_DEVICE auto transpose(const shape< Dims... > &shape)
Definition: array.h:1332
+
NDARRAY_HOST_DEVICE array_ref< U, Shape > reinterpret(const array_ref< T, Shape > &a)
Definition: array.h:2956
+
Definition: array.h:3065
+
std::ptrdiff_t index_t
Definition: array.h:87
+
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t min() const
Definition: array.h:293
+
array & operator=(array &&other)
Definition: array.h:2427
+
auto operator[](const std::tuple< Args... > &args)
Definition: array.h:2525
+
NDARRAY_HOST_DEVICE bool equal(const array_ref< TA, ShapeA > &a, const array_ref< TB, ShapeB > &b)
Definition: array.h:2913
+
Definition: array.h:248
+
NDARRAY_INLINE NDARRAY_HOST_DEVICE bool is_in_range(const interval< OtherMin, OtherExtent > &at) const
Definition: array.h:311
+
array & operator=(const array &other)
Definition: array.h:2403
+
Definition: array.h:231
+
NDARRAY_HOST_DEVICE bool operator==(const interval< OtherMin, OtherExtent > &other) const
Definition: array.h:329
+
NDARRAY_HOST_DEVICE dims_type & dims()
Definition: array.h:1213
+
NDARRAY_HOST_DEVICE void set_shape(const Shape &new_shape, index_t offset=0)
Definition: array.h:2180
+
bool operator!=(const array &other) const
Definition: array.h:2644
+
NDARRAY_HOST_DEVICE bool is_in_range(const std::tuple< Args... > &args) const
Definition: array.h:1163
+
index_t width() const
Definition: array.h:2632
+
array(array &&other, const Alloc &alloc)
Definition: array.h:2381
+
NDARRAY_HOST_DEVICE index_t operator[](const index_type &indices) const
Definition: array.h:1172
+
NDARRAY_HOST_DEVICE auto make_compact(const Shape &s)
Definition: array.h:1620
+
NDARRAY_HOST_DEVICE index_iterator end() const
Definition: array.h:324
+
static NDARRAY_HOST_DEVICE void for_each_index(const Shape &shape, Fn &&fn)
Definition: array.h:1866
+
NDARRAY_HOST_DEVICE index_t rows() const
Definition: array.h:1293
+
array(const array &other)
Definition: array.h:2346
+
NDARRAY_HOST_DEVICE void fill(const array_ref< T, Shape > &dst, const T &value)
Definition: array.h:2862
+
static constexpr size_t rank()
Definition: array.h:1070
+
NDARRAY_HOST_DEVICE index_t width() const
Definition: array.h:1287
+
NDARRAY_HOST_DEVICE bool is_explicitly_compatible(const ShapeSrc &src)
Definition: array.h:1661
+
static constexpr size_t rank()
Definition: array.h:2223
+
const Shape & shape() const
Definition: array.h:2562
+
void reshape(Shape new_shape)
Definition: array.h:2586
+
NDARRAY_HOST_DEVICE dim(index_t min, index_t extent, index_t stride=DefaultStride)
Definition: array.h:422
+
NDARRAY_HOST_DEVICE array_ref(pointer base=nullptr, const Shape &shape=Shape())
Definition: array.h:2030
+
array_ref< T, Shape > ref()
Definition: array.h:2665
+
pointer base()
Definition: array.h:2553
+
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t extent() const
Definition: array.h:296
+
decltype(internal::make_default_dense_shape< Rank >()) dense_shape
Definition: array.h:1606
+
auto make_compact_copy(const array_ref< T, Shape > &src, const Alloc &alloc=Alloc())
Definition: array.h:2779
+
NDARRAY_HOST_DEVICE void transform_index(const array_ref< T, Shape > &dst, Fn &&fn)
Definition: array.h:2887
+
NDARRAY_HOST_DEVICE shape(const std::tuple< OtherDims... > &other)
Definition: array.h:1128
+
+ + + + diff --git a/arrowdown.png b/arrowdown.png new file mode 100644 index 0000000000000000000000000000000000000000..0b63f6d38c4b9ec907b820192ebe9724ed6eca22 GIT binary patch literal 246 zcmVkw!R34#Lv2LOS^S2tZA31X++9RY}n zChwn@Z)Wz*WWHH{)HDtJnq&A2hk$b-y(>?@z0iHr41EKCGp#T5?07*qoM6N<$f(V3Pvj6}9 literal 0 HcmV?d00001 diff --git a/arrowright.png b/arrowright.png new file mode 100644 index 0000000000000000000000000000000000000000..c6ee22f937a07d1dbfc27c669d11f8ed13e2f152 GIT binary patch literal 229 zcmV^P)R?RzRoKvklcaQ%HF6%rK2&ZgO(-ihJ_C zzrKgp4jgO( fd_(yg|3PpEQb#9`a?Pz_00000NkvXXu0mjftR`5K literal 0 HcmV?d00001 diff --git a/bc_s.png b/bc_s.png new file mode 100644 index 0000000000000000000000000000000000000000..224b29aa9847d5a4b3902efd602b7ddf7d33e6c2 GIT binary patch literal 676 zcmV;V0$crwP)y__>=_9%My z{n931IS})GlGUF8K#6VIbs%684A^L3@%PlP2>_sk`UWPq@f;rU*V%rPy_ekbhXT&s z(GN{DxFv}*vZp`F>S!r||M`I*nOwwKX+BC~3P5N3-)Y{65c;ywYiAh-1*hZcToLHK ztpl1xomJ+Yb}K(cfbJr2=GNOnT!UFA7Vy~fBz8?J>XHsbZoDad^8PxfSa0GDgENZS zuLCEqzb*xWX2CG*b&5IiO#NzrW*;`VC9455M`o1NBh+(k8~`XCEEoC1Ybwf;vr4K3 zg|EB<07?SOqHp9DhLpS&bzgo70I+ghB_#)K7H%AMU3v}xuyQq9&Bm~++VYhF09a+U zl7>n7Jjm$K#b*FONz~fj;I->Bf;ule1prFN9FovcDGBkpg>)O*-}eLnC{6oZHZ$o% zXKW$;0_{8hxHQ>l;_*HATI(`7t#^{$(zLe}h*mqwOc*nRY9=?Sx4OOeVIfI|0V(V2 zBrW#G7Ss9wvzr@>H*`r>zE z+e8bOBgqIgldUJlG(YUDviMB`9+DH8n-s9SXRLyJHO1!=wY^79WYZMTa(wiZ!zP66 zA~!21vmF3H2{ngD;+`6j#~6j;$*f*G_2ZD1E;9(yaw7d-QnSCpK(cR1zU3qU0000< KMNUMnLSTYoA~SLT literal 0 HcmV?d00001 diff --git a/bdwn.png b/bdwn.png new file mode 100644 index 0000000000000000000000000000000000000000..940a0b950443a0bb1b216ac03c45b8a16c955452 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)H!3HEvS)PKZC{Gv1kP61Pb5HX&C2wk~_T + + + + + +array: Class Index + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class Index
+
+
+
A | C | D | I | S | U
+ + + + + + + + + +
  a  
+
  c  
+
  i  
+
shape_traits (nda)   
shape_traits< chunky_image_shape< Channels > > (nda)   
array (nda)   copy_shape_traits (nda)   index_iterator (nda)   shape_traits< chunky_image_shape< Channels, XStride > > (nda)   
array_ref (nda)   
  d  
+
interval (nda)   shape_traits< matrix_shape< Rows, Cols > > (nda)   
auto_allocator (nda)   
  s  
+
  u  
+
dim (nda)   
shape (nda)   uninitialized_allocator (nda)   
+
A | C | D | I | S | U
+
+ + + + diff --git a/classnda_1_1array-members.html b/classnda_1_1array-members.html new file mode 100644 index 00000000..b0b03158 --- /dev/null +++ b/classnda_1_1array-members.html @@ -0,0 +1,186 @@ + + + + + + +array: Member List + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
array< T, Shape, Alloc > Member List
+
+
+ +

This is the complete list of members for array< T, Shape, Alloc >, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
alloc_traits typedef (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >
allocator_type typedefarray< T, Shape, Alloc >
array()array< T, Shape, Alloc >inline
array(const Alloc &alloc) (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inlineexplicit
array(const Shape &shape, const T &value, const Alloc &alloc)array< T, Shape, Alloc >inline
array(const Shape &shape, const T &value) (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
array(const Shape &shape, const Alloc &alloc)array< T, Shape, Alloc >inlineexplicit
array(const Shape &shape) (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inlineexplicit
array(const array &other)array< T, Shape, Alloc >inline
array(const array &other, const Alloc &alloc)array< T, Shape, Alloc >inline
array(array &&other)array< T, Shape, Alloc >inline
array(array &&other, const Alloc &alloc)array< T, Shape, Alloc >inline
assign(const array &other)array< T, Shape, Alloc >inline
assign(array &&other) (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
assign(Shape shape, const T &value)array< T, Shape, Alloc >inline
base()array< T, Shape, Alloc >inline
base() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
c() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
channels() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
clear()array< T, Shape, Alloc >inline
columns() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
const_pointer typedef (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >
const_reference typedef (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >
copy_shape_traits_type typedef (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >
cref() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
data()array< T, Shape, Alloc >inline
data() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
dim() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
dim(size_t d) const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
empty() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
for_each_value(Fn &&fn)array< T, Shape, Alloc >inline
for_each_value(Fn &&fn) const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
get_allocator() const array< T, Shape, Alloc >inline
height() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
i() const array< T, Shape, Alloc >inline
index_type typedef (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >
is_compact() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
is_scalar()array< T, Shape, Alloc >inlinestatic
j() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
k() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
move_reinterpret_shape (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >friend
move_reinterpret_shape (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >friend
operator array_ref< T, Shape >() (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
operator const_array_ref< T, Shape >() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
operator const_reference() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
operator reference()array< T, Shape, Alloc >inline
operator!=(const array &other) const array< T, Shape, Alloc >inline
operator()(Args...indices) (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
operator()(Args...indices) const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
operator()(Args...args) (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
operator()(Args...args) const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
operator=(const array &other)array< T, Shape, Alloc >inline
operator=(array &&other)array< T, Shape, Alloc >inline
operator==(const array &other) const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
operator[](const index_type &indices)array< T, Shape, Alloc >inline
operator[](const index_type &indices) const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
operator[](const std::tuple< Args... > &args)array< T, Shape, Alloc >inline
operator[](const std::tuple< Args... > &args) const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
pointer typedef (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >
rank()array< T, Shape, Alloc >inlinestatic
ref()array< T, Shape, Alloc >inline
ref() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
reference typedef (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >
reshape(Shape new_shape)array< T, Shape, Alloc >inline
rows() const array< T, Shape, Alloc >inline
set_shape(const Shape &new_shape, index_t offset=0)array< T, Shape, Alloc >inline
shape() const array< T, Shape, Alloc >inline
shape_traits_type typedef (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >
shape_type typedefarray< T, Shape, Alloc >
size() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
size_type typedef (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >
swap(array &other)array< T, Shape, Alloc >inline
value_type typedefarray< T, Shape, Alloc >
w() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
width() const array< T, Shape, Alloc >inline
x() const array< T, Shape, Alloc >inline
y() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
z() const (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
~array() (defined in array< T, Shape, Alloc >)array< T, Shape, Alloc >inline
+ + + + diff --git a/classnda_1_1array.html b/classnda_1_1array.html new file mode 100644 index 00000000..d3485a25 --- /dev/null +++ b/classnda_1_1array.html @@ -0,0 +1,1215 @@ + + + + + + +array: array< T, Shape, Alloc > Class Template Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
array< T, Shape, Alloc > Class Template Reference
+
+
+ +

#include <array.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Types

using allocator_type = Alloc
 
+using alloc_traits = std::allocator_traits< Alloc >
 
using value_type = T
 
+using reference = value_type &
 
+using const_reference = const value_type &
 
+using pointer = typename alloc_traits::pointer
 
+using const_pointer = typename alloc_traits::const_pointer
 
using shape_type = Shape
 
+using index_type = typename Shape::index_type
 
+using shape_traits_type = shape_traits< Shape >
 
+using copy_shape_traits_type = copy_shape_traits< Shape, Shape >
 
+using size_type = size_t
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 array ()
 
array (const Alloc &alloc)
 
 array (const Shape &shape, const T &value, const Alloc &alloc)
 
array (const Shape &shape, const T &value)
 
 array (const Shape &shape, const Alloc &alloc)
 
array (const Shape &shape)
 
 array (const array &other)
 
 array (const array &other, const Alloc &alloc)
 
 array (array &&other)
 
 array (array &&other, const Alloc &alloc)
 
arrayoperator= (const array &other)
 
arrayoperator= (array &&other)
 
void assign (const array &other)
 
+void assign (array &&other)
 
void assign (Shape shape, const T &value)
 
const Alloc & get_allocator () const
 
reference operator[] (const index_type &indices)
 
+const_reference operator[] (const index_type &indices) const
 
+template<class... Args, class = enable_if_all_indices<Args...>>
reference operator() (Args...indices)
 
+template<class... Args, class = enable_if_all_indices<Args...>>
const_reference operator() (Args...indices) const
 
template<class... Args, class = enable_if_any_slices<Args...>>
auto operator[] (const std::tuple< Args... > &args)
 
+template<class... Args, class = enable_if_any_slices<Args...>>
auto operator() (Args...args)
 
+template<class... Args, class = enable_if_any_slices<Args...>>
auto operator[] (const std::tuple< Args... > &args) const
 
+template<class... Args, class = enable_if_any_slices<Args...>>
auto operator() (Args...args) const
 
template<class Fn , class = internal::enable_if_callable<Fn, reference>>
void for_each_value (Fn &&fn)
 
+template<class Fn , class = internal::enable_if_callable<Fn, const_reference>>
void for_each_value (Fn &&fn) const
 
pointer base ()
 
+const_pointer base () const
 
pointer data ()
 
+const_pointer data () const
 
const Shape & shape () const
 
+template<size_t D, class = enable_if_dim<D>>
const auto & dim () const
 
+const nda::dim dim (size_t d) const
 
+size_type size () const
 
+bool empty () const
 
+bool is_compact () const
 
void clear ()
 
void reshape (Shape new_shape)
 
void set_shape (const Shape &new_shape, index_t offset=0)
 
const auto & i () const
 
+const auto & j () const
 
+const auto & k () const
 
const auto & x () const
 
+const auto & y () const
 
+const auto & z () const
 
+const auto & c () const
 
+const auto & w () const
 
index_t width () const
 
+index_t height () const
 
+index_t channels () const
 
index_t rows () const
 
+index_t columns () const
 
bool operator!= (const array &other) const
 
+bool operator== (const array &other) const
 
void swap (array &other)
 
array_ref< T, Shape > ref ()
 
+const_array_ref< T, Shape > cref () const
 
+const_array_ref< T, Shape > ref () const
 
operator array_ref< T, Shape > ()
 
operator const_array_ref< T, Shape > () const
 
template<std::size_t R = rank(), typename = std::enable_if_t<R == 0>>
 operator reference ()
 
+template<std::size_t R = rank(), typename = std::enable_if_t<R == 0>>
 operator const_reference () const
 
+ + + + + +

+Static Public Member Functions

static constexpr size_t rank ()
 
static constexpr bool is_scalar ()
 
+ + + + + + + +

+Friends

+template<typename NewShape , typename T2 , typename OldShape , typename Alloc2 >
array< T2, NewShape, Alloc2 > move_reinterpret_shape (array< T2, OldShape, Alloc2 > &&from, const NewShape &new_shape, index_t offset)
 
+template<typename NewShape , typename T2 , typename OldShape , typename Alloc2 >
array< T2, NewShape, Alloc2 > move_reinterpret_shape (array< T2, OldShape, Alloc2 > &&from, index_t offset)
 
+

Detailed Description

+

template<class T, class Shape, class Alloc = std::allocator<T>>
+class nda::array< T, Shape, Alloc >

+ +

A multi-dimensional array container that owns an allocation of memory.

+

Member Typedef Documentation

+ +
+
+ + + + +
using allocator_type = Alloc
+
+

Type of the allocator used to allocate memory in this array.

+ +
+
+ +
+
+ + + + +
using value_type = T
+
+

Type of the values stored in this array.

+ +
+
+ +
+
+ + + + +
using shape_type = Shape
+
+

Type of the shape of this array.

+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + +
array ()
+
+inline
+
+

Construct an array with a default constructed Shape. Most shapes are empty by default, but a Shape with non-zero compile-time constants for all extents will be non-empty.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
array (const Shape & shape,
const T & value,
const Alloc & alloc 
)
+
+inline
+
+

Construct an array with a particular shape, allocated by alloc. All elements in the array are copy-constructed from value.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
array (const Shape & shape,
const Alloc & alloc 
)
+
+inlineexplicit
+
+

Construct an array with a particular shape, allocated by alloc, with default constructed elements.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
array (const array< T, Shape, Alloc > & other)
+
+inline
+
+

Copy construct from another array other, using copy's allocator. This is a deep copy of the contents of other.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
array (const array< T, Shape, Alloc > & other,
const Alloc & alloc 
)
+
+inline
+
+

Copy construct from another array other. The array is allocated using alloc. This is a deep copy of the contents of other.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
array (array< T, Shape, Alloc > && other)
+
+inline
+
+

Move construct from another array other. If the allocator of this array is propagate_on_container_move_assignment or the allocators of both arrays are equal this operation moves the allocation of other to this array, and the other array becomes a default constructed array. Otherwise, each element is move-constructed into a new allocation.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
array (array< T, Shape, Alloc > && other,
const Alloc & alloc 
)
+
+inline
+
+

Move construct from another array other. If the allocator of this array and the other array are equal, this operation moves the allocation of other to this array, and the other array becomes a default constructed array. If the allocator of this and the other array are non-equal, each element is move-constructed into a new allocation.

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
static constexpr size_t rank ()
+
+inlinestatic
+
+

The number of dims in the shape of this array.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
static constexpr bool is_scalar ()
+
+inlinestatic
+
+

True if the rank of this array is 0.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
array& operator= (const array< T, Shape, Alloc > & other)
+
+inline
+
+

Assign the contents of the array as a copy of other. The array is deallocated if the allocator cannot be propagated on assignment. The array is then reallocated if necessary, and each element in the array is copy constructed from other.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
array& operator= (array< T, Shape, Alloc > && other)
+
+inline
+
+

Assign the contents of the array by moving from other. If the allocator can be propagated on move assignment, the allocation of other is moved in an O(1) operation. If the allocator cannot be propagated, each element is move-assigned from other.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void assign (const array< T, Shape, Alloc > & other)
+
+inline
+
+

Assign the contents of the array to be a copy or move of other. The array is destroyed, reallocated if necessary, and then each element is copy- or move-constructed from other.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void assign (Shape shape,
const T & value 
)
+
+inline
+
+

Assign the contents of this array to have shape with each element copy constructed from value.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
const Alloc& get_allocator () const
+
+inline
+
+

Get the allocator used to allocate memory for this buffer.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
reference operator[] (const index_type & indices)
+
+inline
+
+

Get a reference to the element at indices.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
auto operator[] (const std::tuple< Args... > & args)
+
+inline
+
+

Create an array_ref from this array using indices or intervals args. Dimensions corresponding to indices in args are sliced, i.e. the result will not have this dimension. The rest of the dimensions are cropped.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void for_each_value (Fn && fn)
+
+inline
+
+

Call a function with a reference to each value in this array. The order in which fn is called is undefined to enable optimized memory accesses.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
pointer base ()
+
+inline
+
+

Pointer to the element at the min index of the shape.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
pointer data ()
+
+inline
+
+

Pointer to the element at the beginning of the flat array. This is equivalent to base() if all of the strides of the shape are positive.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
const Shape& shape () const
+
+inline
+
+

Shape of this array.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void clear ()
+
+inline
+
+

Reset the shape of this array to default. If the default constructed Shape is empty, the array will be empty. If the default constructed Shape is non-empty, the elements of the array will be default constructed.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void reshape (Shape new_shape)
+
+inline
+
+

Reallocate the array, and move the intersection of the old and new shapes to the new array.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void set_shape (const Shape & new_shape,
index_t offset = 0 
)
+
+inline
+
+

Change the shape of the array to new_shape, and move the base pointer by offset. This function is disabled for non-trivial types, because it does not call the destructor or constructor for newly inaccessible or newly accessible elements, respectively.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
const auto& i () const
+
+inline
+
+

Provide some aliases for common interpretations of dimensions i, j, k as dimensions 0, 1, 2, respectively.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
const auto& x () const
+
+inline
+
+

Provide some aliases for common interpretations of dimensions x, y, z or c, w as dimensions 0, 1, 2, 3 respectively.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
index_t width () const
+
+inline
+
+

Assuming this array represents an image with dimensions width, height, channels, get the extent of those dimensions.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
index_t rows () const
+
+inline
+
+

Assuming this array represents a matrix with dimensions {rows, cols}, get the extent of those dimensions.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool operator!= (const array< T, Shape, Alloc > & other) const
+
+inline
+
+

Compare the contents of this array to other. For two arrays to be considered equal, they must have the same shape, and all elements addressable by the shape must also be equal.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void swap (array< T, Shape, Alloc > & other)
+
+inline
+
+

Swap the contents of two arrays. This performs zero copies or moves of individual elements.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
array_ref<T, Shape> ref ()
+
+inline
+
+

Make an array_ref referring to the data in this array.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
operator reference ()
+
+inline
+
+

Implicit conversion to T for scalar shaped arrays.

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/classnda_1_1array__ref-members.html b/classnda_1_1array__ref-members.html new file mode 100644 index 00000000..7ca73488 --- /dev/null +++ b/classnda_1_1array__ref-members.html @@ -0,0 +1,168 @@ + + + + + + +array: Member List + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
array_ref< T, Shape > Member List
+
+
+ +

This is the complete list of members for array_ref< T, Shape >, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
array_ref(pointer base=nullptr, const Shape &shape=Shape())array_ref< T, Shape >inline
array_ref(pointer base, const Shape &shape, std::false_type) (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
array_ref(const array_ref &other)=defaultarray_ref< T, Shape >
array_ref(array_ref &&other)=default (defined in array_ref< T, Shape >)array_ref< T, Shape >
array_ref(const array_ref< T, OtherShape > &other)array_ref< T, Shape >inline
base() const array_ref< T, Shape >inline
c() (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
c() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
channels() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
columns() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
const_reference typedef (defined in array_ref< T, Shape >)array_ref< T, Shape >
cref() const array_ref< T, Shape >inline
data() const array_ref< T, Shape >inline
dim() (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
dim() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
dim(size_t d) const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
empty() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
for_each_value(Fn &&fn) const array_ref< T, Shape >inline
height() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
i()array_ref< T, Shape >inline
i() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
index_type typedef (defined in array_ref< T, Shape >)array_ref< T, Shape >
is_compact() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
is_scalar()array_ref< T, Shape >inlinestatic
j() (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
j() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
k() (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
k() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
operator const_array_ref< T, Shape >() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
operator reference() const array_ref< T, Shape >inline
operator!=(const array_ref &other) const array_ref< T, Shape >inline
operator()(Args...indices) const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
operator()(Args...args) const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
operator=(const array_ref &other)=default (defined in array_ref< T, Shape >)array_ref< T, Shape >
operator=(array_ref &&other)=default (defined in array_ref< T, Shape >)array_ref< T, Shape >
operator=(const array_ref< T, OtherShape > &other) (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
operator==(const array_ref &other) const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
operator[](const index_type &indices) const array_ref< T, Shape >inline
operator[](const std::tuple< Args... > &args) const array_ref< T, Shape >inline
pointer typedef (defined in array_ref< T, Shape >)array_ref< T, Shape >
rank()array_ref< T, Shape >inlinestatic
ref() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
reference typedef (defined in array_ref< T, Shape >)array_ref< T, Shape >
rows() const array_ref< T, Shape >inline
set_shape(const Shape &new_shape, index_t offset=0)array_ref< T, Shape >inline
shape()array_ref< T, Shape >inline
shape() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
shape_traits_type typedef (defined in array_ref< T, Shape >)array_ref< T, Shape >
shape_type typedefarray_ref< T, Shape >
size() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
size_type typedef (defined in array_ref< T, Shape >)array_ref< T, Shape >
value_type typedefarray_ref< T, Shape >
w() (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
w() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
width() const array_ref< T, Shape >inline
x()array_ref< T, Shape >inline
x() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
y() (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
y() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
z() (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
z() const (defined in array_ref< T, Shape >)array_ref< T, Shape >inline
+ + + + diff --git a/classnda_1_1array__ref.html b/classnda_1_1array__ref.html new file mode 100644 index 00000000..d67d7724 --- /dev/null +++ b/classnda_1_1array__ref.html @@ -0,0 +1,813 @@ + + + + + + +array: array_ref< T, Shape > Class Template Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
array_ref< T, Shape > Class Template Reference
+
+
+ +

#include <array.h>

+ + + + + + + + + + + + + + + + + + +

+Public Types

using value_type = T
 
+using reference = value_type &
 
+using const_reference = const value_type &
 
+using pointer = value_type *
 
using shape_type = Shape
 
+using index_type = typename Shape::index_type
 
+using shape_traits_type = shape_traits< Shape >
 
+using size_type = size_t
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

NDARRAY_HOST_DEVICE array_ref (pointer base=nullptr, const Shape &shape=Shape())
 
+NDARRAY_HOST_DEVICE array_ref (pointer base, const Shape &shape, std::false_type)
 
NDARRAY_HOST_DEVICE array_ref (const array_ref &other)=default
 
+NDARRAY_HOST_DEVICE array_ref (array_ref &&other)=default
 
+NDARRAY_HOST_DEVICE array_refoperator= (const array_ref &other)=default
 
+NDARRAY_HOST_DEVICE array_refoperator= (array_ref &&other)=default
 
template<class OtherShape , class = enable_if_shape_compatible<OtherShape>>
NDARRAY_HOST_DEVICE array_ref (const array_ref< T, OtherShape > &other)
 
+template<class OtherShape , class = enable_if_shape_compatible<OtherShape>>
NDARRAY_HOST_DEVICE array_refoperator= (const array_ref< T, OtherShape > &other)
 
NDARRAY_HOST_DEVICE reference operator[] (const index_type &indices) const
 
+template<class... Args, class = enable_if_all_indices<Args...>>
NDARRAY_HOST_DEVICE reference operator() (Args...indices) const
 
template<class... Args, class = enable_if_any_slices<Args...>>
NDARRAY_HOST_DEVICE auto operator[] (const std::tuple< Args... > &args) const
 
+template<class... Args, class = enable_if_any_slices<Args...>>
NDARRAY_HOST_DEVICE auto operator() (Args...args) const
 
template<class Fn , class = internal::enable_if_callable<Fn, reference>>
NDARRAY_HOST_DEVICE void for_each_value (Fn &&fn) const
 
NDARRAY_HOST_DEVICE pointer base () const
 
NDARRAY_HOST_DEVICE pointer data () const
 
NDARRAY_HOST_DEVICE Shape & shape ()
 
+NDARRAY_HOST_DEVICE const Shape & shape () const
 
+template<size_t D, class = enable_if_dim<D>>
NDARRAY_HOST_DEVICE auto & dim ()
 
+template<size_t D, class = enable_if_dim<D>>
NDARRAY_HOST_DEVICE const auto & dim () const
 
+const nda::dim dim (size_t d) const
 
+NDARRAY_HOST_DEVICE size_type size () const
 
+NDARRAY_HOST_DEVICE bool empty () const
 
+NDARRAY_HOST_DEVICE bool is_compact () const
 
NDARRAY_HOST_DEVICE auto & i ()
 
+NDARRAY_HOST_DEVICE const auto & i () const
 
+NDARRAY_HOST_DEVICE auto & j ()
 
+NDARRAY_HOST_DEVICE const auto & j () const
 
+NDARRAY_HOST_DEVICE auto & k ()
 
+NDARRAY_HOST_DEVICE const auto & k () const
 
NDARRAY_HOST_DEVICE auto & x ()
 
+NDARRAY_HOST_DEVICE const auto & x () const
 
+NDARRAY_HOST_DEVICE auto & y ()
 
+NDARRAY_HOST_DEVICE const auto & y () const
 
+NDARRAY_HOST_DEVICE auto & z ()
 
+NDARRAY_HOST_DEVICE const auto & z () const
 
+NDARRAY_HOST_DEVICE auto & c ()
 
+NDARRAY_HOST_DEVICE const auto & c () const
 
+NDARRAY_HOST_DEVICE auto & w ()
 
+NDARRAY_HOST_DEVICE const auto & w () const
 
NDARRAY_HOST_DEVICE index_t width () const
 
+NDARRAY_HOST_DEVICE index_t height () const
 
+NDARRAY_HOST_DEVICE index_t channels () const
 
NDARRAY_HOST_DEVICE index_t rows () const
 
+NDARRAY_HOST_DEVICE index_t columns () const
 
NDARRAY_HOST_DEVICE bool operator!= (const array_ref &other) const
 
+NDARRAY_HOST_DEVICE bool operator== (const array_ref &other) const
 
+NDARRAY_HOST_DEVICE const array_ref< T, Shape > & ref () const
 
NDARRAY_HOST_DEVICE const const_array_ref< T, Shape > cref () const
 
+NDARRAY_HOST_DEVICE operator const_array_ref< T, Shape > () const
 
template<std::size_t R = rank(), typename = std::enable_if_t<R == 0>>
NDARRAY_HOST_DEVICE operator reference () const
 
NDARRAY_HOST_DEVICE void set_shape (const Shape &new_shape, index_t offset=0)
 
+ + + + + +

+Static Public Member Functions

static constexpr size_t rank ()
 
static constexpr bool is_scalar ()
 
+

Detailed Description

+

template<class T, class Shape>
+class nda::array_ref< T, Shape >

+ +

A reference to an array is an object with a shape mapping indices to flat offsets, which are used to dereference a pointer. This object does not own any memory, and it is cheap to copy.

+

Member Typedef Documentation

+ +
+
+ + + + +
using value_type = T
+
+

Type of elements referenced in this array_ref.

+ +
+
+ +
+
+ + + + +
using shape_type = Shape
+
+

Type of the shape of this array_ref.

+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
NDARRAY_HOST_DEVICE array_ref (pointer base = nullptr,
const Shape & shape = Shape() 
)
+
+inline
+
+

Make an array_ref to the given base pointer, interpreting it as having the shape shape.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_HOST_DEVICE array_ref (const array_ref< T, Shape > & other)
+
+default
+
+

Shallow copy or assign an array_ref.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_HOST_DEVICE array_ref (const array_ref< T, OtherShape > & other)
+
+inline
+
+

Shallow copy or assign an array_ref with a different shape type.

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
static constexpr size_t rank ()
+
+inlinestatic
+
+

The number of dims in the shape of this array.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
static constexpr bool is_scalar ()
+
+inlinestatic
+
+

True if the rank of this array is 0.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_HOST_DEVICE reference operator[] (const index_type & indices) const
+
+inline
+
+

Get a reference to the element at indices.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_HOST_DEVICE auto operator[] (const std::tuple< Args... > & args) const
+
+inline
+
+

Create an array_ref from this array_ref using indices or intervals args. Dimensions corresponding to indices in args are sliced, i.e. the result will not have this dimension. The rest of the dimensions are cropped.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_HOST_DEVICE void for_each_value (Fn && fn) const
+
+inline
+
+

Call a function with a reference to each value in this array_ref. The order in which fn is called is undefined, to enable optimized memory access patterns.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE pointer base () const
+
+inline
+
+

Pointer to the element at the min index of the shape.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE pointer data () const
+
+inline
+
+

Pointer to the element at the beginning of the flat array. This is equivalent to base() if all of the strides of the shape are positive.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE Shape& shape ()
+
+inline
+
+

Shape of this array_ref.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE auto& i ()
+
+inline
+
+

Provide some aliases for common interpretations of dimensions i, j, k as dimensions 0, 1, 2, respectively.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE auto& x ()
+
+inline
+
+

Provide some aliases for common interpretations of dimensions x, y, z or c, w as dimensions 0, 1, 2, 3 respectively.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE index_t width () const
+
+inline
+
+

Assuming this array represents an image with dimensions width, height, channels, get the extent of those dimensions.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE index_t rows () const
+
+inline
+
+

Assuming this array represents a matrix with dimensions {rows, cols}, get the extent of those dimensions.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_HOST_DEVICE bool operator!= (const array_ref< T, Shape > & other) const
+
+inline
+
+

Compare the contents of this array_ref to other. For two array_refs to be considered equal, they must have the same shape, and all elements addressable by the shape must also be equal.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE const const_array_ref<T, Shape> cref () const
+
+inline
+
+

Allow conversion from array_ref<T> to const_array_ref<T>.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE operator reference () const
+
+inline
+
+

Implicit conversion to T for scalar shaped array_refs.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
NDARRAY_HOST_DEVICE void set_shape (const Shape & new_shape,
index_t offset = 0 
)
+
+inline
+
+

Change the shape of the array to new_shape, and move the base pointer by offset. The new shape must be a subset of the old shape.

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/classnda_1_1auto__allocator-members.html b/classnda_1_1auto__allocator-members.html new file mode 100644 index 00000000..2763fd0e --- /dev/null +++ b/classnda_1_1auto__allocator-members.html @@ -0,0 +1,122 @@ + + + + + + +array: Member List + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
auto_allocator< T, N, Alignment, BaseAlloc > Member List
+
+
+ +

This is the complete list of members for auto_allocator< T, N, Alignment, BaseAlloc >, including all inherited members.

+ + + + + + + + + + + + + + + + +
allocate(size_t n) (defined in auto_allocator< T, N, Alignment, BaseAlloc >)auto_allocator< T, N, Alignment, BaseAlloc >inline
auto_allocator() (defined in auto_allocator< T, N, Alignment, BaseAlloc >)auto_allocator< T, N, Alignment, BaseAlloc >inline
auto_allocator(const auto_allocator< U, U_N, U_A, U_BaseAlloc > &) noexcept (defined in auto_allocator< T, N, Alignment, BaseAlloc >)auto_allocator< T, N, Alignment, BaseAlloc >inline
auto_allocator(const auto_allocator &copy) noexcept (defined in auto_allocator< T, N, Alignment, BaseAlloc >)auto_allocator< T, N, Alignment, BaseAlloc >inline
auto_allocator(auto_allocator &&move) noexcept (defined in auto_allocator< T, N, Alignment, BaseAlloc >)auto_allocator< T, N, Alignment, BaseAlloc >inline
deallocate(value_type *ptr, size_t n) noexcept (defined in auto_allocator< T, N, Alignment, BaseAlloc >)auto_allocator< T, N, Alignment, BaseAlloc >inline
operator!= (defined in auto_allocator< T, N, Alignment, BaseAlloc >)auto_allocator< T, N, Alignment, BaseAlloc >friend
operator=(const auto_allocator &copy) (defined in auto_allocator< T, N, Alignment, BaseAlloc >)auto_allocator< T, N, Alignment, BaseAlloc >inline
operator=(auto_allocator &&move) (defined in auto_allocator< T, N, Alignment, BaseAlloc >)auto_allocator< T, N, Alignment, BaseAlloc >inline
operator== (defined in auto_allocator< T, N, Alignment, BaseAlloc >)auto_allocator< T, N, Alignment, BaseAlloc >friend
propagate_on_container_copy_assignment typedef (defined in auto_allocator< T, N, Alignment, BaseAlloc >)auto_allocator< T, N, Alignment, BaseAlloc >
propagate_on_container_move_assignment typedef (defined in auto_allocator< T, N, Alignment, BaseAlloc >)auto_allocator< T, N, Alignment, BaseAlloc >
propagate_on_container_swap typedef (defined in auto_allocator< T, N, Alignment, BaseAlloc >)auto_allocator< T, N, Alignment, BaseAlloc >
select_on_container_copy_construction(const auto_allocator &) (defined in auto_allocator< T, N, Alignment, BaseAlloc >)auto_allocator< T, N, Alignment, BaseAlloc >inlinestatic
value_type typedef (defined in auto_allocator< T, N, Alignment, BaseAlloc >)auto_allocator< T, N, Alignment, BaseAlloc >
+ + + + diff --git a/classnda_1_1auto__allocator.html b/classnda_1_1auto__allocator.html new file mode 100644 index 00000000..b19eb7d7 --- /dev/null +++ b/classnda_1_1auto__allocator.html @@ -0,0 +1,178 @@ + + + + + + +array: auto_allocator< T, N, Alignment, BaseAlloc > Class Template Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
auto_allocator< T, N, Alignment, BaseAlloc > Class Template Reference
+
+
+ +

#include <array.h>

+ + + + + + + + + + +

+Public Types

+using value_type = T
 
+using propagate_on_container_copy_assignment = std::false_type
 
+using propagate_on_container_move_assignment = std::false_type
 
+using propagate_on_container_swap = std::false_type
 
+ + + + + + + + + + + + + + + + +

+Public Member Functions

+template<class U , size_t U_N, size_t U_A, class U_BaseAlloc >
constexpr auto_allocator (const auto_allocator< U, U_N, U_A, U_BaseAlloc > &) noexcept
 
auto_allocator (const auto_allocator &copy) noexcept
 
auto_allocator (auto_allocator &&move) noexcept
 
+auto_allocatoroperator= (const auto_allocator &copy)
 
+auto_allocatoroperator= (auto_allocator &&move)
 
+value_type * allocate (size_t n)
 
+void deallocate (value_type *ptr, size_t n) noexcept
 
+ + + +

+Static Public Member Functions

+static auto_allocator select_on_container_copy_construction (const auto_allocator &)
 
+ + + + + + + +

+Friends

+template<class U , size_t U_N, size_t U_A>
bool operator== (const auto_allocator &a, const auto_allocator< U, U_N, U_A > &b)
 
+template<class U , size_t U_N, size_t U_A>
bool operator!= (const auto_allocator &a, const auto_allocator< U, U_N, U_A > &b)
 
+

Detailed Description

+

template<class T, size_t N, size_t Alignment = alignof(T), class BaseAlloc = std::allocator<T>>
+class nda::auto_allocator< T, N, Alignment, BaseAlloc >

+ +

Allocator satisfying the std::allocator interface that owns a buffer with automatic storage, and a fallback base allocator. For allocations, the allocator uses the buffer if it is large enough and not already allocated, otherwise it uses the base allocator.

+

The documentation for this class was generated from the following file: +
+ + + + diff --git a/classnda_1_1copy__shape__traits-members.html b/classnda_1_1copy__shape__traits-members.html new file mode 100644 index 00000000..8ac380d6 --- /dev/null +++ b/classnda_1_1copy__shape__traits-members.html @@ -0,0 +1,110 @@ + + + + + + +array: Member List + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
copy_shape_traits< ShapeSrc, ShapeDst > Member List
+
+
+ +

This is the complete list of members for copy_shape_traits< ShapeSrc, ShapeDst >, including all inherited members.

+ + + + +
dst_shape_type typedef (defined in copy_shape_traits< ShapeSrc, ShapeDst >)copy_shape_traits< ShapeSrc, ShapeDst >
for_each_value(const ShapeSrc &shape_src, TSrc src, const ShapeDst &shape_dst, TDst dst, Fn &&fn)copy_shape_traits< ShapeSrc, ShapeDst >inlinestatic
src_shape_type typedef (defined in copy_shape_traits< ShapeSrc, ShapeDst >)copy_shape_traits< ShapeSrc, ShapeDst >
+ + + + diff --git a/classnda_1_1copy__shape__traits.html b/classnda_1_1copy__shape__traits.html new file mode 100644 index 00000000..0f040242 --- /dev/null +++ b/classnda_1_1copy__shape__traits.html @@ -0,0 +1,188 @@ + + + + + + +array: copy_shape_traits< ShapeSrc, ShapeDst > Class Template Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
copy_shape_traits< ShapeSrc, ShapeDst > Class Template Reference
+
+
+ +

#include <array.h>

+ + + + + + +

+Public Types

+using src_shape_type = ShapeSrc
 
+using dst_shape_type = ShapeDst
 
+ + + + +

+Static Public Member Functions

template<class Fn , class TSrc , class TDst >
static NDARRAY_HOST_DEVICE void for_each_value (const ShapeSrc &shape_src, TSrc src, const ShapeDst &shape_dst, TDst dst, Fn &&fn)
 
+

Detailed Description

+

template<class ShapeSrc, class ShapeDst>
+class nda::copy_shape_traits< ShapeSrc, ShapeDst >

+ +

Copy shape traits enable some behaviors to be customized on a pairwise shape basis for copies.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static NDARRAY_HOST_DEVICE void for_each_value (const ShapeSrc & shape_src,
TSrc src,
const ShapeDst & shape_dst,
TDst dst,
Fn && fn 
)
+
+inlinestatic
+
+

The for_each_value implementation for the shapes may be able to statically optimize the shapes. The default implementation optimizes the shapes at runtime, and only attempts to convert the shapes to dense_shapes of the same rank.

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/classnda_1_1dim-members.html b/classnda_1_1dim-members.html new file mode 100644 index 00000000..d450e78e --- /dev/null +++ b/classnda_1_1dim-members.html @@ -0,0 +1,154 @@ + + + + + + +array: Member List + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
dim< Min_, Extent_, Stride_ > Member List
+
+
+ +

This is the complete list of members for dim< Min_, Extent_, Stride_ >, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
base_range typedef (defined in dim< Min_, Extent_, Stride_ >)dim< Min_, Extent_, Stride_ >
begin() const interval< Min_, Extent_ >inlineprotected
DefaultStride (defined in dim< Min_, Extent_, Stride_ >)dim< Min_, Extent_, Stride_ >static
dim(index_t min, index_t extent, index_t stride=DefaultStride)dim< Min_, Extent_, Stride_ >inline
dim(index_t extent) (defined in dim< Min_, Extent_, Stride_ >)dim< Min_, Extent_, Stride_ >inline
dim() (defined in dim< Min_, Extent_, Stride_ >)dim< Min_, Extent_, Stride_ >inline
dim(const base_range &interval, index_t stride=DefaultStride) (defined in dim< Min_, Extent_, Stride_ >)dim< Min_, Extent_, Stride_ >inline
dim(const dim &)=default (defined in dim< Min_, Extent_, Stride_ >)dim< Min_, Extent_, Stride_ >
dim(dim &&)=default (defined in dim< Min_, Extent_, Stride_ >)dim< Min_, Extent_, Stride_ >
dim(const dim< CopyMin, CopyExtent, CopyStride > &other)dim< Min_, Extent_, Stride_ >inline
end() const interval< Min_, Extent_ >inlineprotected
extent() const interval< Min_, Extent_ >inlineprotected
Extent (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >protectedstatic
extent_ (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >protected
flat_offset(index_t at) const dim< Min_, Extent_, Stride_ >inline
interval(index_t min, index_t extent)interval< Min_, Extent_ >inlineprotected
interval(index_t min) (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inlineprotected
interval() (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inlineprotected
interval(const interval &)=default (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >protected
interval(interval &&)=default (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >protected
interval(const interval< CopyMin, CopyExtent > &other)interval< Min_, Extent_ >inlineprotected
is_in_range(index_t at) const interval< Min_, Extent_ >inlineprotected
is_in_range(const interval< OtherMin, OtherExtent > &at) const interval< Min_, Extent_ >inlineprotected
is_in_range(const dim< OtherMin, OtherExtent, OtherStride > &at) const (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inlineprotected
Max (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >protectedstatic
max() const interval< Min_, Extent_ >inlineprotected
min() const interval< Min_, Extent_ >inlineprotected
Min (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >protectedstatic
min_ (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >protected
operator!=(const dim< OtherMin, OtherExtent, OtherStride > &other) const (defined in dim< Min_, Extent_, Stride_ >)dim< Min_, Extent_, Stride_ >inline
operator!=(const interval< OtherMin, OtherExtent > &other) const (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inlineprotected
operator=(const dim &)=default (defined in dim< Min_, Extent_, Stride_ >)dim< Min_, Extent_, Stride_ >
operator=(dim &&)=default (defined in dim< Min_, Extent_, Stride_ >)dim< Min_, Extent_, Stride_ >
operator=(const dim< CopyMin, CopyExtent, CopyStride > &other) (defined in dim< Min_, Extent_, Stride_ >)dim< Min_, Extent_, Stride_ >inline
operator=(const interval &)=default (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >protected
operator=(interval &&)=default (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >protected
operator=(const interval< CopyMin, CopyExtent > &other) (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inlineprotected
operator==(const dim< OtherMin, OtherExtent, OtherStride > &other) const dim< Min_, Extent_, Stride_ >inline
nda::interval::operator==(const interval< OtherMin, OtherExtent > &other) const interval< Min_, Extent_ >inlineprotected
set_extent(index_t extent) (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inlineprotected
set_max(index_t max) (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inlineprotected
set_min(index_t min) (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inlineprotected
set_stride(index_t stride) (defined in dim< Min_, Extent_, Stride_ >)dim< Min_, Extent_, Stride_ >inline
size() const (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inlineprotected
stride() const dim< Min_, Extent_, Stride_ >inline
Stride (defined in dim< Min_, Extent_, Stride_ >)dim< Min_, Extent_, Stride_ >static
stride_ (defined in dim< Min_, Extent_, Stride_ >)dim< Min_, Extent_, Stride_ >protected
+ + + + diff --git a/classnda_1_1dim.html b/classnda_1_1dim.html new file mode 100644 index 00000000..cf971530 --- /dev/null +++ b/classnda_1_1dim.html @@ -0,0 +1,426 @@ + + + + + + +array: dim< Min_, Extent_, Stride_ > Class Template Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
dim< Min_, Extent_, Stride_ > Class Template Reference
+
+
+ +

#include <array.h>

+
+Inheritance diagram for dim< Min_, Extent_, Stride_ >:
+
+
+ + +interval< Min_, Extent_ > + +
+ + + + +

+Public Types

+using base_range = interval< Min_, Extent_ >
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

NDARRAY_HOST_DEVICE dim (index_t min, index_t extent, index_t stride=DefaultStride)
 
+NDARRAY_HOST_DEVICE dim (index_t extent)
 
+NDARRAY_HOST_DEVICE dim (const base_range &interval, index_t stride=DefaultStride)
 
+NDARRAY_HOST_DEVICE dim (const dim &)=default
 
+NDARRAY_HOST_DEVICE dim (dim &&)=default
 
+NDARRAY_HOST_DEVICE dimoperator= (const dim &)=default
 
+NDARRAY_HOST_DEVICE dimoperator= (dim &&)=default
 
template<index_t CopyMin, index_t CopyExtent, index_t CopyStride, class = internal::disable_if_not_equal<Min, CopyMin>, class = internal::disable_if_not_equal<Extent, CopyExtent>, class = internal::disable_if_not_equal<Stride, CopyStride>>
NDARRAY_HOST_DEVICE dim (const dim< CopyMin, CopyExtent, CopyStride > &other)
 
+template<index_t CopyMin, index_t CopyExtent, index_t CopyStride, class = internal::disable_if_not_equal<Min, CopyMin>, class = internal::disable_if_not_equal<Extent, CopyExtent>, class = internal::disable_if_not_equal<Stride, CopyStride>>
NDARRAY_HOST_DEVICE dimoperator= (const dim< CopyMin, CopyExtent, CopyStride > &other)
 
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t stride () const
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE void set_stride (index_t stride)
 
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t flat_offset (index_t at) const
 
template<index_t OtherMin, index_t OtherExtent, index_t OtherStride>
NDARRAY_HOST_DEVICE bool operator== (const dim< OtherMin, OtherExtent, OtherStride > &other) const
 
+template<index_t OtherMin, index_t OtherExtent, index_t OtherStride>
NDARRAY_HOST_DEVICE bool operator!= (const dim< OtherMin, OtherExtent, OtherStride > &other) const
 
+ + + + + +

+Static Public Attributes

+static constexpr index_t Stride = Stride_
 
+static constexpr index_t DefaultStride = internal::is_static(Stride) ? Stride : unresolved
 
+ + + + + + + + +

+Protected Attributes

+internal::constexpr_index< Stride_ > stride_
 
- Protected Attributes inherited from interval< Min_, Extent_ >
+internal::constexpr_index< Min_ > min_
 
+internal::constexpr_index< Extent_ > extent_
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Additional Inherited Members

- Protected Member Functions inherited from interval< Min_, Extent_ >
NDARRAY_HOST_DEVICE interval (index_t min, index_t extent)
 
+NDARRAY_HOST_DEVICE interval (index_t min)
 
+NDARRAY_HOST_DEVICE interval (const interval &)=default
 
+NDARRAY_HOST_DEVICE interval (interval &&)=default
 
+NDARRAY_HOST_DEVICE intervaloperator= (const interval &)=default
 
+NDARRAY_HOST_DEVICE intervaloperator= (interval &&)=default
 
template<index_t CopyMin, index_t CopyExtent, class = internal::disable_if_not_equal<Min, CopyMin>, class = internal::disable_if_not_equal<Extent, CopyExtent>>
NDARRAY_HOST_DEVICE interval (const interval< CopyMin, CopyExtent > &other)
 
+template<index_t CopyMin, index_t CopyExtent, class = internal::disable_if_not_equal<Min, CopyMin>, class = internal::disable_if_not_equal<Extent, CopyExtent>>
NDARRAY_HOST_DEVICE intervaloperator= (const interval< CopyMin, CopyExtent > &other)
 
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t min () const
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE void set_min (index_t min)
 
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t extent () const
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t size () const
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE void set_extent (index_t extent)
 
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t max () const
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE void set_max (index_t max)
 
NDARRAY_INLINE NDARRAY_HOST_DEVICE bool is_in_range (index_t at) const
 
template<index_t OtherMin, index_t OtherExtent>
NDARRAY_INLINE NDARRAY_HOST_DEVICE bool is_in_range (const interval< OtherMin, OtherExtent > &at) const
 
+template<index_t OtherMin, index_t OtherExtent, index_t OtherStride>
NDARRAY_INLINE NDARRAY_HOST_DEVICE bool is_in_range (const dim< OtherMin, OtherExtent, OtherStride > &at) const
 
NDARRAY_HOST_DEVICE index_iterator begin () const
 
NDARRAY_HOST_DEVICE index_iterator end () const
 
template<index_t OtherMin, index_t OtherExtent>
NDARRAY_HOST_DEVICE bool operator== (const interval< OtherMin, OtherExtent > &other) const
 
+template<index_t OtherMin, index_t OtherExtent>
NDARRAY_HOST_DEVICE bool operator!= (const interval< OtherMin, OtherExtent > &other) const
 
- Static Protected Attributes inherited from interval< Min_, Extent_ >
+static constexpr index_t Min = Min_
 
+static constexpr index_t Extent = Extent_
 
+static constexpr index_t Max = internal::static_sub(internal::static_add(Min, Extent), 1)
 
+

Detailed Description

+

template<index_t Min_ = dynamic, index_t Extent_ = dynamic, index_t Stride_ = dynamic>
+class nda::dim< Min_, Extent_, Stride_ >

+ +

Describes one dimension of an array. The template parameters enable providing compile time constants for the min, extent, and stride of the dim.

+

These parameters define a mapping from the indices of the dimension to offsets: offset(x) = (x - min)*stride. The extent does not affect the mapping directly. Values not in the interval [min, min + extent) are considered to be out of bounds.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
NDARRAY_HOST_DEVICE dim (index_t min,
index_t extent,
index_t stride = DefaultStride 
)
+
+inline
+
+

Construct a new dim object. If the min, extent or stride are specified in the constructor, it must have a value compatible with Min, Extent, or Stride, respectively.

+

The default values if not specified in the constructor are:

    +
  • The default min is Min if Min is static, or 0 if not.
  • +
  • The default extent is Extent if Extent is static, or 0 if not.
  • +
  • The default stride is Stride.
  • +
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_HOST_DEVICE dim (const dim< CopyMin, CopyExtent, CopyStride > & other)
+
+inline
+
+

Copy construction or assignment of another dim object, possibly with different compile-time template parameters. other.min(), other.extent(), and other.stride() must be compatible with Min, Extent, and Stride, respectively.

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t stride () const
+
+inline
+
+

Get or set the distance in flat indices between neighboring elements in this dim.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t flat_offset (index_t at) const
+
+inline
+
+

Offset of the index at in this dim in the flat array.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_HOST_DEVICE bool operator== (const dim< OtherMin, OtherExtent, OtherStride > & other) const
+
+inline
+
+

Two dim objects are considered equal if their mins, extents, and strides are equal.

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/classnda_1_1dim.png b/classnda_1_1dim.png new file mode 100644 index 0000000000000000000000000000000000000000..59cf93dc2ed6eedf46174af0382ccd5d89095bd6 GIT binary patch literal 759 zcmVvTJkN^MxkN^Mxkifve1&Q1r00008bW%=J0RR90|NsC0)yh;d0007pNkl~AEv$dt@`vl4cl#3d_FSMOsh0oocd=K${x8286Ww|DtW{U7 zU486aK$4td-&WC-H|t5#2lcVj;s!O}n~QNby;Ypn&WcZxsa2l#PDql|f!jN5BQwT+ z2M)Wv49VBowkL`C_uUoq;)%N0`Q5fqBy4k%Nd9}>Gw3TCFw3rY)QIH<6@HEYA155!t zO*7j7P9cOao(KS=X<`H1rHKu2mmK!{w)YaL|6oWuln}BQkab-i=*eTm7uloytSI%~G4q#g4ViVhK zk_pcNc8wBW;}F{wv^&&HN#32aZePH5<2(>xoBbqDY)#W`6RtGPjH}-406Vgr2}v9K zLbmNm(m9g4*rmj}vkBXrB$;L(r~EPGkylO + + + + + +array: Member List + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
index_iterator Member List
+
+
+ +

This is the complete list of members for index_iterator, including all inherited members.

+ + + + + + + + + + + + + + + +
index_iterator(index_t i)index_iteratorinline
operator!=(const index_iterator &r) const (defined in index_iterator)index_iteratorinline
operator*() const index_iteratorinline
operator+(index_t r) (defined in index_iterator)index_iteratorinline
operator++(int) (defined in index_iterator)index_iteratorinline
operator++() (defined in index_iterator)index_iteratorinline
operator+=(index_t r) (defined in index_iterator)index_iteratorinline
operator-(index_t r) (defined in index_iterator)index_iteratorinline
operator-(const index_iterator &r) (defined in index_iterator)index_iteratorinline
operator--(int) (defined in index_iterator)index_iteratorinline
operator--() (defined in index_iterator)index_iteratorinline
operator-=(index_t r) (defined in index_iterator)index_iteratorinline
operator==(const index_iterator &r) const (defined in index_iterator)index_iteratorinline
operator[](index_t n) const (defined in index_iterator)index_iteratorinline
+ + + + diff --git a/classnda_1_1index__iterator.html b/classnda_1_1index__iterator.html new file mode 100644 index 00000000..3d437607 --- /dev/null +++ b/classnda_1_1index__iterator.html @@ -0,0 +1,209 @@ + + + + + + +array: index_iterator Class Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
index_iterator Class Reference
+
+
+ +

#include <array.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 index_iterator (index_t i)
 
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t operator* () const
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE bool operator== (const index_iterator &r) const
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE bool operator!= (const index_iterator &r) const
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE index_iterator operator++ (int)
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE index_iterator operator-- (int)
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE index_iteratoroperator++ ()
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE index_iteratoroperator-- ()
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE index_iteratoroperator+= (index_t r)
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE index_iteratoroperator-= (index_t r)
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE index_iterator operator+ (index_t r)
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE index_iterator operator- (index_t r)
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t operator- (const index_iterator &r)
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t operator[] (index_t n) const
 
+

Detailed Description

+

An iterator representing an index.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
index_iterator (index_t i)
+
+inline
+
+

Construct the iterator with an index i.

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t operator* () const
+
+inline
+
+

Access the current index of this iterator.

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/classnda_1_1interval-members.html b/classnda_1_1interval-members.html new file mode 100644 index 00000000..5099b0ea --- /dev/null +++ b/classnda_1_1interval-members.html @@ -0,0 +1,135 @@ + + + + + + +array: Member List + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
interval< Min_, Extent_ > Member List
+
+
+ +

This is the complete list of members for interval< Min_, Extent_ >, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
begin() const interval< Min_, Extent_ >inline
end() const interval< Min_, Extent_ >inline
Extent (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >static
extent() const interval< Min_, Extent_ >inline
extent_ (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >protected
interval(index_t min, index_t extent)interval< Min_, Extent_ >inline
interval(index_t min) (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inline
interval() (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inline
interval(const interval &)=default (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >
interval(interval &&)=default (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >
interval(const interval< CopyMin, CopyExtent > &other)interval< Min_, Extent_ >inline
is_in_range(index_t at) const interval< Min_, Extent_ >inline
is_in_range(const interval< OtherMin, OtherExtent > &at) const interval< Min_, Extent_ >inline
is_in_range(const dim< OtherMin, OtherExtent, OtherStride > &at) const (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inline
Max (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >static
max() const interval< Min_, Extent_ >inline
min() const interval< Min_, Extent_ >inline
Min (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >static
min_ (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >protected
operator!=(const interval< OtherMin, OtherExtent > &other) const (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inline
operator=(const interval &)=default (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >
operator=(interval &&)=default (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >
operator=(const interval< CopyMin, CopyExtent > &other) (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inline
operator==(const interval< OtherMin, OtherExtent > &other) const interval< Min_, Extent_ >inline
set_extent(index_t extent) (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inline
set_max(index_t max) (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inline
set_min(index_t min) (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inline
size() const (defined in interval< Min_, Extent_ >)interval< Min_, Extent_ >inline
+ + + + diff --git a/classnda_1_1interval.html b/classnda_1_1interval.html new file mode 100644 index 00000000..0e17b2e3 --- /dev/null +++ b/classnda_1_1interval.html @@ -0,0 +1,482 @@ + + + + + + +array: interval< Min_, Extent_ > Class Template Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
interval< Min_, Extent_ > Class Template Reference
+
+
+ +

#include <array.h>

+
+Inheritance diagram for interval< Min_, Extent_ >:
+
+
+ + +dim< Min_, Extent_, Stride_ > + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

NDARRAY_HOST_DEVICE interval (index_t min, index_t extent)
 
+NDARRAY_HOST_DEVICE interval (index_t min)
 
+NDARRAY_HOST_DEVICE interval (const interval &)=default
 
+NDARRAY_HOST_DEVICE interval (interval &&)=default
 
+NDARRAY_HOST_DEVICE intervaloperator= (const interval &)=default
 
+NDARRAY_HOST_DEVICE intervaloperator= (interval &&)=default
 
template<index_t CopyMin, index_t CopyExtent, class = internal::disable_if_not_equal<Min, CopyMin>, class = internal::disable_if_not_equal<Extent, CopyExtent>>
NDARRAY_HOST_DEVICE interval (const interval< CopyMin, CopyExtent > &other)
 
+template<index_t CopyMin, index_t CopyExtent, class = internal::disable_if_not_equal<Min, CopyMin>, class = internal::disable_if_not_equal<Extent, CopyExtent>>
NDARRAY_HOST_DEVICE intervaloperator= (const interval< CopyMin, CopyExtent > &other)
 
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t min () const
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE void set_min (index_t min)
 
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t extent () const
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t size () const
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE void set_extent (index_t extent)
 
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t max () const
 
+NDARRAY_INLINE NDARRAY_HOST_DEVICE void set_max (index_t max)
 
NDARRAY_INLINE NDARRAY_HOST_DEVICE bool is_in_range (index_t at) const
 
template<index_t OtherMin, index_t OtherExtent>
NDARRAY_INLINE NDARRAY_HOST_DEVICE bool is_in_range (const interval< OtherMin, OtherExtent > &at) const
 
+template<index_t OtherMin, index_t OtherExtent, index_t OtherStride>
NDARRAY_INLINE NDARRAY_HOST_DEVICE bool is_in_range (const dim< OtherMin, OtherExtent, OtherStride > &at) const
 
NDARRAY_HOST_DEVICE index_iterator begin () const
 
NDARRAY_HOST_DEVICE index_iterator end () const
 
template<index_t OtherMin, index_t OtherExtent>
NDARRAY_HOST_DEVICE bool operator== (const interval< OtherMin, OtherExtent > &other) const
 
+template<index_t OtherMin, index_t OtherExtent>
NDARRAY_HOST_DEVICE bool operator!= (const interval< OtherMin, OtherExtent > &other) const
 
+ + + + + + + +

+Static Public Attributes

+static constexpr index_t Min = Min_
 
+static constexpr index_t Extent = Extent_
 
+static constexpr index_t Max = internal::static_sub(internal::static_add(Min, Extent), 1)
 
+ + + + + +

+Protected Attributes

+internal::constexpr_index< Min_ > min_
 
+internal::constexpr_index< Extent_ > extent_
 
+

Detailed Description

+

template<index_t Min_ = dynamic, index_t Extent_ = dynamic>
+class nda::interval< Min_, Extent_ >

+ +

Describes a half-open interval of indices. The template parameters enable providing compile time constants for the min and extent of the interval. The values in the interval [min, min + extent) are considered in bounds.

+

interval<> a is said to be 'compatible with' another interval<Min, Extent> b if a.min() is compatible with Min and a.extent() is compatible with Extent.

+

Examples:

    +
  • interval<> is an interval with runtime-valued min and extent.
  • +
  • interval<0> is an interval with compile-time constant min of 0, and runtime-valued extent.
  • +
  • interval<dynamic, 8> is an interval with compile-time constant extent of 8 and runtime-valuedmin. -interval<2, 3>` is a fully compile-time constant interval of indices 2, 3, 4.
  • +
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
NDARRAY_HOST_DEVICE interval (index_t min,
index_t extent 
)
+
+inline
+
+

Construct a new interval object. If the min or extent is specified in the constructor, it must have a value compatible with Min or Extent, respectively.

+

The default values if not specified in the constructor are:

    +
  • The default min is Min if Min is static, or 0 if not.
  • +
  • The default extent is Extent if Extent is static, or 1 if not.
  • +
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_HOST_DEVICE interval (const interval< CopyMin, CopyExtent > & other)
+
+inline
+
+

Copy construction or assignment of another interval object, possibly with different compile-time template parameters. other.min() and other.extent() must be compatible with Min and Extent, respectively.

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t min () const
+
+inline
+
+

Get or set the first index in this interval.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t extent () const
+
+inline
+
+

Get or set the number of indices in this interval.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t max () const
+
+inline
+
+

Get or set the last index in this interval.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_INLINE NDARRAY_HOST_DEVICE bool is_in_range (index_t at) const
+
+inline
+
+

Returns true if at is within the interval [min(), max()].

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_INLINE NDARRAY_HOST_DEVICE bool is_in_range (const interval< OtherMin, OtherExtent > & at) const
+
+inline
+
+

Returns true if at.min() and at.max() are both within the interval [min(), max()].

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE index_iterator begin () const
+
+inline
+
+

Make an iterator referring to the first index in this interval.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE index_iterator end () const
+
+inline
+
+

Make an iterator referring to one past the last index in this interval.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_HOST_DEVICE bool operator== (const interval< OtherMin, OtherExtent > & other) const
+
+inline
+
+

Two interval objects are considered equal if they contain the same indices.

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/classnda_1_1interval.png b/classnda_1_1interval.png new file mode 100644 index 0000000000000000000000000000000000000000..8d95ef771f06552178f0a7b28d75edec42b5e784 GIT binary patch literal 761 zcmVvTJkN^MxkN^Mxkifve1&Q1r00008bW%=J0RR90|NsC0)yh;d0007rNkl{L1E1g~cs;jmQj#p<(|LLJ0kd0MMHTHb5&4Y=Bm( zW3PROiz+^**Y|TjEM5eA=`R-XtlGD*m-iJ4pp^gkTkN@BpXukq#Oi#8etyiFyY{hj z0syDjw`4Tw&3phS+Q&|l8`S*UJWO@ds$y8(E8a;a*ZQ`t1c1{)wKv#CW{f=t4!geP z+1qKqYLz$zzk;3SG2`R*`lL%wxmv)s^)%)($6R}7xdwi*+N&LH(Kpq;f$hfml)&1) zueLKsgs*$M76#bnj^wFHzV^1gNzA|Ru1)A6c3#_JiiB-$k~|;4iJJW{`P*s!8ha`3 zomo-@z^J$6*>XN%p>^F6f+?`^Nn*?A8 z;CUL}1{eZ(nufOlh5(+X;cb8+fTwAA8(;|FX&T-J7y@{jhPMHnrfHh`6O$zMrhzR< ztu(MDsg)ddn42VRl==^byuZwUWymH+8RFCLjg+*u5?hjLiZm;fB$e_XuVBwz+fv-X zeiJS6=_zS#274J&EuCeV%b04p{+47~idgc_Ge?l>@GbV7H$7scscuY_R#x|lcTyZ< z5=&B{R1RB`oW9(H_1$7C$Td5zz~0&Nu`$@GW rsjUXKB(>7OmZVnd7kiqfsXP4xcY7tn54Dwu00000NkvXXu0mjf&Axdm literal 0 HcmV?d00001 diff --git a/classnda_1_1shape-members.html b/classnda_1_1shape-members.html new file mode 100644 index 00000000..71fdc2ea --- /dev/null +++ b/classnda_1_1shape-members.html @@ -0,0 +1,171 @@ + + + + + + +array: Member List + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
shape< Dims > Member List
+
+
+ +

This is the complete list of members for shape< Dims >, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
c() (defined in shape< Dims >)shape< Dims >inline
c() const (defined in shape< Dims >)shape< Dims >inline
channels() const (defined in shape< Dims >)shape< Dims >inline
columns() const (defined in shape< Dims >)shape< Dims >inline
dim()shape< Dims >inline
dim() const (defined in shape< Dims >)shape< Dims >inline
dim(size_t d) const shape< Dims >inline
dim_indices typedef (defined in shape< Dims >)shape< Dims >
dims()shape< Dims >inline
dims() const (defined in shape< Dims >)shape< Dims >inline
dims_type typedefshape< Dims >
empty() const shape< Dims >inline
extent() const (defined in shape< Dims >)shape< Dims >inline
flat_extent() const (defined in shape< Dims >)shape< Dims >inline
flat_max() const (defined in shape< Dims >)shape< Dims >inline
flat_min() const shape< Dims >inline
height() const (defined in shape< Dims >)shape< Dims >inline
i()shape< Dims >inline
i() const (defined in shape< Dims >)shape< Dims >inline
index_type typedefshape< Dims >
is_compact() const shape< Dims >inline
is_in_range(const std::tuple< Args... > &args) const shape< Dims >inline
is_in_range(Args...args) const (defined in shape< Dims >)shape< Dims >inline
is_one_to_one() const shape< Dims >inline
is_resolved() const shape< Dims >inline
is_scalar()shape< Dims >inlinestatic
is_subset_of(const OtherShape &other, index_t offset) const shape< Dims >inline
j() (defined in shape< Dims >)shape< Dims >inline
j() const (defined in shape< Dims >)shape< Dims >inline
k() (defined in shape< Dims >)shape< Dims >inline
k() const (defined in shape< Dims >)shape< Dims >inline
max() const (defined in shape< Dims >)shape< Dims >inline
min() const (defined in shape< Dims >)shape< Dims >inline
operator!=(const shape< OtherDims... > &other) const (defined in shape< Dims >)shape< Dims >inline
operator()(Args...indices) const (defined in shape< Dims >)shape< Dims >inline
operator()(Args...args) const (defined in shape< Dims >)shape< Dims >inline
operator=(const shape &)=default (defined in shape< Dims >)shape< Dims >
operator=(shape &&)=default (defined in shape< Dims >)shape< Dims >
operator=(const shape< OtherDims... > &other) (defined in shape< Dims >)shape< Dims >inline
operator==(const shape< OtherDims... > &other) const shape< Dims >inline
operator[](const index_type &indices) const shape< Dims >inline
operator[](const std::tuple< Args... > &args) const shape< Dims >inline
rank()shape< Dims >inlinestatic
resolve()shape< Dims >inline
rows() const shape< Dims >inline
shape() (defined in shape< Dims >)shape< Dims >inline
shape(const Dims &...dims) (defined in shape< Dims >)shape< Dims >inline
shape(const shape &)=default (defined in shape< Dims >)shape< Dims >
shape(shape &&)=default (defined in shape< Dims >)shape< Dims >
shape(const std::tuple< OtherDims... > &other)shape< Dims >inline
shape(OtherDims...other_dims) (defined in shape< Dims >)shape< Dims >inline
shape(const shape< OtherDims... > &other) (defined in shape< Dims >)shape< Dims >inline
size() const shape< Dims >inline
size_type typedef (defined in shape< Dims >)shape< Dims >
stride() const (defined in shape< Dims >)shape< Dims >inline
w() (defined in shape< Dims >)shape< Dims >inline
w() const (defined in shape< Dims >)shape< Dims >inline
width() const shape< Dims >inline
x()shape< Dims >inline
x() const (defined in shape< Dims >)shape< Dims >inline
y() (defined in shape< Dims >)shape< Dims >inline
y() const (defined in shape< Dims >)shape< Dims >inline
z() (defined in shape< Dims >)shape< Dims >inline
z() const (defined in shape< Dims >)shape< Dims >inline
+ + + + diff --git a/classnda_1_1shape.html b/classnda_1_1shape.html new file mode 100644 index 00000000..65b595db --- /dev/null +++ b/classnda_1_1shape.html @@ -0,0 +1,889 @@ + + + + + + +array: shape< Dims > Class Template Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
shape< Dims > Class Template Reference
+
+
+ +

#include <array.h>

+ + + + + + + + + + +

+Public Types

using dims_type = std::tuple< Dims... >
 
using index_type = index_of_rank< rank()>
 
+using size_type = size_t
 
+using dim_indices = decltype(internal::make_index_sequence< std::tuple_size< dims_type >::value >())
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

+template<size_t N = sizeof...(Dims), class = std::enable_if_t<(N > 0>
NDARRAY_HOST_DEVICE shape (const Dims &...dims)
 
+NDARRAY_HOST_DEVICE shape (const shape &)=default
 
+NDARRAY_HOST_DEVICE shape (shape &&)=default
 
+NDARRAY_HOST_DEVICE shapeoperator= (const shape &)=default
 
+NDARRAY_HOST_DEVICE shapeoperator= (shape &&)=default
 
template<class... OtherDims, class = enable_if_dims_compatible<OtherDims...>>
NDARRAY_HOST_DEVICE shape (const std::tuple< OtherDims... > &other)
 
+template<class... OtherDims, class = enable_if_dims_compatible<OtherDims...>>
NDARRAY_HOST_DEVICE shape (OtherDims...other_dims)
 
+template<class... OtherDims, class = enable_if_dims_compatible<OtherDims...>>
NDARRAY_HOST_DEVICE shape (const shape< OtherDims... > &other)
 
+template<class... OtherDims, class = enable_if_dims_compatible<OtherDims...>>
NDARRAY_HOST_DEVICE shapeoperator= (const shape< OtherDims... > &other)
 
NDARRAY_HOST_DEVICE void resolve ()
 
NDARRAY_HOST_DEVICE bool is_resolved () const
 
template<class... Args, class = enable_if_any_slices_or_indices<Args...>>
NDARRAY_HOST_DEVICE bool is_in_range (const std::tuple< Args... > &args) const
 
+template<class... Args, class = enable_if_any_slices_or_indices<Args...>>
NDARRAY_HOST_DEVICE bool is_in_range (Args...args) const
 
NDARRAY_HOST_DEVICE index_t operator[] (const index_type &indices) const
 
+template<class... Args, class = enable_if_all_indices<Args...>>
NDARRAY_HOST_DEVICE index_t operator() (Args...indices) const
 
template<class... Args, class = enable_if_any_slices<Args...>>
NDARRAY_HOST_DEVICE auto operator[] (const std::tuple< Args... > &args) const
 
+template<class... Args, class = enable_if_any_slices<Args...>>
NDARRAY_HOST_DEVICE auto operator() (Args...args) const
 
template<size_t D, class = enable_if_dim<D>>
NDARRAY_HOST_DEVICE auto & dim ()
 
+template<size_t D, class = enable_if_dim<D>>
NDARRAY_HOST_DEVICE const auto & dim () const
 
NDARRAY_HOST_DEVICE const nda::dim dim (size_t d) const
 
NDARRAY_HOST_DEVICE dims_typedims ()
 
+NDARRAY_HOST_DEVICE const dims_typedims () const
 
+NDARRAY_HOST_DEVICE index_type min () const
 
+NDARRAY_HOST_DEVICE index_type max () const
 
+NDARRAY_HOST_DEVICE index_type extent () const
 
+NDARRAY_HOST_DEVICE index_type stride () const
 
NDARRAY_HOST_DEVICE index_t flat_min () const
 
+NDARRAY_HOST_DEVICE index_t flat_max () const
 
+NDARRAY_HOST_DEVICE size_type flat_extent () const
 
NDARRAY_HOST_DEVICE size_type size () const
 
NDARRAY_HOST_DEVICE bool empty () const
 
NDARRAY_HOST_DEVICE bool is_compact () const
 
NDARRAY_HOST_DEVICE bool is_one_to_one () const
 
template<typename OtherShape >
NDARRAY_HOST_DEVICE bool is_subset_of (const OtherShape &other, index_t offset) const
 
NDARRAY_HOST_DEVICE auto & i ()
 
+NDARRAY_HOST_DEVICE const auto & i () const
 
+NDARRAY_HOST_DEVICE auto & j ()
 
+NDARRAY_HOST_DEVICE const auto & j () const
 
+NDARRAY_HOST_DEVICE auto & k ()
 
+NDARRAY_HOST_DEVICE const auto & k () const
 
NDARRAY_HOST_DEVICE auto & x ()
 
+NDARRAY_HOST_DEVICE const auto & x () const
 
+NDARRAY_HOST_DEVICE auto & y ()
 
+NDARRAY_HOST_DEVICE const auto & y () const
 
+NDARRAY_HOST_DEVICE auto & z ()
 
+NDARRAY_HOST_DEVICE const auto & z () const
 
+NDARRAY_HOST_DEVICE auto & c ()
 
+NDARRAY_HOST_DEVICE const auto & c () const
 
+NDARRAY_HOST_DEVICE auto & w ()
 
+NDARRAY_HOST_DEVICE const auto & w () const
 
NDARRAY_HOST_DEVICE index_t width () const
 
+NDARRAY_HOST_DEVICE index_t height () const
 
+NDARRAY_HOST_DEVICE index_t channels () const
 
NDARRAY_HOST_DEVICE index_t rows () const
 
+NDARRAY_HOST_DEVICE index_t columns () const
 
template<class... OtherDims, class = enable_if_same_rank<OtherDims...>>
NDARRAY_HOST_DEVICE bool operator== (const shape< OtherDims... > &other) const
 
+template<class... OtherDims, class = enable_if_same_rank<OtherDims...>>
NDARRAY_HOST_DEVICE bool operator!= (const shape< OtherDims... > &other) const
 
+ + + + + +

+Static Public Member Functions

static constexpr size_t rank ()
 
static constexpr bool is_scalar ()
 
+

Detailed Description

+

template<class... Dims>
+class nda::shape< Dims >

+ +

A list of Dim objects describing a multi-dimensional space of indices. The rank of a shape refers to the number of dimensions in the shape. The first dimension is known as the 'innermost' dimension, and dimensions then increase until the 'outermost' dimension.

+

Shapes map a multi-dimensional index x to a flat offset by sum(dim<i>().flat_offset(std::get<i>(x))) for i in [0, Rank).

+

Member Typedef Documentation

+ +
+
+ + + + +
using dims_type = std::tuple<Dims...>
+
+

The type of the dims tuple of this shape.

+ +
+
+ +
+
+ + + + +
using index_type = index_of_rank<rank()>
+
+

The type of an index for this shape.

+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_HOST_DEVICE shape (const std::tuple< OtherDims... > & other)
+
+inline
+
+

Construct or assign a shape from another set of dims of a possibly different type. Each dim must be compatible with the corresponding dim of this shape.

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
static constexpr size_t rank ()
+
+inlinestatic
+
+

Number of dims in this shape.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
static constexpr bool is_scalar ()
+
+inlinestatic
+
+

A shape is scalar if its rank is 0.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE void resolve ()
+
+inline
+
+

Replace strides with automatically determined values.

+

An automatic stride for a dimension is determined by taking the minimum of all possible candidate strides, which are the product of the stride and extent of all dimensions with a known stride. This is repeated for each dimension, starting with the innermost dimension.

+

Examples:

    +
  • {{0, 5}, {0, 10}} -> {{0, 5, 1}, {0, 10, 5}}
  • +
  • {{0, 5}, {0, 10}, {0, 3, 1}} -> {{0, 5, 3}, {0, 10, 15}, {0, 3, 1}}
  • +
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE bool is_resolved () const
+
+inline
+
+

Check if all strides of the shape are known.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_HOST_DEVICE bool is_in_range (const std::tuple< Args... > & args) const
+
+inline
+
+

Returns true if the indices or intervals args are in interval of this shape.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_HOST_DEVICE index_t operator[] (const index_typeindices) const
+
+inline
+
+

Compute the flat offset of the index indices.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_HOST_DEVICE auto operator[] (const std::tuple< Args... > & args) const
+
+inline
+
+

Create a new shape from this shape using a indices or intervals args. Dimensions corresponding to indices in args are sliced, i.e. the result will not have this dimension. The rest of the dimensions are cropped.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE auto& dim ()
+
+inline
+
+

Get a specific dim D of this shape.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_HOST_DEVICE const nda::dim dim (size_t d) const
+
+inline
+
+

Get a specific dim of this shape with a runtime dimension index d. This will lose knowledge of any compile-time constant dimension attributes, and it is not a reference to the original dimension.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE dims_type& dims ()
+
+inline
+
+

Get a tuple of all of the dims of this shape.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE index_t flat_min () const
+
+inline
+
+

Compute the min, max, or extent of the flat offsets of this shape. This is the min, max, or extent of the valid interval of values returned by operator() or operator[].

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE size_type size () const
+
+inline
+
+

Compute the total number of indices in this shape.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE bool empty () const
+
+inline
+
+

A shape is empty if its size is 0.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE bool is_compact () const
+
+inline
+
+

Returns true if this shape is 'compact' in memory. A shape is compact if there are no unaddressable flat indices between the first and last addressable flat elements.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE bool is_one_to_one () const
+
+inline
+
+

Returns true if this shape is an injective function mapping indices to flat indices. If the dims overlap, or a dim has stride zero, multiple indices will map to the same flat index; in this case, this function will return false.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
NDARRAY_HOST_DEVICE bool is_subset_of (const OtherShape & other,
index_t offset 
) const
+
+inline
+
+

Returns true if this shape projects to a set of flat indices that is a subset of the other shape's projection to flat indices, with an offset offset.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE auto& i ()
+
+inline
+
+

Provide some aliases for common interpretations of dimensions i, j, k as dimensions 0, 1, 2, respectively.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE auto& x ()
+
+inline
+
+

Provide some aliases for common interpretations of dimensions x, y, z or c, w as dimensions 0, 1, 2, 3 respectively.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE index_t width () const
+
+inline
+
+

Assuming this array represents an image with dimensions {width, height, channels}, get the extent of those dimensions.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
NDARRAY_HOST_DEVICE index_t rows () const
+
+inline
+
+

Assuming this array represents a matrix with dimensions {rows, cols}, get the extent of those dimensions.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
NDARRAY_HOST_DEVICE bool operator== (const shape< OtherDims... > & other) const
+
+inline
+
+

A shape is equal to another shape if the dim objects of each dimension from both shapes are equal.

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/classnda_1_1shape__traits-members.html b/classnda_1_1shape__traits-members.html new file mode 100644 index 00000000..24330692 --- /dev/null +++ b/classnda_1_1shape__traits-members.html @@ -0,0 +1,110 @@ + + + + + + +array: Member List + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
shape_traits< Shape > Member List
+
+
+ +

This is the complete list of members for shape_traits< Shape >, including all inherited members.

+ + + + +
for_each_index(const Shape &shape, Fn &&fn)shape_traits< Shape >inlinestatic
for_each_value(const Shape &shape, Ptr base, Fn &&fn)shape_traits< Shape >inlinestatic
shape_type typedef (defined in shape_traits< Shape >)shape_traits< Shape >
+ + + + diff --git a/classnda_1_1shape__traits.html b/classnda_1_1shape__traits.html new file mode 100644 index 00000000..8358b938 --- /dev/null +++ b/classnda_1_1shape__traits.html @@ -0,0 +1,211 @@ + + + + + + +array: shape_traits< Shape > Class Template Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
shape_traits< Shape > Class Template Reference
+
+
+ +

#include <array.h>

+ + + + +

+Public Types

+using shape_type = Shape
 
+ + + + + + + +

+Static Public Member Functions

template<class Fn >
static NDARRAY_HOST_DEVICE void for_each_index (const Shape &shape, Fn &&fn)
 
template<class Ptr , class Fn >
static NDARRAY_HOST_DEVICE void for_each_value (const Shape &shape, Ptr base, Fn &&fn)
 
+

Detailed Description

+

template<class Shape>
+class nda::shape_traits< Shape >

+ +

Shape traits enable some behaviors to be customized per shape type.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static NDARRAY_HOST_DEVICE void for_each_index (const Shape & shape,
Fn && fn 
)
+
+inlinestatic
+
+

The for_each_index implementation for the shape may choose to iterate in a different order than the default (in-order).

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static NDARRAY_HOST_DEVICE void for_each_value (const Shape & shape,
Ptr base,
Fn && fn 
)
+
+inlinestatic
+
+

The for_each_value implementation for the shape may be able to statically optimize shape. The default implementation optimizes the shape at runtime, and only attempts to convert the shape to a dense_shape.

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_00_01_x_stride_01_4_01_4-members.html b/classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_00_01_x_stride_01_4_01_4-members.html new file mode 100644 index 00000000..048da7e4 --- /dev/null +++ b/classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_00_01_x_stride_01_4_01_4-members.html @@ -0,0 +1,110 @@ + + + + + + +array: Member List + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
shape_traits< chunky_image_shape< Channels, XStride > > Member List
+
+
+ +

This is the complete list of members for shape_traits< chunky_image_shape< Channels, XStride > >, including all inherited members.

+ + + + +
for_each_index(const shape_type &s, Fn &&fn) (defined in shape_traits< chunky_image_shape< Channels, XStride > >)shape_traits< chunky_image_shape< Channels, XStride > >inlinestatic
for_each_value(const shape_type &s, Ptr base, Fn &&fn) (defined in shape_traits< chunky_image_shape< Channels, XStride > >)shape_traits< chunky_image_shape< Channels, XStride > >inlinestatic
shape_type typedef (defined in shape_traits< chunky_image_shape< Channels, XStride > >)shape_traits< chunky_image_shape< Channels, XStride > >
+ + + + diff --git a/classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_00_01_x_stride_01_4_01_4.html b/classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_00_01_x_stride_01_4_01_4.html new file mode 100644 index 00000000..493be4a8 --- /dev/null +++ b/classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_00_01_x_stride_01_4_01_4.html @@ -0,0 +1,129 @@ + + + + + + +array: shape_traits< chunky_image_shape< Channels, XStride > > Class Template Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
shape_traits< chunky_image_shape< Channels, XStride > > Class Template Reference
+
+
+ + + + +

+Public Types

+typedef chunky_image_shape< Channels, XStride > shape_type
 
+ + + + + + + +

+Static Public Member Functions

+template<class Fn >
static void for_each_index (const shape_type &s, Fn &&fn)
 
+template<class Ptr , class Fn >
static void for_each_value (const shape_type &s, Ptr base, Fn &&fn)
 
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_01_4_01_4-members.html b/classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_01_4_01_4-members.html new file mode 100644 index 00000000..4bc9832e --- /dev/null +++ b/classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_01_4_01_4-members.html @@ -0,0 +1,110 @@ + + + + + + +array: Member List + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
shape_traits< chunky_image_shape< Channels > > Member List
+
+
+ +

This is the complete list of members for shape_traits< chunky_image_shape< Channels > >, including all inherited members.

+ + + + +
for_each_index(const shape_type &s, Fn &&fn) (defined in shape_traits< chunky_image_shape< Channels > >)shape_traits< chunky_image_shape< Channels > >inlinestatic
for_each_value(const shape_type &s, Ptr base, Fn &&fn) (defined in shape_traits< chunky_image_shape< Channels > >)shape_traits< chunky_image_shape< Channels > >inlinestatic
shape_type typedef (defined in shape_traits< chunky_image_shape< Channels > >)shape_traits< chunky_image_shape< Channels > >
+ + + + diff --git a/classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_01_4_01_4.html b/classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_01_4_01_4.html new file mode 100644 index 00000000..63fa1fb7 --- /dev/null +++ b/classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_01_4_01_4.html @@ -0,0 +1,129 @@ + + + + + + +array: shape_traits< chunky_image_shape< Channels > > Class Template Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
shape_traits< chunky_image_shape< Channels > > Class Template Reference
+
+
+ + + + +

+Public Types

+typedef chunky_image_shape< Channels > shape_type
 
+ + + + + + + +

+Static Public Member Functions

+template<class Fn >
static void for_each_index (const shape_type &s, Fn &&fn)
 
+template<class Ptr , class Fn >
static void for_each_value (const shape_type &s, Ptr base, Fn &&fn)
 
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/classnda_1_1shape__traits_3_01matrix__shape_3_01_rows_00_01_cols_01_4_01_4-members.html b/classnda_1_1shape__traits_3_01matrix__shape_3_01_rows_00_01_cols_01_4_01_4-members.html new file mode 100644 index 00000000..9c87fded --- /dev/null +++ b/classnda_1_1shape__traits_3_01matrix__shape_3_01_rows_00_01_cols_01_4_01_4-members.html @@ -0,0 +1,110 @@ + + + + + + +array: Member List + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
shape_traits< matrix_shape< Rows, Cols > > Member List
+
+
+ +

This is the complete list of members for shape_traits< matrix_shape< Rows, Cols > >, including all inherited members.

+ + + + +
for_each_index(const shape_type &s, Fn &&fn) (defined in shape_traits< matrix_shape< Rows, Cols > >)shape_traits< matrix_shape< Rows, Cols > >inlinestatic
for_each_value(const shape_type &s, Ptr base, Fn &&fn) (defined in shape_traits< matrix_shape< Rows, Cols > >)shape_traits< matrix_shape< Rows, Cols > >inlinestatic
shape_type typedef (defined in shape_traits< matrix_shape< Rows, Cols > >)shape_traits< matrix_shape< Rows, Cols > >
+ + + + diff --git a/classnda_1_1shape__traits_3_01matrix__shape_3_01_rows_00_01_cols_01_4_01_4.html b/classnda_1_1shape__traits_3_01matrix__shape_3_01_rows_00_01_cols_01_4_01_4.html new file mode 100644 index 00000000..dcda9b9b --- /dev/null +++ b/classnda_1_1shape__traits_3_01matrix__shape_3_01_rows_00_01_cols_01_4_01_4.html @@ -0,0 +1,129 @@ + + + + + + +array: shape_traits< matrix_shape< Rows, Cols > > Class Template Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
shape_traits< matrix_shape< Rows, Cols > > Class Template Reference
+
+
+ + + + +

+Public Types

+typedef matrix_shape< Rows, Cols > shape_type
 
+ + + + + + + +

+Static Public Member Functions

+template<class Fn >
static void for_each_index (const shape_type &s, Fn &&fn)
 
+template<class Ptr , class Fn >
static void for_each_value (const shape_type &s, Ptr base, Fn &&fn)
 
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/classnda_1_1uninitialized__allocator-members.html b/classnda_1_1uninitialized__allocator-members.html new file mode 100644 index 00000000..8ec5df0f --- /dev/null +++ b/classnda_1_1uninitialized__allocator-members.html @@ -0,0 +1,117 @@ + + + + + + +array: Member List + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
uninitialized_allocator< BaseAlloc > Member List
+
+
+ +

This is the complete list of members for uninitialized_allocator< BaseAlloc >, including all inherited members.

+ + + + + + + + + + + +
allocate(size_t n) (defined in uninitialized_allocator< BaseAlloc >)uninitialized_allocator< BaseAlloc >inline
construct(value_type *ptr, Args &&...args) (defined in uninitialized_allocator< BaseAlloc >)uninitialized_allocator< BaseAlloc >inline
deallocate(value_type *p, size_t n) noexcept (defined in uninitialized_allocator< BaseAlloc >)uninitialized_allocator< BaseAlloc >inline
operator!= (defined in uninitialized_allocator< BaseAlloc >)uninitialized_allocator< BaseAlloc >friend
operator== (defined in uninitialized_allocator< BaseAlloc >)uninitialized_allocator< BaseAlloc >friend
propagate_on_container_copy_assignment typedef (defined in uninitialized_allocator< BaseAlloc >)uninitialized_allocator< BaseAlloc >
propagate_on_container_move_assignment typedef (defined in uninitialized_allocator< BaseAlloc >)uninitialized_allocator< BaseAlloc >
propagate_on_container_swap typedef (defined in uninitialized_allocator< BaseAlloc >)uninitialized_allocator< BaseAlloc >
select_on_container_copy_construction(const uninitialized_allocator &alloc) (defined in uninitialized_allocator< BaseAlloc >)uninitialized_allocator< BaseAlloc >inlinestatic
value_type typedef (defined in uninitialized_allocator< BaseAlloc >)uninitialized_allocator< BaseAlloc >
+ + + + diff --git a/classnda_1_1uninitialized__allocator.html b/classnda_1_1uninitialized__allocator.html new file mode 100644 index 00000000..18d4fc47 --- /dev/null +++ b/classnda_1_1uninitialized__allocator.html @@ -0,0 +1,174 @@ + + + + + + +array: uninitialized_allocator< BaseAlloc > Class Template Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
uninitialized_allocator< BaseAlloc > Class Template Reference
+
+
+ +

#include <array.h>

+
+Inheritance diagram for uninitialized_allocator< BaseAlloc >:
+
+
+ + + +
+ + + + + + + + + + +

+Public Types

+using value_type = typename std::allocator_traits< BaseAlloc >::value_type
 
+using propagate_on_container_copy_assignment = typename std::allocator_traits< BaseAlloc >::propagate_on_container_copy_assignment
 
+using propagate_on_container_move_assignment = typename std::allocator_traits< BaseAlloc >::propagate_on_container_move_assignment
 
+using propagate_on_container_swap = typename std::allocator_traits< BaseAlloc >::propagate_on_container_swap
 
+ + + + + + + + +

+Public Member Functions

+value_type * allocate (size_t n)
 
+void deallocate (value_type *p, size_t n) noexcept
 
+template<class... Args>
NDARRAY_INLINE void construct (value_type *ptr, Args &&...args)
 
+ + + +

+Static Public Member Functions

+static uninitialized_allocator select_on_container_copy_construction (const uninitialized_allocator &alloc)
 
+ + + + + + + +

+Friends

+template<class OtherBaseAlloc >
bool operator== (const uninitialized_allocator &a, const uninitialized_allocator< OtherBaseAlloc > &b)
 
+template<class OtherBaseAlloc >
bool operator!= (const uninitialized_allocator &a, const uninitialized_allocator< OtherBaseAlloc > &b)
 
+

Detailed Description

+

template<class BaseAlloc>
+class nda::uninitialized_allocator< BaseAlloc >

+ +

Allocator satisfying the std::allocator interface that is a wrapper around another allocator BaseAlloc, and skips default construction. Using this allocator can be dangerous, it is only safe to use when BaseAlloc::value_type is a trivial type.

+

The documentation for this class was generated from the following file: +
+ + + + diff --git a/classnda_1_1uninitialized__allocator.png b/classnda_1_1uninitialized__allocator.png new file mode 100644 index 0000000000000000000000000000000000000000..2fd1095247787811da22c6593c28be7baa5cdcb0 GIT binary patch literal 655 zcmeAS@N?(olHy`uVBq!ia0vp^*MT^IgBeKf6%%+4q$C1-LR|m<{|{uoc=NTi|Ih>= z3ycpOIKbL@M;^%KC<*clW&kPzfvcxNj2IZ0Oc6k2!qHWn*uejr)tK_^c{SPnl43bfuu5vUG#LzvH znzn5o!#^+c2G*?_*WYeayRj&ye2wbCu&1Z0I0QUTvI@8pk3V?NoT;n9lVGVT?jQrg za|^Cc|Gs;z>3N3UwsQ5d;M?mgn9pqG-5c?1afPXv`m^xDy)yUBe+yn;T-2qD z`{uKgtN(m!KfCko{X@4yyKh}R{o>l8(C~Hqvf;Z;9^5_<`sv)=t4rr>z7_7fDCvsX z+i$y*<7VD_Q*H1r{Co3Rqs*%+spQ}H?9| zp5OR>(c@2LcaOKL-U`@W8S$v{z_fpJR;L~4-+4^s)v|pj56|3uykcvm#TmBZx9uN` z_SGN1s&XR#-1QA}KYuPg_w`lHTi4uEp|2k%eqJYcZEIWAj;l9=_!+OC`gyB+!~DC2 ze>cc6=`4A@W8S)XzxW=kpZbxhWAPIxJ|2JROpfJW=C^*$VNExU<^xj?gQu&X%Q~lo FCIC)fMF{`^ literal 0 HcmV?d00001 diff --git a/closed.png b/closed.png new file mode 100644 index 0000000000000000000000000000000000000000..98cc2c909da37a6df914fbf67780eebd99c597f5 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{V-kvUwAr*{o@8{^CZMh(5KoB^r_<4^zF@3)Cp&&t3hdujKf f*?bjBoY!V+E))@{xMcbjXe@)LtDnm{r-UW|*e5JT literal 0 HcmV?d00001 diff --git a/dir_1db1952525b7159ee5ea1c5d1ec74f56.html b/dir_1db1952525b7159ee5ea1c5d1ec74f56.html new file mode 100644 index 00000000..d75fc2af --- /dev/null +++ b/dir_1db1952525b7159ee5ea1c5d1ec74f56.html @@ -0,0 +1,105 @@ + + + + + + +array: absl Directory Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
absl Directory Reference
+
+
+ + +

+Files

+
+ + + + diff --git a/dir_717b3188b45e89f652d81ea10aa11b1d.html b/dir_717b3188b45e89f652d81ea10aa11b1d.html new file mode 100644 index 00000000..e24d39e7 --- /dev/null +++ b/dir_717b3188b45e89f652d81ea10aa11b1d.html @@ -0,0 +1,120 @@ + + + + + + +array: include/array Directory Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
array Directory Reference
+
+
+ + + + + + + + + + + + + + + + + +

+Files

file  array.h [code]
 Main header for array library.
 
file  ein_reduce.h [code]
 Optional helper for computing Einstein reductions on arrays.
 
file  image.h [code]
 Optional image-specific helpers and specializations.
 
file  matrix.h [code]
 Optional matrix-specific helpers and specializations.
 
file  z_order.h [code]
 Helpers for traversing multi-dimensional ranges in z-order.
 
+
+ + + + diff --git a/dir_d44c64559bbebec7f509842c48db8b23.html b/dir_d44c64559bbebec7f509842c48db8b23.html new file mode 100644 index 00000000..3bfcf96d --- /dev/null +++ b/dir_d44c64559bbebec7f509842c48db8b23.html @@ -0,0 +1,105 @@ + + + + + + +array: include Directory Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
include Directory Reference
+
+
+ + +

+Directories

+
+ + + + diff --git a/doc.png b/doc.png new file mode 100644 index 0000000000000000000000000000000000000000..17edabff95f7b8da13c9516a04efe05493c29501 GIT binary patch literal 746 zcmV7=@pnbNXRFEm&G8P!&WHG=d)>K?YZ1bzou)2{$)) zumDct!>4SyxL;zgaG>wy`^Hv*+}0kUfCrz~BCOViSb$_*&;{TGGn2^x9K*!Sf0=lV zpP=7O;GA0*Jm*tTYj$IoXvimpnV4S1Z5f$p*f$Db2iq2zrVGQUz~yq`ahn7ck(|CE z7Gz;%OP~J6)tEZWDzjhL9h2hdfoU2)Nd%T<5Kt;Y0XLt&<@6pQx!nw*5`@bq#?l*?3z{Hlzoc=Pr>oB5(9i6~_&-}A(4{Q$>c>%rV&E|a(r&;?i5cQB=} zYSDU5nXG)NS4HEs0it2AHe2>shCyr7`6@4*6{r@8fXRbTA?=IFVWAQJL&H5H{)DpM#{W(GL+Idzf^)uRV@oB8u$ z8v{MfJbTiiRg4bza<41NAzrl{=3fl_D+$t+^!xlQ8S}{UtY`e z;;&9UhyZqQRN%2pot{*Ei0*4~hSF_3AH2@fKU!$NSflS>{@tZpDT4`M2WRTTVH+D? z)GFlEGGHe?koB}i|1w45!BF}N_q&^HJ&-tyR{(afC6H7|aml|tBBbv}55C5DNP8p3 z)~jLEO4Z&2hZmP^i-e%(@d!(E|KRafiU8Q5u(wU((j8un3OR*Hvj+t literal 0 HcmV?d00001 diff --git a/doxygen-awesome.css b/doxygen-awesome.css new file mode 100644 index 00000000..23ddb59a --- /dev/null +++ b/doxygen-awesome.css @@ -0,0 +1,1454 @@ +/** + +Doxygen Awesome +https://github.com/jothepro/doxygen-awesome-css + +MIT License + +Copyright (c) 2021 jothepro + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +html { + /* primary theme color. This will affect the entire websites color scheme: links, arrows, labels, ... */ + --primary-color: #1779c4; + --primary-dark-color: #00559f; + --primary-light-color: #7aabd6; + --primary-lighter-color: #cae1f1; + --primary-lightest-color: #e9f1f8; + + /* page base colors */ + --page-background-color: white; + --page-foreground-color: #2c3e50; + --page-secondary-foreground-color: #67727e; + + /* color for all separators on the website: hr, borders, ... */ + --separator-color: #dedede; + + /* border radius for all rounded components. Will affect many components, like dropdowns, memitems, codeblocks, ... */ + --border-radius-large: 8px; + --border-radius-small: 4px; + --border-radius-medium: 6px; + + /* default spacings. Most compontest reference these values for spacing, to provide uniform spacing on the page. */ + --spacing-small: 5px; + --spacing-medium: 10px; + --spacing-large: 16px; + + /* default box shadow used for raising an element above the normal content. Used in dropdowns, Searchresult, ... */ + --box-shadow: 0 2px 10px 0 rgba(0,0,0,.1); + + --odd-color: rgba(0,0,0,.03); + + /* font-families. will affect all text on the website + * font-family: the normal font for text, headlines, menus + * font-family-monospace: used for preformatted text in memtitle, code, fragments + */ + --font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif; + --font-family-monospace: source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace; + + /* font sizes */ + --page-font-size: 15.6px; + --navigation-font-size: 14.4px; + --code-font-size: 14.4px; /* affects code, fragment */ + --title-font-size: 22px; + + /* content text properties. These only affect the page content, not the navigation or any other ui elements */ + --content-line-height: 27px; + /* The content is centered and constraint in it's width. To make the content fill the whole page, set the variable to auto.*/ + --content-maxwidth: 900px; + + /* colors for various content boxes: @warning, @note, @deprecated @bug */ + --warning-color: #fca49b; + --warning-color-dark: #b61825; + --warning-color-darker: #75070f; + --note-color: rgba(255,229,100,.3); + --note-color-dark: #c39900; + --note-color-darker: #8d7400; + --deprecated-color: rgb(214, 216, 224); + --deprecated-color-dark: #5b6269; + --deprecated-color-darker: #43454a; + --bug-color: rgb(246, 208, 178); + --bug-color-dark: #a53a00; + --bug-color-darker: #5b1d00; + --invariant-color: #b7f8d0; + --invariant-color-dark: #00ba44; + --invariant-color-darker: #008622; + + /* blockquote colors */ + --blockquote-background: #f5f5f5; + --blockquote-foreground: #727272; + + /* table colors */ + --tablehead-background: #f1f1f1; + --tablehead-foreground: var(--page-foreground-color); + + /* menu-display: block | none + * Visibility of the top navigation on screens >= 768px. On smaller screen the menu is always visible. + * `GENERATE_TREEVIEW` MUST be enabled! + */ + --menu-display: block; + + --menu-focus-foreground: var(--page-background-color); + --menu-focus-background: var(--primary-color); + --menu-selected-background: rgba(0,0,0,.05); + + + --header-background: var(--page-background-color); + --header-foreground: var(--page-foreground-color); + + /* searchbar colors */ + --searchbar-background: var(--side-nav-background); + --searchbar-foreground: var(--page-foreground-color); + + /* searchbar size + * (`searchbar-width` is only applied on screens >= 768px. + * on smaller screens the searchbar will always fill the entire screen width) */ + --searchbar-height: 33px; + --searchbar-width: 210px; + + /* code block colors */ + --code-background: #f5f5f5; + --code-foreground: var(--page-foreground-color); + + /* fragment colors */ + --fragment-background: #282c34; + --fragment-foreground: #ffffff; + --fragment-keyword: #cc99cd; + --fragment-keywordtype: #ab99cd; + --fragment-keywordflow: #e08000; + --fragment-token: #7ec699; + --fragment-comment: #999999; + --fragment-link: #98c0e3; + --fragment-preprocessor: #65cabe; + --fragment-linenumber-color: #cccccc; + --fragment-linenumber-background: #35393c; + --fragment-linenumber-border: #1f1f1f; + --fragment-lineheight: 20px; + + /* sidebar navigation (treeview) colors */ + --side-nav-background: #fbfbfb; + --side-nav-foreground: var(--page-foreground-color); + --side-nav-arrow-opacity: 0; + --side-nav-arrow-hover-opacity: 0.9; + + /* height of an item in any tree / collapsable table */ + --tree-item-height: 30px; + + --darkmode-toggle-button-icon: '☀️' +} + +@media screen and (max-width: 767px) { + html { + --page-font-size: 16px; + --navigation-font-size: 16px; + --code-font-size: 15px; /* affects code, fragment */ + --title-font-size: 22px; + } +} + +@media (prefers-color-scheme: dark) { + html:not(.light-mode) { + --primary-color: #1982d2; + --primary-dark-color: #5ca8e2; + --primary-light-color: #4779ac; + --primary-lighter-color: #191e21; + --primary-lightest-color: #191a1c; + + --box-shadow: 0 2px 10px 0 rgba(0,0,0,.35); + + --odd-color: rgba(0,0,0,.1); + + --menu-selected-background: rgba(0,0,0,.4); + + --page-background-color: #1C1D1F; + --page-foreground-color: #d2dbde; + --page-secondary-foreground-color: #859399; + --separator-color: #000000; + --side-nav-background: #252628; + + --code-background: #2a2c2f; + + --tablehead-background: #2a2c2f; + + --blockquote-background: #1f2022; + --blockquote-foreground: #77848a; + + --warning-color: #b61825; + --warning-color-dark: #510a02; + --warning-color-darker: #f5b1aa; + --note-color: rgb(255, 183, 0); + --note-color-dark: #9f7300; + --note-color-darker: #fff6df; + --deprecated-color: rgb(88, 90, 96); + --deprecated-color-dark: #262e37; + --deprecated-color-darker: #a0a5b0; + --bug-color: rgb(248, 113, 0); + --bug-color-dark: #812a00; + --bug-color-darker: #ffd3be; + + --darkmode-toggle-button-icon: '🌛'; + } +} + +/* dark mode variables are defined twice, to support both the dark-mode without and with doxygen-awesome-darkmode-toggle.js */ +html.dark-mode { + --primary-color: #1982d2; + --primary-dark-color: #5ca8e2; + --primary-light-color: #4779ac; + --primary-lighter-color: #191e21; + --primary-lightest-color: #191a1c; + + --box-shadow: 0 2px 10px 0 rgba(0,0,0,.35); + + --odd-color: rgba(0,0,0,.1); + + --menu-selected-background: rgba(0,0,0,.4); + + --page-background-color: #1C1D1F; + --page-foreground-color: #d2dbde; + --page-secondary-foreground-color: #859399; + --separator-color: #000000; + --side-nav-background: #252628; + + --code-background: #2a2c2f; + + --tablehead-background: #2a2c2f; + + --blockquote-background: #1f2022; + --blockquote-foreground: #77848a; + + --warning-color: #b61825; + --warning-color-dark: #510a02; + --warning-color-darker: #f5b1aa; + --note-color: rgb(255, 183, 0); + --note-color-dark: #9f7300; + --note-color-darker: #fff6df; + --deprecated-color: rgb(88, 90, 96); + --deprecated-color-dark: #262e37; + --deprecated-color-darker: #a0a5b0; + --bug-color: rgb(248, 113, 0); + --bug-color-dark: #812a00; + --bug-color-darker: #ffd3be; + + --darkmode-toggle-button-icon: '🌛'; +} + +body { + color: var(--page-foreground-color); + background-color: var(--page-background-color); + font-size: var(--page-font-size); +} + +body, table, div, p, dl, #nav-tree .label, .title, .sm-dox a, .sm-dox a:hover, .sm-dox a:focus, #projectname, .SelectItem, #MSearchField, .navpath li.navelem a, .navpath li.navelem a:hover { + font-family: var(--font-family); +} + +h1, h2, h3, h4, h5 { + margin-top: .9em; + font-weight: 600; + line-height: initial; +} + +p, div, table, dl { + font-size: var(--page-font-size); +} + +a:link, a:visited, a:hover, a:focus, a:active { + color: var(--primary-color) !important; + font-weight: 500; +} + +/* + Title and top navigation + */ + +#top { + background: var(--header-background); + border-bottom: 1px solid var(--separator-color); +} + +@media screen and (min-width: 768px) { + #top { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-items: center; + } +} + +#main-nav { + flex-grow: 5; + padding: var(--spacing-small) var(--spacing-medium); +} + +#titlearea { + width: auto; + padding: var(--spacing-medium) var(--spacing-large); + background: none; + color: var(--header-foreground); + border-bottom: none; +} + +@media screen and (max-width: 767px) { + #titlearea { + padding-bottom: var(--spacing-small); + } +} + +#titlearea table tbody tr { + height: auto !important; +} + +#projectname { + font-size: var(--title-font-size); + font-weight: 600; +} + +#projectnumber { + font-family: inherit; + font-size: 60%; +} + +#projectbrief { + font-family: inherit; + font-size: 80%; +} + +#projectlogo { + vertical-align: middle; +} + +#projectlogo img { + max-height: calc(var(--title-font-size) * 2); + margin-right: var(--spacing-small); +} + +.sm-dox, .tabs, .tabs2, .tabs3 { + background: none; + padding: 0; +} + +.tabs, .tabs2, .tabs3 { + border-bottom: 1px solid var(--separator-color); + margin-bottom: -1px; +} + +@media screen and (max-width: 767px) { + .sm-dox a span.sub-arrow { + background: var(--code-background); + } +} + +@media screen and (min-width: 768px) { + .sm-dox li, .tablist li { + display: var(--menu-display); + } + + .sm-dox a span.sub-arrow { + border-color: var(--header-foreground) transparent transparent transparent; + } + + .sm-dox a:hover span.sub-arrow { + border-color: var(--menu-focus-foreground) transparent transparent transparent; + } + + .sm-dox ul a span.sub-arrow { + border-color: transparent transparent transparent var(--page-foreground-color); + } + + .sm-dox ul a:hover span.sub-arrow { + border-color: transparent transparent transparent var(--menu-focus-foreground); + } +} + +.sm-dox ul { + background: var(--page-background-color); + box-shadow: var(--box-shadow); + border: 1px solid var(--separator-color); + border-radius: var(--border-radius-medium) !important; + padding: var(--spacing-small); + animation: ease-out 150ms slideInMenu; +} + +@keyframes slideInMenu { + from { + opacity: 0; + transform: translate(0px, -2px); + } + + to { + opacity: 1; + transform: translate(0px, 0px); + } +} + +.sm-dox ul a { + color: var(--page-foreground-color) !important; + background: var(--page-background-color); + font-size: var(--navigation-font-size); +} + +.sm-dox>li>ul:after { + border-bottom-color: var(--page-background-color) !important; +} + +.sm-dox>li>ul:before { + border-bottom-color: var(--separator-color) !important; +} + +.sm-dox ul a:hover, .sm-dox ul a:active, .sm-dox ul a:focus { + font-size: var(--navigation-font-size) !important; + color: var(--menu-focus-foreground) !important; + text-shadow: none; + background-color: var(--menu-focus-background); + border-radius: var(--border-radius-small) !important; +} + +.sm-dox a, .sm-dox a:focus, .tablist li, .tablist li a, .tablist li.current a { + text-shadow: none; + background: transparent; + background-image: none !important; + color: var(--header-foreground) !important; + font-weight: normal; + font-size: var(--navigation-font-size); +} + +.sm-dox a:focus { + outline: auto; +} + +.sm-dox a:hover, .sm-dox a:active, .tablist li a:hover { + text-shadow: none; + font-weight: normal; + background: var(--menu-focus-background); + color: var(--menu-focus-foreground) !important; + border-radius: var(--border-radius-small) !important; + font-size: var(--navigation-font-size); +} + +.tablist li.current { + border-radius: var(--border-radius-small); + background: var(--menu-selected-background); +} + +.tablist li { + margin: var(--spacing-small) 0 var(--spacing-small) var(--spacing-small); +} + +.tablist a { + padding: 0 var(--spacing-large); +} + + +/* + Search box + */ + +#MSearchBox { + height: var(--searchbar-height); + background: var(--searchbar-background); + border-radius: var(--searchbar-height); + border: 1px solid var(--separator-color); + overflow: hidden; + width: var(--searchbar-width); + position: relative; + box-shadow: none; + display: block; + margin-top: 0; +} + +.left #MSearchSelect { + left: 0; +} + +.tabs .left #MSearchSelect { + padding-left: 0; +} + +.tabs #MSearchBox { + position: absolute; + right: var(--spacing-medium); +} + +@media screen and (max-width: 767px) { + .tabs #MSearchBox { + position: relative; + right: 0; + margin-left: var(--spacing-medium); + margin-top: 0; + } +} + +#MSearchSelectWindow, #MSearchResultsWindow { + z-index: 9999; +} + +#MSearchBox.MSearchBoxActive { + border-color: var(--primary-color); + box-shadow: inset 0 0 0 1px var(--primary-color); +} + +#main-menu > li:last-child { + margin-right: 0; +} + +@media screen and (max-width: 767px) { + #main-menu > li:last-child { + height: 50px; + } +} + +#MSearchField { + font-size: var(--navigation-font-size); + height: calc(var(--searchbar-height) - 2px); + background: transparent; + width: calc(var(--searchbar-width) - 64px); +} + +.MSearchBoxActive #MSearchField { + color: var(--searchbar-foreground); +} + +#MSearchSelect { + top: calc(calc(var(--searchbar-height) / 2) - 11px); +} + +.left #MSearchSelect { + padding-left: 8px; +} + +#MSearchBox span.left, #MSearchBox span.right { + background: none; +} + +#MSearchBox span.right { + padding-top: calc(calc(var(--searchbar-height) / 2) - 12px); + position: absolute; + right: var(--spacing-small); +} + +.tabs #MSearchBox span.right { + top: calc(calc(var(--searchbar-height) / 2) - 12px); +} + +@keyframes slideInSearchResults { + from { + opacity: 0; + transform: translate(0, 15px); + } + + to { + opacity: 1; + transform: translate(0, 20px); + } +} + +#MSearchResultsWindow { + left: auto !important; + right: var(--spacing-medium); + border-radius: var(--border-radius-large); + border: 1px solid var(--separator-color); + transform: translate(0, 20px); + box-shadow: var(--box-shadow); + animation: ease-out 280ms slideInSearchResults; + background: var(--page-background-color); +} + +iframe#MSearchResults { + background: var(--page-background-color); + margin: 4px; +} + +#MSearchSelectWindow { + border: 1px solid var(--separator-color); + border-radius: var(--border-radius-medium); + box-shadow: var(--box-shadow); + background: var(--page-background-color); +} + +#MSearchSelectWindow a.SelectItem { + font-size: var(--navigation-font-size); + line-height: var(--content-line-height); + margin: 0 var(--spacing-small); + border-radius: var(--border-radius-small); + color: var(--page-foreground-color) !important; + font-weight: normal; +} + +#MSearchSelectWindow a.SelectItem:hover { + background: var(--menu-focus-background); + color: var(--menu-focus-foreground) !important; +} + +@media screen and (max-width: 767px) { + #MSearchBox { + margin-top: var(--spacing-medium); + margin-bottom: var(--spacing-medium); + width: calc(100vw - 30px); + } + + #main-menu > li:last-child { + float: none !important; + } + + #MSearchField { + width: calc(100vw - 110px); + } + + @keyframes slideInSearchResultsMobile { + from { + opacity: 0; + transform: translate(0, 15px); + } + + to { + opacity: 1; + transform: translate(0, 20px); + } + } + + #MSearchResultsWindow { + left: var(--spacing-medium) !important; + right: var(--spacing-medium); + overflow: auto; + transform: translate(0, 20px); + animation: ease-out 280ms slideInSearchResultsMobile; + } +} + +/* + Tree view + */ + +#side-nav { + padding: 0 !important; + background: var(--side-nav-background); +} + +@media screen and (max-width: 767px) { + #side-nav { + display: none; + } + + #doc-content { + margin-left: 0 !important; + height: auto !important; + padding-bottom: calc(2 * var(--spacing-large)); + } +} + +#nav-tree { + background: transparent; +} + +#nav-tree .label { + font-size: var(--navigation-font-size); +} + +#nav-tree .item { + height: var(--tree-item-height); + line-height: var(--tree-item-height); +} + +#nav-sync { + top: 12px !important; + right: 12px; +} + +#nav-tree .selected { + text-shadow: none; + background-image: none; + background-color: transparent; + box-shadow: inset 4px 0 0 0 var(--primary-color); +} + +#nav-tree a { + color: var(--side-nav-foreground) !important; + font-weight: normal; +} + +#nav-tree a:focus { + outline-style: auto; +} + +#nav-tree .arrow { + opacity: var(--side-nav-arrow-opacity); +} + +.arrow { + color: inherit; + cursor: pointer; + font-size: 45%; + vertical-align: middle; + margin-right: 2px; + font-family: serif; + height: auto; + text-align: right; +} + +#nav-tree div.item:hover .arrow, #nav-tree a:focus .arrow { + opacity: var(--side-nav-arrow-hover-opacity); +} + +#nav-tree .selected a { + color: var(--primary-color) !important; + font-weight: bolder; + font-weight: 600; +} + +.ui-resizable-e { + background: var(--separator-color); + width: 1px; +} + +/* + Contents + */ + +div.header { + border-bottom: 1px solid var(--separator-color); + background-color: var(--page-background-color); + background-image: none; +} + +div.contents, div.header .title, div.header .summary { + max-width: var(--content-maxwidth); +} + +div.contents, div.header .title { + line-height: initial; + margin: calc(var(--spacing-medium) + .2em) auto var(--spacing-medium) auto; +} + +div.header .summary { + margin: var(--spacing-medium) auto 0 auto; +} + +div.headertitle { + padding: 0; +} + +div.header .title { + font-weight: 600; + font-size: 210%; + padding: var(--spacing-medium) var(--spacing-large); + word-break: break-word; +} + +div.header .summary { + width: auto; + display: block; + float: none; + padding: 0 var(--spacing-large); +} + +td.memSeparator { + border-color: var(--separator-color); +} + +.mdescLeft, .mdescRight, .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background: var(--code-background); +} + +.mdescRight { + color: var(--page-secondary-foreground-color); +} + +span.mlabel { + background: var(--primary-color); + border: none; + padding: 4px 9px; + border-radius: 12px; + margin-right: var(--spacing-medium); +} + +span.mlabel:last-of-type { + margin-right: 2px; +} + +div.contents { + padding: 0 var(--spacing-large); +} + +div.contents p, div.contents li { + line-height: var(--content-line-height); +} + +div.contents div.dyncontent { + margin: var(--spacing-medium) 0; +} + +@media (prefers-color-scheme: dark) { + html:not(.light-mode) div.contents div.dyncontent img { + filter: hue-rotate(180deg) invert(); + } +} + +html.dark-mode div.contents div.dyncontent img { + filter: hue-rotate(180deg) invert(); +} + +h2.groupheader { + border-bottom: 1px solid var(--separator-color); + color: var(--page-foreground-color); +} + +blockquote { + padding: var(--spacing-small) var(--spacing-medium); + background: var(--blockquote-background); + color: var(--blockquote-foreground); + border-left: 2px solid var(--blockquote-foreground); + margin: 0; +} + +blockquote p { + margin: var(--spacing-small) 0 var(--spacing-medium) 0; +} +.paramname { + font-weight: 600; + color: var(--primary-dark-color); +} + +.glow { + text-shadow: 0 0 15px var(--primary-light-color) !important; +} + +.alphachar a { + color: var(--page-foreground-color); +} + +/* + Table of Contents + */ + +div.toc { + background-color: var(--side-nav-background); + border: 1px solid var(--separator-color); + border-radius: var(--border-radius-medium); + box-shadow: var(--box-shadow); + padding: 0 var(--spacing-large); + margin: 0 0 var(--spacing-medium) var(--spacing-medium); +} + +div.toc h3 { + color: var(--side-nav-foreground); + font-size: var(--navigation-font-size); + margin: var(--spacing-large) 0; +} + +div.toc li { + font-size: var(--navigation-font-size); + padding: 0; + background: none; +} + +div.toc li:before { + content: '↓'; + font-weight: 800; + font-family: var(--font-family); + margin-right: var(--spacing-small); + color: var(--side-nav-foreground); + opacity: .4; +} + +div.toc ul li.level1 { + margin: 0; +} + +div.toc ul li.level2, div.toc ul li.level3 { + margin-top: 0; +} + + +@media screen and (max-width: 767px) { + div.toc { + float: none; + width: auto; + margin: 0 0 var(--spacing-medium) 0; + } +} + +/* + Code & Fragments + */ + +code, div.fragment, pre.fragment { + border-radius: var(--border-radius-small); + border: none; + overflow: hidden; +} + +code { + display: inline; + background: var(--code-background); + color: var(--code-foreground); + padding: 2px 6px; + word-break: break-word; +} + +div.fragment, pre.fragment { + margin: var(--spacing-medium) 0; + padding: 14px 16px; + background: var(--fragment-background); + color: var(--fragment-foreground); + overflow-x: auto; +} + +@media screen and (max-width: 767px) { + div.fragment, pre.fragment { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + .contents > div.fragment, .textblock > div.fragment, .textblock > pre.fragment { + margin: var(--spacing-medium) calc(0px - var(--spacing-large)); + border-radius: 0; + } + + .textblock li > .fragment { + margin: var(--spacing-medium) calc(0px - var(--spacing-large)); + } + + .memdoc li > .fragment { + margin: var(--spacing-medium) calc(0px - var(--spacing-medium)); + } + + .memdoc > div.fragment, .memdoc > pre.fragment, dl dd > div.fragment, dl dd pre.fragment { + margin: var(--spacing-medium) calc(0px - var(--spacing-medium)); + border-radius: 0; + } +} + +code, code a, pre.fragment, div.fragment, div.fragment .line, div.fragment span, div.fragment .line a, div.fragment .line span { + font-family: var(--font-family-monospace); + font-size: var(--code-font-size) !important; +} + +div.line:after { + margin-right: var(--spacing-medium); +} + +div.fragment .line, pre.fragment { + white-space: pre; + word-wrap: initial; + line-height: var(--fragment-lineheight); +} + +div.fragment span.keyword { + color: var(--fragment-keyword); +} + +div.fragment span.keywordtype { + color: var(--fragment-keywordtype); +} + +div.fragment span.keywordflow { + color: var(--fragment-keywordflow); +} + +div.fragment span.stringliteral { + color: var(--fragment-token) +} + +div.fragment span.comment { + color: var(--fragment-comment); +} + +div.fragment a.code { + color: var(--fragment-link) !important; +} + +div.fragment span.preprocessor { + color: var(--fragment-preprocessor); +} + +div.fragment span.lineno { + display: inline-block; + width: 27px; + border-right: none; + background: var(--fragment-linenumber-background); + color: var(--fragment-linenumber-color); +} + +div.fragment span.lineno a { + background: none; + color: var(--fragment-link) !important; +} + +div.fragment .line:first-child .lineno { + box-shadow: -999999px 0px 0 999999px var(--fragment-linenumber-background), -999998px 0px 0 999999px var(--fragment-linenumber-border); +} + +/* + dl warning, attention, note, deprecated, bug, ... + */ + +dl.warning, dl.attention, dl.note, dl.deprecated, dl.bug, dl.invariant, dl.pre { + padding: var(--spacing-medium); + margin: var(--spacing-medium) 0; + color: var(--page-background-color); + overflow: hidden; + margin-left: 0; + border-radius: var(--border-radius-small); +} + +dl.section dd { + margin-bottom: 2px; +} + +dl.warning, dl.attention { + background: var(--warning-color); + border-left: 8px solid var(--warning-color-dark); + color: var(--warning-color-darker); +} + +dl.warning dt, dl.attention dt { + color: var(--warning-color-dark); +} + +dl.note { + background: var(--note-color); + border-left: 8px solid var(--note-color-dark); + color: var(--note-color-darker); +} + +dl.note dt { + color: var(--note-color-dark); +} + +dl.bug { + background: var(--bug-color); + border-left: 8px solid var(--bug-color-dark); + color: var(--bug-color-darker); +} + +dl.bug dt a { + color: var(--bug-color-dark) !important; +} + +dl.deprecated { + background: var(--deprecated-color); + border-left: 8px solid var(--deprecated-color-dark); + color: var(--deprecated-color-darker); +} + +dl.deprecated dt a { + color: var(--deprecated-color-dark) !important; +} + +dl.section dd, dl.bug dd, dl.deprecated dd { + margin-inline-start: 0px; +} + +dl.invariant, dl.pre { + background: var(--invariant-color); + border-left: 8px solid var(--invariant-color-dark); + color: var(--invariant-color-darker); +} + +/* + memitem + */ + +div.memdoc, div.memproto, h2.memtitle { + box-shadow: none; + background-image: none; + border: none; +} + +div.memdoc { + padding: 0 var(--spacing-medium); + background: var(--page-background-color); +} + +h2.memtitle, div.memitem { + border: 1px solid var(--separator-color); +} + +div.memproto, h2.memtitle { + background: var(--code-background); + text-shadow: none; +} + +h2.memtitle { + font-weight: 500; + font-family: monospace, fixed; + border-bottom: none; + border-top-left-radius: var(--border-radius-medium); + border-top-right-radius: var(--border-radius-medium); + word-break: break-all; +} + +a:target + h2.memtitle, a:target + h2.memtitle + div.memitem { + border-color: var(--primary-light-color); +} + +a:target + h2.memtitle { + box-shadow: -3px -3px 3px 0 var(--primary-lightest-color), 3px -3px 3px 0 var(--primary-lightest-color); +} + +a:target + h2.memtitle + div.memitem { + box-shadow: 0 0 10px 0 var(--primary-lighter-color); +} + +div.memitem { + border-top-right-radius: var(--border-radius-medium); + border-bottom-right-radius: var(--border-radius-medium); + border-bottom-left-radius: var(--border-radius-medium); + overflow: hidden; + display: block !important; +} + +div.memdoc { + border-radius: 0; +} + +div.memproto { + border-radius: 0 var(--border-radius-small) 0 0; + overflow: auto; + border-bottom: 1px solid var(--separator-color); + padding: var(--spacing-medium); + margin-bottom: -1px; +} + +div.memtitle { + border-top-right-radius: var(--border-radius-medium); + border-top-left-radius: var(--border-radius-medium); +} + +div.memproto table.memname { + font-family: monospace, fixed; + color: var(--page-foreground-color); +} + +table.mlabels, table.mlabels > tbody { + display: block; +} + +td.mlabels-left { + width: auto; +} + +table.mlabels > tbody > tr:first-child { + display: flex; + justify-content: space-between; + flex-wrap: wrap; +} + +.memname, .memitem span.mlabels { + margin: 0 +} + +/* + reflist + */ + +dl.reflist { + box-shadow: var(--box-shadow); + border-radius: var(--border-radius-medium); + border: 1px solid var(--separator-color); + overflow: hidden; + padding: 0; +} + + +dl.reflist dt, dl.reflist dd { + box-shadow: none; + text-shadow: none; + background-image: none; + border: none; + padding: 12px; +} + + +dl.reflist dt { + font-weight: 500; + border-radius: 0; + background: var(--code-background); + border-bottom: 1px solid var(--separator-color); + color: var(--page-foreground-color) +} + + +dl.reflist dd { + background: none; +} + +/* + Table + */ + +table.markdownTable, table.fieldtable { + width: 100%; + border: 1px solid var(--separator-color); + margin: var(--spacing-medium) 0; +} + +table.fieldtable { + box-shadow: none; + border-radius: var(--border-radius-small); +} + +th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { + background: var(--tablehead-background); + color: var(--tablehead-foreground); + font-weight: 600; + font-size: var(--page-font-size); +} + +table.markdownTable td, table.markdownTable th, table.fieldtable dt { + border: 1px solid var(--separator-color); + padding: var(--spacing-small) var(--spacing-medium); +} + +table.fieldtable th { + font-size: var(--page-font-size); + font-weight: 600; + background-image: none; + background-color: var(--tablehead-background); + color: var(--tablehead-foreground); + border-bottom: 1px solid var(--separator-color); +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + border-bottom: 1px solid var(--separator-color); + border-right: 1px solid var(--separator-color); +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid var(--separator-color); +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: var(--primary-light-color); + box-shadow: 0 0 15px var(--primary-lighter-color); +} + +table.memberdecls { + display: block; + overflow-x: auto; + overflow-y: hidden; +} + + +/* + Horizontal Rule + */ + +hr { + margin-top: var(--spacing-large); + margin-bottom: var(--spacing-large); + border-top:1px solid var(--separator-color); +} + +.contents hr { + box-shadow: var(--content-maxwidth) 0 0 0 var(--separator-color), calc(0px - var(--content-maxwidth)) 0 0 0 var(--separator-color); +} + +.contents img { + max-width: 100%; +} + +/* + Directories + */ +div.directory { + border-top: 1px solid var(--separator-color); + border-bottom: 1px solid var(--separator-color); + width: auto; +} + +table.directory { + font-family: var(--font-family); + font-size: var(--page-font-size); + font-weight: normal; +} + +.directory td.entry { + padding: var(--spacing-small); + display: flex; + align-items: center; +} + +.directory tr.even { + background-color: var(--odd-color); +} + +.icona { + width: auto; + height: auto; + margin: 0 var(--spacing-small); +} + +.icon { + background: var(--primary-color); + width: 18px; + height: 18px; + line-height: 18px; +} + +.iconfopen, .icondoc, .iconfclosed { + background-position: center; + margin-bottom: 0; +} + +.icondoc { + filter: saturate(0.2); +} + +@media screen and (max-width: 767px) { + div.directory { + margin-left: calc(0px - var(--spacing-medium)); + margin-right: calc(0px - var(--spacing-medium)); + } +} + +@media (prefers-color-scheme: dark) { + html:not(.light-mode) .iconfopen, html:not(.light-mode) .iconfclosed { + filter: hue-rotate(180deg) invert(); + } +} + +html.dark-mode .iconfopen, html.dark-mode .iconfclosed { + filter: hue-rotate(180deg) invert(); +} + +/* + Class list + */ + +.classindex dl.odd { + background: var(--odd-color); + border-radius: var(--border-radius-small); +} + +@media screen and (max-width: 767px) { + .classindex { + margin: 0 calc(0px - var(--spacing-small)); + } +} + +/* + Footer and nav-path + */ + +#nav-path { + margin-bottom: -1px; + width: 100%; +} + +#nav-path ul { + background-image: none; + background: var(--page-background-color); + border: none; + border-top: 1px solid var(--separator-color); + border-bottom: 1px solid var(--separator-color); + font-size: var(--navigation-font-size); +} + +img.footer { + width: 60px; +} + +.navpath li.footer { + color: var(--page-secondary-foreground-color); +} + +address.footer { + margin-bottom: var(--spacing-large); +} + +#nav-path li.navelem { + background-image: none; + display: flex; + align-items: center; +} + +.navpath li.navelem a { + text-shadow: none; + display: inline-block; + color: var(--primary-color) !important; +} + +li.navelem { + padding: 0; + margin-left: -8px; +} + +li.navelem:first-child { + margin-left: var(--spacing-large); +} + +li.navelem:first-child:before { + display: none; +} + +#nav-path li.navelem:after { + content: ''; + border: 5px solid var(--page-background-color); + border-bottom-color: transparent; + border-right-color: transparent; + border-top-color: transparent; + transform: scaleY(4.2); + z-index: 10; + margin-left: 6px; +} + +#nav-path li.navelem:before { + content: ''; + border: 5px solid var(--separator-color); + border-bottom-color: transparent; + border-right-color: transparent; + border-top-color: transparent; + transform: scaleY(3.2); + margin-right: var(--spacing-small); +} + +.navpath li.navelem a:hover { + color: var(--primary-color); +} + +/* + Optional Dark mode toggle button +*/ + +doxygen-awesome-dark-mode-toggle { + margin: 0 0 0 var(--spacing-small); + padding: 0; + width: var(--searchbar-height); + height: var(--searchbar-height); + background: none; + border: none; + font-size: 23px; + border-radius: var(--border-radius-medium); + vertical-align: middle; + text-align: center; + line-height: var(--searchbar-height); +} + +doxygen-awesome-dark-mode-toggle:hover { + background: var(--separator-color); +} + +doxygen-awesome-dark-mode-toggle:after { + content: var(--darkmode-toggle-button-icon) +} diff --git a/doxygen.css b/doxygen.css new file mode 100644 index 00000000..1425ec53 --- /dev/null +++ b/doxygen.css @@ -0,0 +1,1475 @@ +/* The standard CSS for doxygen 1.8.11 */ + +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 4px 6px; + margin: 4px 8px 4px 2px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line:after { + content:"\000A"; + white-space: pre; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +div.ah, span.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%); +} + +div.classindex ul { + list-style: none; + padding-left: 0; +} + +div.classindex span.ai { + display: inline-block; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: bold; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + border-top-left-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #9CAFD4; + border-bottom: 1px solid #9CAFD4; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +.arrow { + color: #9CAFD4; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: Arial, Helvetica; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: #728DC1; + color: white; + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderopen.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderclosed.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('doc.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +table.directory { + font: 400 14px Roboto,sans-serif; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable caption { + caption-side: top; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +table.classindex +{ + margin: 10px; + white-space: nowrap; + margin-left: 3%; + margin-right: 3%; + width: 94%; + border: 0; + border-spacing: 0; + padding: 0; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +dl +{ + padding: 0 0 0 10px; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ +dl.section +{ + margin-left: 0px; + padding-left: 0px; +} + +dl.note +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00D000; +} + +dl.deprecated +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #505050; +} + +dl.todo +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00C0E0; +} + +dl.test +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #3030E0; +} + +dl.bug +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectalign +{ + vertical-align: middle; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 8px 10px 10px; + width: 200px; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + white-space: nowrap; + background-color: white; + border: 1px solid gray; + border-radius: 4px 4px 4px 4px; + box-shadow: 1px 1px 7px gray; + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: grey; + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: #006318; +} + +#powerTip div { + margin: 0px; + padding: 0px; + font: 12px/16px Roboto,sans-serif; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before { + border-top-color: #808080; + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: #808080; + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + diff --git a/doxygen.png b/doxygen.png new file mode 100644 index 0000000000000000000000000000000000000000..3ff17d807fd8aa003bed8bb2a69e8f0909592fd1 GIT binary patch literal 3779 zcmV;!4m|ORP)tMIv#Q0*~7*`IBSO7_x;@a8#Zk6_PeKR_s92J&)(m+);m9Iz3blw)z#Gi zP!9lj4$%+*>Hz@HCmM9L9|8c+0u=!H$O3?R0Kgx|#WP<6fKfC8fM-CQZT|_r@`>VO zX^Hgb|9cJqpdJA5$MCEK`F_2@2Y@s>^+;pF`~jdI0Pvr|vl4`=C)EH@1IFe7pdJ8F zH(qGi004~QnF)Ggga~8v08kGAs2hKTATxr7pwfNk|4#_AaT>w8P6TV+R2kbS$v==} zAjf`s0g#V8lB+b3)5oEI*q+{Yt$MZDruD2^;$+(_%Qn+%v0X-bJO=;@kiJ^ygLBnC z?1OVv_%aex1M@jKU|Z~$eI?PoF4Vj>fDzyo zAiLfpXY*a^Sj-S5D0S3@#V$sRW)g)_1e#$%8xdM>Jm7?!h zu0P2X=xoN>^!4DoPRgph2(2va07yfpXF+WH7EOg1GY%Zn z7~1A<(z7Q$ktEXhW_?GMpHp9l_UL18F3KOsxu81pqoBiNbFSGsof-W z6~eloMoz=4?OOnl2J268x5rOY`dCk0us(uS#Ud4yqOr@?=Q57a}tit|BhY>}~frH1sP`ScHS_d)oqH^lYy zZ%VP`#10MlE~P?cE(%(#(AUSv_T{+;t@$U}El}(1ig`vZo`Rm;+5&(AYzJ^Ae=h2X z@Re%vHwZU>|f0NI&%$*4eJweC5OROQrpPMA@*w|o z()A==l}(@bv^&>H1Ob3C=<^|hob?0+xJ?QQ3-ueQC}zy&JQNib!OqSO@-=>XzxlSF zAZ^U*1l6EEmg3r};_HY>&Jo_{dOPEFTWPmt=U&F#+0(O59^UIlHbNX+eF8UzyDR*T z(=5X$VF3!gm@RooS-&iiUYGG^`hMR(07zr_xP`d!^BH?uD>Phl8Rdifx3Af^Zr`Ku ztL+~HkVeL#bJ)7;`=>;{KNRvjmc}1}c58Sr#Treq=4{xo!ATy|c>iRSp4`dzMMVd@ zL8?uwXDY}Wqgh4mH`|$BTXpUIu6A1-cSq%hJw;@^Zr8TP=GMh*p(m(tN7@!^D~sl$ zz^tf4II4|};+irE$Fnm4NTc5%p{PRA`%}Zk`CE5?#h3|xcyQsS#iONZ z6H(@^i9td!$z~bZiJLTax$o>r(p}3o@< zyD7%(>ZYvy=6$U3e!F{Z`uSaYy`xQyl?b{}eg|G3&fz*`QH@mDUn)1%#5u`0m$%D} z?;tZ0u(mWeMV0QtzjgN!lT*pNRj;6510Wwx?Yi_=tYw|J#7@(Xe7ifDzXuK;JB;QO z#bg~K$cgm$@{QiL_3yr}y&~wuv=P=#O&Tj=Sr)aCUlYmZMcw?)T?c%0rUe1cS+o!qs_ zQ6Gp)-{)V!;=q}llyK3|^WeLKyjf%y;xHku;9(vM!j|~<7w1c*Mk-;P{T&yG) z@C-8E?QPynNQ<8f01D`2qexcVEIOU?y}MG)TAE6&VT5`rK8s(4PE;uQ92LTXUQ<>^ ztyQ@=@kRdh@ebUG^Z6NWWIL;_IGJ2ST>$t!$m$qvtj0Qmw8moN6GUV^!QKNK zHBXCtUH8)RY9++gH_TUV4^=-j$t}dD3qsN7GclJ^Zc&(j6&a_!$jCf}%c5ey`pm~1)@{yI3 zTdWyB+*X{JFw#z;PwRr5evb2!ueWF;v`B0HoUu4-(~aL=z;OXUUEtG`_$)Oxw6FKg zEzY`CyKaSBK3xt#8gA|r_|Kehn_HYVBMpEwbn9-fI*!u*eTA1ef8Mkl1=!jV4oYwWYM}i`A>_F4nhmlCIC6WLa zY%;4&@AlnaG11ejl61Jev21|r*m+?Kru3;1tFDl}#!OzUp6c>go4{C|^erwpG*&h6bspUPJag}oOkN2912Y3I?(eRc@U9>z#HPBHC?nps7H5!zP``90!Q1n80jo+B3TWXp!8Pe zwuKuLLI6l3Gv@+QH*Y}2wPLPQ1^EZhT#+Ed8q8Wo z1pTmIBxv14-{l&QVKxAyQF#8Q@NeJwWdKk>?cpiJLkJr+aZ!Me+Cfp!?FWSRf^j2k z73BRR{WSKaMkJ>1Nbx5dan5hg^_}O{Tj6u%iV%#QGz0Q@j{R^Ik)Z*+(YvY2ziBG)?AmJa|JV%4UT$k`hcOg5r9R?5>?o~JzK zJCrj&{i#hG>N7!B4kNX(%igb%kDj0fOQThC-8mtfap82PNRXr1D>lbgg)dYTQ(kbx z`Ee5kXG~Bh+BHQBf|kJEy6(ga%WfhvdQNDuOfQoe377l#ht&DrMGeIsI5C<&ai zWG$|hop2@@q5YDa)_-A?B02W;#fH!%k`daQLEItaJJ8Yf1L%8x;kg?)k)00P-lH+w z)5$QNV6r2$YtnV(4o=0^3{kmaXn*Dm0F*fU(@o)yVVjk|ln8ea6BMy%vZAhW9|wvA z8RoDkVoMEz1d>|5(k0Nw>22ZT){V<3$^C-cN+|~hKt2)){+l-?3m@-$c?-dlzQ)q- zZ)j%n^gerV{|+t}9m1_&&Ly!9$rtG4XX|WQ8`xYzGC~U@nYh~g(z9)bdAl#xH)xd5a=@|qql z|FzEil{P5(@gy!4ek05i$>`E^G~{;pnf6ftpLh$h#W?^#4UkPfa;;?bsIe&kz!+40 zI|6`F2n020)-r`pFaZ38F!S-lJM-o&inOw|66=GMeP@xQU5ghQH{~5Uh~TMTd;I9` z>YhVB`e^EVj*S7JF39ZgNf}A-0DwOcTT63ydN$I3b?yBQtUI*_fae~kPvzoD$zjX3 zoqBe#>12im4WzZ=f^4+u=!lA|#r%1`WB0-6*3BL#at`47#ebPpR|D1b)3BjT34nYY z%Ds%d?5$|{LgOIaRO{{oC&RK`O91$fqwM0(C_TALcozu*fWHb%%q&p-q{_8*2Zsi^ zh1ZCnr^UYa;4vQEtHk{~zi>wwMC5o{S=$P0X681y`SXwFH?Ewn{x-MOZynmc)JT5v zuHLwh;tLfxRrr%|k370}GofLl7thg>ACWWY&msqaVu&ry+`7+Ss>NL^%T1|z{IGMA zW-SKl=V-^{(f!Kf^#3(|T2W47d(%JVCI4JgRrT1pNz>+ietmFToNv^`gzC@&O-)+i zPQ~RwK8%C_vf%;%e>NyTp~dM5;!C|N0Q^6|CEb7Bw=Vz~$1#FA;Z*?mKSC)Hl-20s t8QyHj(g6VK0RYbl8UjE)0O0w=e*@m04r>stuEhWV002ovPDHLkV1hl;dM*F} literal 0 HcmV?d00001 diff --git a/dynsections.js b/dynsections.js new file mode 100644 index 00000000..85e18369 --- /dev/null +++ b/dynsections.js @@ -0,0 +1,97 @@ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + +array: include/array/ein_reduce.h File Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ein_reduce.h File Reference
+
+
+ +

Optional helper for computing Einstein reductions on arrays. +More...

+
#include "array/array.h"
+
+

Go to the source code of this file.

+ + + + + + + + +

+Macros

#define NDARRAY_MAKE_EIN_BINARY_HELPERS(name, op)
 
#define NDARRAY_MAKE_EIN_BINARY_OP(name, op, is_assign_)
 
#define NDARRAY_MAKE_EIN_BINARY_FN(name, fn)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

template<class Type , class Op >
auto cast (const internal::ein_op_base< Op > &op)
 
template<class OpA , class OpB >
auto min (const internal::ein_op_base< OpA > &a, const internal::ein_op_base< OpB > &b)
 
+template<class OpA , class OpB >
auto max (const internal::ein_op_base< OpA > &a, const internal::ein_op_base< OpB > &b)
 
template<size_t... Is, class Op , class = internal::enable_if_callable<Op, decltype(Is)...>>
auto ein (Op op)
 
+template<size_t... Is, class T , class Shape , class Alloc , class = std::enable_if_t<sizeof...(Is) == Shape::rank()>>
auto ein (array< T, Shape, Alloc > &op)
 
+template<size_t... Is, class T , class Shape , class Alloc , class = std::enable_if_t<sizeof...(Is) == Shape::rank()>>
auto ein (const array< T, Shape, Alloc > &op)
 
template<class T >
auto ein (T &scalar)
 
template<size_t I0, class T >
auto ein (T *x, size_t N)
 
template<size_t I0, class T , size_t N>
auto ein (T(&x)[N])
 
template<class Expr , class = internal::enable_if_ein_assign<Expr>>
NDARRAY_INLINE auto ein_reduce (const Expr &expr)
 
template<size_t... ResultIs, class Expr , class = internal::enable_if_ein_op<Expr>>
NDARRAY_UNIQUE auto make_ein_reduce_shape (const Expr &expr)
 
template<class T , size_t... ResultIs, class Expr , class Alloc = std::allocator<T>, class = internal::enable_if_ein_op<Expr>>
NDARRAY_INLINE auto make_ein_sum (const Expr &expr, const T &init=T(), const Alloc &alloc=Alloc())
 
+

Detailed Description

+

Optional helper for computing Einstein reductions on arrays.

+

Macro Definition Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + +
#define NDARRAY_MAKE_EIN_BINARY_HELPERS( name,
 op 
)
+
+Value:
template <class OpA, class OpB> \
auto make_##name(const OpA& a, const OpB& b) { \
return name<OpA, OpB>(a, b); \
}
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
#define NDARRAY_MAKE_EIN_BINARY_OP( name,
 op,
 is_assign_ 
)
+
+Value:
template <class OpA, class OpB> \
struct name : public ein_binary_op<OpA, OpB, name<OpA, OpB>> { \
using base = ein_binary_op<OpA, OpB, name>; \
name(const OpA& a, const OpB& b) : base(a, b) {} \
using is_assign = is_assign_; \
template <class Idx> \
NDARRAY_INLINE auto operator()(const Idx& i) const { \
return base::op_a(i) op base::op_b(i); \
} \
}; \
NDARRAY_MAKE_EIN_BINARY_HELPERS(name, op)
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
#define NDARRAY_MAKE_EIN_BINARY_FN( name,
 fn 
)
+
+Value:
template <class OpA, class OpB> \
struct name : public ein_binary_op<OpA, OpB, name<OpA, OpB>> { \
using base = ein_binary_op<OpA, OpB, name>; \
name(const OpA& a, const OpB& b) : base(a, b) {} \
template <class Idx> \
NDARRAY_INLINE auto operator()(const Idx& i) const { \
using internal::min; \
using internal::max; \
return fn(base::op_a(i), base::op_b(i)); \
} \
}; \
NDARRAY_MAKE_EIN_BINARY_HELPERS(name, op)
+
+
+

Function Documentation

+ +
+
+ + + + + + + + +
auto nda::cast (const internal::ein_op_base< Op > & op)
+
+

Cast an Einstein summation operand to a different type Type. The cast is performed using static_cast<Type>.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
auto nda::min (const internal::ein_op_base< OpA > & a,
const internal::ein_op_base< OpB > & b 
)
+
+

The min or max of two Einstein summation operands.

+ +
+
+ +
+
+ + + + + + + + +
auto nda::ein (Op op)
+
+

Operand for an Einstein summation, which is an array or other callable object, along with a set of dimension indices. ein<i, j, ...>(a) means the dimensions i, j, ... of the summation index are used to address a during Einstein summation. The number of dimensions must match the number of arguments of a. See ein_reduce() for more details.

+ +
+
+ +
+
+ + + + + + + + +
auto nda::ein (T & scalar)
+
+

Define an Einstein summation operand for a scalar. The scalar is broadcasted as needed during the summation. Because this operand does not provide a shape, the dimensions of the sum must be inferred from other operands. See ein_reduce() for more details.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
auto nda::ein (T * x,
size_t N 
)
+
+

Define an Einstein summation operand for a pointer and size.

+ +
+
+ +
+
+ + + + + + + + +
auto nda::ein (T(&) x[N])
+
+

Define an Einstein summation operand for a C array.

+ +
+
+ +
+
+ + + + + + + + +
NDARRAY_INLINE auto nda::ein_reduce (const Expr & expr)
+
+

Compute an Einstein reduction. This function allows one to specify many kinds of array transformations and reductions using Einstein notation.

+

This function accepts an expression expr constructed using operators on ein<i, j, ...>(op) operands. These operands describe which dimensions of the reduction index should be used to address that operand. The rank of the reduction operation is inferred from the number of dimensions used in the expression. The reduction operation is executed in the order of the indices, with the lowest numbered dimension executed as the innermost loop.

+

If expr is a reduction operator, the result must be initialized to some useful value, typically the identity value for the reduction operator, e.g. 0 for +=. Not initializing the result allows successive ein_reduce operations to be applied to the same result.

+

This function does not optimize the associative order in which the operations are performed. It evaluates the expression for each element of the final result reduction. This can be efficient for expansion operations, but it may be inefficient for contractions. Contractions may need to be reassociated manually for efficient computation.

+

This function does not optimize the loop ordering within each operation. The goal of this function is to provide a low-overhead and expressive reduction that can be composed with other explicit loop transformations to achieve good performance. Various optimization strategies can be implemented by splitting loops appropriately and by controlling the order of the loops with the reduction indices.

+

Examples:

    +
  • ein_reduce(ein<>(tr_A) += ein<i, i>(A)), the trace of A.
  • +
  • ein_reduce(ein<>(dot) += (ein<i>(x) + ein<i>(y)) * ein<i>(z)), the dot product (x + y)*z.
  • +
  • ein_reduce(ein<i, j>(AB) += ein<i, k>(A) * ein<k, j>(B)), the matrix product A*B
  • +
  • ein_reduce(ein<i>(Ax) += ein<i, j>(A) * ein<j>(x)), the matrix-vector product A*x
  • +
  • ein_reduce(ein<i>(diag_A) = ein<i, i>(A)), the diagonal of A.
  • +
+

where:

    +
  • A, B, AB are matrices (rank 2 arrays)
  • +
  • x, y, z, Ax are vectors (rank 1 arrays)
  • +
  • tr_A, dot are scalar (rank 0 arrays)
  • +
  • i, j, k are unique constexpr integers.
  • +
+ +
+
+ +
+
+ + + + + + + + +
NDARRAY_UNIQUE auto nda::make_ein_reduce_shape (const Expr & expr)
+
+

Infer the shape of the result of make_ein_reduce.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
NDARRAY_INLINE auto nda::make_ein_sum (const Expr & expr,
const T & init = T(),
const Alloc & alloc = Alloc() 
)
+
+

Compute an Einstein summation using ein_reduce and return the result. The value_type of the result will be T, and the result shape will be inferred from the shape of the operands. The result is initialized to init prior to computing the summation. The Einstein summation indices for the result operand are ResultIs....

+

Examples:

    +
  • trace_A = make_ein_sum<T>(ein<i, i>(A))
  • +
  • dot = make_ein_sum<T>((ein<i>(x) + ein<i>(y)) * ein<i>(z))
  • +
  • AB = make_ein_sum<T, i, j>(ein<i, k>(A) * ein<k, j>(B))
  • +
  • Ax = make_ein_sum<T, i>(ein<i, j>(A) * ein<1>(x))
  • +
+

where:

    +
  • A, B are matrices (rank 2 arrays)
  • +
  • x, y, z are vectors (rank 1 arrays)
  • +
  • i, j, k are unique constexpr integers.
  • +
+

See ein_reduce() for more details.

+ +
+
+
+ + + + diff --git a/ein__reduce_8h_source.html b/ein__reduce_8h_source.html new file mode 100644 index 00000000..ceecd5db --- /dev/null +++ b/ein__reduce_8h_source.html @@ -0,0 +1,122 @@ + + + + + + +array: include/array/ein_reduce.h Source File + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ein_reduce.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
19 #ifndef NDARRAY_EIN_REDUCE_H
20 #define NDARRAY_EIN_REDUCE_H
21 
22 #include "array/array.h"
23 
24 namespace nda {
25 
26 namespace internal {
27 
28 // TODO: Find a way to enable operations with non-op types? e.g. scalars.
29 template <class T>
30 using enable_if_ein_op =
31  std::enable_if_t<std::is_same<typename T::is_ein_op, std::true_type>::value>;
32 
33 template <class T>
34 using enable_if_ein_assign =
35  std::enable_if_t<std::is_same<typename T::is_assign, std::true_type>::value>;
36 
37 // Briefly, the high level goal of the next few classes is to enable construction of
38 // expressions describing Einstein summations or other reductions. This is done using
39 // a small expression template system. Normally, expression templates are troublesome
40 // due to overwhemling the compiler's ability to do CSE and other optimziations. In
41 // the case of Einstein reductions, the expressions will usually be very small...
42 
43 template <class Derived>
44 struct ein_op_base {
45  using is_ein_op = std::true_type;
46  using is_assign = std::false_type;
47 
48  // We need to be able to get the derived type when creating binary operations using
49  // this operation as an operand.
50  const Derived& derived() const { return *static_cast<const Derived*>(this); }
51 
52  auto operator-() const { return make_ein_op_negate(derived()); }
53  template <class T, class = enable_if_ein_op<T>>
54  auto operator+(const T& r) const {
55  return make_ein_op_add(derived(), r);
56  }
57  template <class T, class = enable_if_ein_op<T>>
58  auto operator-(const T& r) const {
59  return make_ein_op_sub(derived(), r);
60  }
61  template <class T, class = enable_if_ein_op<T>>
62  auto operator*(const T& r) const {
63  return make_ein_op_mul(derived(), r);
64  }
65  template <class T, class = enable_if_ein_op<T>>
66  auto operator/(const T& r) const {
67  return make_ein_op_div(derived(), r);
68  }
69 };
70 
71 // A leaf operand of an Einstein reduction expression. The Is... indicate the
72 // dimension of the reduction to use to address this operand.
73 template <class Op, size_t... Is>
74 struct ein_op : public ein_op_base<ein_op<Op, Is...>> {
75  Op op;
76  ein_op(Op op) : op(std::move(op)) {}
77 
78  // The largest dimension used by this operand.
79  static constexpr index_t MaxIndex = sizeof...(Is) == 0 ? -1 : variadic_max(Is...);
80 
81  // auto doesn't work here because it doesn't include the reference type of operator() when we
82  // need it, but it writing it includes it when we can't, e.g. if op(...) doesn't return a
83  // reference.
84  template <class Idx>
85  NDARRAY_INLINE decltype(op(Is...)) operator()(const Idx& i) const {
86  return op(std::get<Is>(i)...);
87  }
88 
89  // Only ein_op has assignment operators.
90  template <class T, class = enable_if_ein_op<T>>
91  auto operator=(const T& r) const {
92  return make_ein_op_assign(*this, r);
93  }
94  template <class T, class = enable_if_ein_op<T>>
95  auto operator+=(const T& r) const {
96  return make_ein_op_add_assign(*this, r);
97  }
98  template <class T, class = enable_if_ein_op<T>>
99  auto operator-=(const T& r) const {
100  return make_ein_op_sub_assign(*this, r);
101  }
102  template <class T, class = enable_if_ein_op<T>>
103  auto operator*=(const T& r) const {
104  return make_ein_op_mul_assign(*this, r);
105  }
106 };
107 
108 // A unary operation on an Einstein operand.
109 template <class Op, class Derived>
110 struct ein_unary_op : public ein_op_base<Derived> {
111  Op op;
112  ein_unary_op(const Op& op) : op(op) {}
113  static constexpr index_t MaxIndex = Op::MaxIndex;
114 };
115 
116 // Unary negate.
117 template <class Op>
118 struct ein_negate_op : public ein_unary_op<Op, ein_negate_op<Op>> {
119  using base = ein_unary_op<Op, ein_negate_op<Op>>;
120  ein_negate_op(const Op& op) : base(op) {}
121  template <class Idx>
122  NDARRAY_INLINE auto operator()(const Idx& i) const {
123  return -base::op(i);
124  }
125 };
126 
127 template <class Op>
128 auto make_ein_op_negate(const Op& op) {
129  return ein_negate_op<Op>(op);
130 }
131 
132 // Cast to a different type.
133 template <class Type, class Op>
134 struct ein_cast_op : public ein_unary_op<Op, ein_cast_op<Type, Op>> {
135  using base = ein_unary_op<Op, ein_cast_op<Type, Op>>;
136  ein_cast_op(const Op& op) : base(op) {}
137  template <class Idx>
138  NDARRAY_INLINE auto operator()(const Idx& i) const {
139  return static_cast<Type>(base::op(i));
140  }
141 };
142 
143 // A binary operation of two operands.
144 template <class OpA, class OpB, class Derived>
145 struct ein_binary_op : public ein_op_base<Derived> {
146  OpA op_a;
147  OpB op_b;
148  ein_binary_op(const OpA& a, const OpB& b) : op_a(a), op_b(b) {}
149  static constexpr index_t MaxIndex = internal::max(OpA::MaxIndex, OpB::MaxIndex);
150 };
151 
152 #define NDARRAY_MAKE_EIN_BINARY_HELPERS(name, op) \
153  template <class OpA, class OpB> \
154  auto make_##name(const OpA& a, const OpB& b) { \
155  return name<OpA, OpB>(a, b); \
156  }
157 
158 #define NDARRAY_MAKE_EIN_BINARY_OP(name, op, is_assign_) \
159  template <class OpA, class OpB> \
160  struct name : public ein_binary_op<OpA, OpB, name<OpA, OpB>> { \
161  using base = ein_binary_op<OpA, OpB, name>; \
162  name(const OpA& a, const OpB& b) : base(a, b) {} \
163  using is_assign = is_assign_; \
164  template <class Idx> \
165  NDARRAY_INLINE auto operator()(const Idx& i) const { \
166  return base::op_a(i) op base::op_b(i); \
167  } \
168  }; \
169  NDARRAY_MAKE_EIN_BINARY_HELPERS(name, op)
170 
171 #define NDARRAY_MAKE_EIN_BINARY_FN(name, fn) \
172  template <class OpA, class OpB> \
173  struct name : public ein_binary_op<OpA, OpB, name<OpA, OpB>> { \
174  using base = ein_binary_op<OpA, OpB, name>; \
175  name(const OpA& a, const OpB& b) : base(a, b) {} \
176  template <class Idx> \
177  NDARRAY_INLINE auto operator()(const Idx& i) const { \
178  using internal::min; \
179  using internal::max; \
180  return fn(base::op_a(i), base::op_b(i)); \
181  } \
182  }; \
183  NDARRAY_MAKE_EIN_BINARY_HELPERS(name, op)
184 
185 // Define the expression types for the operations we support.
186 NDARRAY_MAKE_EIN_BINARY_OP(ein_op_add, +, std::false_type);
187 NDARRAY_MAKE_EIN_BINARY_OP(ein_op_sub, -, std::false_type);
188 NDARRAY_MAKE_EIN_BINARY_OP(ein_op_mul, *, std::false_type);
189 NDARRAY_MAKE_EIN_BINARY_OP(ein_op_div, /, std::false_type);
190 NDARRAY_MAKE_EIN_BINARY_FN(ein_op_min, min);
191 NDARRAY_MAKE_EIN_BINARY_FN(ein_op_max, max);
192 
193 NDARRAY_MAKE_EIN_BINARY_OP(ein_op_assign, =, std::true_type);
194 NDARRAY_MAKE_EIN_BINARY_OP(ein_op_add_assign, +=, std::true_type);
195 NDARRAY_MAKE_EIN_BINARY_OP(ein_op_sub_assign, -=, std::true_type);
196 NDARRAY_MAKE_EIN_BINARY_OP(ein_op_mul_assign, *=, std::true_type);
197 
198 #undef NDARRAY_MAKE_EIN_BINARY_FN
199 #undef NDARRAY_MAKE_EIN_BINARY_OP
200 #undef NDARRAY_MAKE_EIN_BINARY_HELPERS
201 
202 } // namespace internal
203 
206 template <class Type, class Op>
207 auto cast(const internal::ein_op_base<Op>& op) {
208  return internal::ein_cast_op<Type, Op>(op.derived());
209 }
210 
212 template <class OpA, class OpB>
213 auto min(const internal::ein_op_base<OpA>& a, const internal::ein_op_base<OpB>& b) {
214  return internal::make_ein_op_min(a.derived(), b.derived());
215 }
216 template <class OpA, class OpB>
217 auto max(const internal::ein_op_base<OpA>& a, const internal::ein_op_base<OpB>& b) {
218  return internal::make_ein_op_max(a.derived(), b.derived());
219 }
220 
221 namespace internal {
222 
223 // Let these be found via ADL too.
224 using nda::cast;
225 using nda::max;
226 using nda::min;
227 
228 // If multiple operands provide the same dim, we need to reconcile them
229 // to one dim. If you follow a compiler or runtime error here, your
230 // Einstein expression tries to address two dimensions that have different
231 // bounds with the same loop variable.
232 // TODO: It would be nice if this error would appear when constructing the
233 // Einstein expression when possible, but that's really hard to do.
234 template <class Dim0, class... Dims,
235  class = std::enable_if_t<!any(not_equal(Dim0::Min, Dims::Min)...)>,
236  class = std::enable_if_t<!any(not_equal(Dim0::Extent, Dims::Extent)...)>>
237 NDARRAY_INLINE const Dim0& reconcile_dim(const Dim0& dim0, const Dims&... dims) {
238  if (dim0.stride() != 0) {
239  // If the first dim is an output dimension, just require the other dims
240  // to be in-bounds. This is a slightly relaxed requirement compared to the
241  // compile-time constraints.
242  assert(all(dims.is_in_range(dim0)...));
243  } else {
244  // If this is a reduction dimension, all of the dims must match. For
245  // example, this is the constraint that checks that the inner dimensions of
246  // a matrix multiplication are compatible.
247  assert(all(dim0.min() == dims.min()...));
248  assert(all(dim0.extent() == dims.extent()...));
249  }
250  return dim0;
251 }
252 // If we have zero dims, the user skipped a dim index, so we need a dummy
253 // loop.
254 NDARRAY_INLINE dim<0, 1, 0> reconcile_dim() { return {}; }
255 
256 template <class... Dims, size_t... Is>
257 NDARRAY_INLINE auto reconcile_dim(const std::tuple<Dims...>& dims, index_sequence<Is...>) {
258  return reconcile_dim(std::get<Is>(dims)...);
259 }
260 template <class... Dims>
261 NDARRAY_INLINE auto reconcile_dim(const std::tuple<Dims...>& dims) {
262  return reconcile_dim(dims, make_index_sequence<sizeof...(Dims)>());
263 }
264 
265 // Get the shape of an ein_reduce operand, or an empty shape if not an array.
266 template <class T, class Shape>
267 NDARRAY_INLINE const auto& dims_of(const array_ref<T, Shape>& op) {
268  return op.shape().dims();
269 }
270 template <class T>
271 NDARRAY_INLINE std::tuple<> dims_of(const T& op) {
272  return std::tuple<>();
273 }
274 
275 // Helper to reinterpret a dim with a new stride.
276 template <index_t NewStride, index_t Min, index_t Extent, index_t Stride>
277 NDARRAY_INLINE auto with_stride(const dim<Min, Extent, Stride>& d) {
278  return dim<Min, Extent, NewStride>(d.min(), d.extent());
279 }
280 template <index_t NewStride, class Dim>
281 NDARRAY_INLINE auto with_stride(const std::tuple<Dim>& maybe_dim) {
282  return std::make_tuple(with_stride<NewStride>(std::get<0>(maybe_dim)));
283 }
284 template <index_t NewStride>
285 NDARRAY_INLINE std::tuple<> with_stride(std::tuple<> maybe_dim) {
286  return maybe_dim;
287 }
288 
289 // These types are flags that let us overload behavior based on these 3 options.
290 class is_inferred_shape {};
291 class is_result_shape {};
292 class is_operand_shape {};
293 
294 // Get a dim from an operand, depending on the intended use of the shape.
295 template <size_t Dim, class Dims, size_t... Is>
296 NDARRAY_INLINE auto gather_dims(is_result_shape, const ein_op<Dims, Is...>& op) {
297  // If this is part of the result, we want to keep its strides.
298  return get_or_empty<index_of<Dim, Is...>()>(dims_of(op.op));
299 }
300 template <size_t Dim, class Dims, size_t... Is>
301 NDARRAY_INLINE auto gather_dims(is_inferred_shape, const ein_op<Dims, Is...>& op) {
302  // For inferred shapes, we want shapes without any constexpr strides, so it can be reshaped.
303  return with_stride<dynamic>(get_or_empty<index_of<Dim, Is...>()>(dims_of(op.op)));
304 }
305 template <size_t Dim, class Dims, size_t... Is>
306 NDARRAY_INLINE auto gather_dims(is_operand_shape, const ein_op<Dims, Is...>& op) {
307  // If this is an operand shape, we want all of its dimensions to be stride 0.
308  return with_stride<0>(get_or_empty<index_of<Dim, Is...>()>(dims_of(op.op)));
309 }
310 
311 template <size_t Dim, class Kind, class Op, class X>
312 NDARRAY_INLINE auto gather_dims(Kind kind, const ein_unary_op<Op, X>& op) {
313  return gather_dims<Dim>(kind, op.op);
314 }
315 template <size_t Dim, class Kind, class OpA, class OpB, class X>
316 NDARRAY_INLINE auto gather_dims(Kind kind, const ein_binary_op<OpA, OpB, X>& op) {
317  return std::tuple_cat(gather_dims<Dim>(kind, op.op_a), gather_dims<Dim>(kind, op.op_b));
318 }
319 
320 template <size_t Dim, class Kind0, class Op0, class Kind1, class Op1>
321 NDARRAY_INLINE auto gather_dims(Kind0 kind0, const Op0& op0, Kind1 kind1, const Op1& op1) {
322  return std::tuple_cat(gather_dims<Dim>(kind0, op0), gather_dims<Dim>(kind1, op1));
323 }
324 template <size_t... Is, class... KindAndOps>
325 NDARRAY_UNIQUE auto make_ein_reduce_shape(
326  index_sequence<Is...>, const KindAndOps&... kind_and_ops) {
327  return make_shape(reconcile_dim(gather_dims<Is>(kind_and_ops...))...);
328 }
329 
330 } // namespace internal
331 
338 template <size_t... Is, class Op, class = internal::enable_if_callable<Op, decltype(Is)...>>
339 auto ein(Op op) {
340  return internal::ein_op<Op, Is...>(std::move(op));
341 }
342 template <size_t... Is, class T, class Shape, class Alloc,
343  class = std::enable_if_t<sizeof...(Is) == Shape::rank()>>
344 auto ein(array<T, Shape, Alloc>& op) {
345  return ein<Is...>(op.ref());
346 }
347 template <size_t... Is, class T, class Shape, class Alloc,
348  class = std::enable_if_t<sizeof...(Is) == Shape::rank()>>
349 auto ein(const array<T, Shape, Alloc>& op) {
350  return ein<Is...>(op.ref());
351 }
352 
358 template <class T>
359 auto ein(T& scalar) {
360  return ein<>(array_ref<T, shape<>>(&scalar, {}));
361 }
362 
364 template <size_t I0, class T>
365 auto ein(T* x, size_t N) {
366  return ein<I0>(make_array_ref(&x[0], shape<dim<0, dynamic, 1>>(static_cast<index_t>(N))));
367 }
368 
370 template <size_t I0, class T, size_t N>
371 auto ein(T (&x)[N]) {
372  return ein<I0>(make_array_ref(&x[0], shape<dim<0, N, 1>>()));
373 }
374 
418 template <class Expr, class = internal::enable_if_ein_assign<Expr>>
419 NDARRAY_INLINE auto ein_reduce(const Expr& expr) {
420  constexpr index_t LoopRank = Expr::MaxIndex + 1;
421 
422  // Gather the dimensions identified by the indices. gather_dims keeps the
423  // first dimension it finds, so we want that to be the result dimension if it
424  // is present. If not, this selects one of the operand dimensions, which are
425  // given stride 0.
426  auto reduction_shape = internal::make_ein_reduce_shape(internal::make_index_sequence<LoopRank>(),
427  internal::is_result_shape(), expr.op_a, internal::is_operand_shape(), expr.op_b);
428 
429  // TODO: Try to compile-time optimize reduction_shape? :)
430  // This is maybe actually somewhat doable, simply moving the for_each_index
431  // call below into a function that could be overloaded based on the type of
432  // the shape would enable different optimizations. This function could be a
433  // member of a template parameter/parameter of this function, enabling the
434  // caller to customize the optimization. However, it's still very difficult
435  // to make useful optimizations without making some assumptions about the
436  // dimensions of the shape.
437 
438  // Perform the reduction.
439  for_each_index_in_order(reduction_shape, expr);
440 
441  // Assume the expr is an assignment, and return the left-hand side.
442  return expr.op_a.op;
443 }
444 
446 template <size_t... ResultIs, class Expr, class = internal::enable_if_ein_op<Expr>>
447 NDARRAY_UNIQUE auto make_ein_reduce_shape(const Expr& expr) {
448  auto result_shape = internal::make_ein_reduce_shape(
449  internal::index_sequence<ResultIs...>(), internal::is_inferred_shape(), expr);
450  return make_compact(result_shape);
451 }
452 
472 // TODO: It would be nice to be able to express reductions other than sums.
473 // TODO: Add an overload with a default ResultIs... = 0, 1, 2, ... This requires
474 // also inferring the rank of the result.
475 template <class T, size_t... ResultIs, class Expr, class Alloc = std::allocator<T>,
476  class = internal::enable_if_ein_op<Expr>>
477 NDARRAY_INLINE auto make_ein_sum(
478  const Expr& expr, const T& init = T(), const Alloc& alloc = Alloc()) {
479  auto result_shape = make_ein_reduce_shape<ResultIs...>(expr);
480  auto result = make_array<T>(result_shape, init, alloc);
481  ein_reduce(ein<ResultIs...>(result) += expr);
482  return result;
483 }
484 
485 } // namespace nda
486 
487 #endif // NDARRAY_EIN_REDUCE_H
NDARRAY_HOST_DEVICE Shape & shape()
Definition: array.h:2095
+
NDARRAY_INLINE auto ein_reduce(const Expr &expr)
Definition: ein_reduce.h:419
+
Definition: array.h:1036
+
NDARRAY_HOST_DEVICE array_ref< T, Shape > make_array_ref(T *base, const Shape &shape)
Definition: array.h:1962
+
const interval< 0,-1 > all
Definition: array.h:363
+
auto ein(Op op)
Definition: ein_reduce.h:339
+
Definition: array.h:1953
+
Definition: array.h:1955
+
NDARRAY_INLINE auto make_ein_sum(const Expr &expr, const T &init=T(), const Alloc &alloc=Alloc())
Definition: ein_reduce.h:477
+
auto cast(const internal::ein_op_base< Op > &op)
Definition: ein_reduce.h:207
+
Main header for array library.
+
Definition: absl.h:10
+
void move(const array_ref< TSrc, ShapeSrc > &src, const array_ref< TDst, ShapeDst > &dst)
Definition: array.h:2792
+
NDARRAY_HOST_DEVICE auto make_shape(Dims...dims)
Definition: array.h:1040
+
std::ptrdiff_t index_t
Definition: array.h:87
+
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t min() const
Definition: array.h:293
+
Definition: array.h:231
+
NDARRAY_HOST_DEVICE auto make_compact(const Shape &s)
Definition: array.h:1620
+
auto min(const internal::ein_op_base< OpA > &a, const internal::ein_op_base< OpB > &b)
Definition: ein_reduce.h:213
+
array_ref< T, Shape > ref()
Definition: array.h:2665
+
NDARRAY_INLINE NDARRAY_HOST_DEVICE index_t extent() const
Definition: array.h:296
+
+ + + + diff --git a/files.html b/files.html new file mode 100644 index 00000000..d0f771f3 --- /dev/null +++ b/files.html @@ -0,0 +1,110 @@ + + + + + + +array: File List + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + +
+ +
+
+ + +
+ +
+ +
+
+
File List
+
+
+
Here is a list of all documented files with brief descriptions:
+
[detail level 123]
+ + + + + + + + + +
  absl
 absl.h
  include
  array
 array.hMain header for array library
 ein_reduce.hOptional helper for computing Einstein reductions on arrays
 image.hOptional image-specific helpers and specializations
 matrix.hOptional matrix-specific helpers and specializations
 z_order.hHelpers for traversing multi-dimensional ranges in z-order
+
+
+ + + + diff --git a/folderclosed.png b/folderclosed.png new file mode 100644 index 0000000000000000000000000000000000000000..bb8ab35edce8e97554e360005ee9fc5bffb36e66 GIT binary patch literal 616 zcmV-u0+;=XP)a9#ETzayK)T~Jw&MMH>OIr#&;dC}is*2Mqdf&akCc=O@`qC+4i z5Iu3w#1M@KqXCz8TIZd1wli&kkl2HVcAiZ8PUn5z_kG@-y;?yK06=cA0U%H0PH+kU zl6dp}OR(|r8-RG+YLu`zbI}5TlOU6ToR41{9=uz^?dGTNL;wIMf|V3`d1Wj3y!#6` zBLZ?xpKR~^2x}?~zA(_NUu3IaDB$tKma*XUdOZN~c=dLt_h_k!dbxm_*ibDM zlFX`g{k$X}yIe%$N)cn1LNu=q9_CS)*>A zsX_mM4L@`(cSNQKMFc$RtYbx{79#j-J7hk*>*+ZZhM4Hw?I?rsXCi#mRWJ=-0LGV5a-WR0Qgt<|Nqf)C-@80`5gIz45^_20000IqP)X=#(TiCT&PiIIVc55T}TU}EUh*{q$|`3@{d>{Tc9Bo>e= zfmF3!f>fbI9#GoEHh0f`i5)wkLpva0ztf%HpZneK?w-7AK@b4Itw{y|Zd3k!fH?q2 zlhckHd_V2M_X7+)U&_Xcfvtw60l;--DgZmLSw-Y?S>)zIqMyJ1#FwLU*%bl38ok+! zh78H87n`ZTS;uhzAR$M`zZ`bVhq=+%u9^$5jDplgxd44}9;IRqUH1YHH|@6oFe%z( zo4)_>E$F&^P-f(#)>(TrnbE>Pefs9~@iN=|)Rz|V`sGfHNrJ)0gJb8xx+SBmRf@1l zvuzt=vGfI)<-F9!o&3l?>9~0QbUDT(wFdnQPv%xdD)m*g%!20>Bc9iYmGAp<9YAa( z0QgYgTWqf1qN++Gqp z8@AYPTB3E|6s=WLG?xw0tm|U!o=&zd+H0oRYE;Dbx+Na9s^STqX|Gnq%H8s(nGDGJ j8vwW|`Ts`)fSK|Kx=IK@RG@g200000NkvXXu0mjfauFEA literal 0 HcmV?d00001 diff --git a/functions.html b/functions.html new file mode 100644 index 00000000..d58bec93 --- /dev/null +++ b/functions.html @@ -0,0 +1,368 @@ + + + + + + +array: Class Members + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- a -

+ + +

- b -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- i -

+ + +

- m -

+ + +

- o -

+ + +

- r -

+ + +

- s -

+ + +

- v -

+ + +

- w -

+ + +

- x -

+
+ + + + diff --git a/functions_func.html b/functions_func.html new file mode 100644 index 00000000..6bbde351 --- /dev/null +++ b/functions_func.html @@ -0,0 +1,346 @@ + + + + + + +array: Class Members - Functions + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- a -

+ + +

- b -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- i -

+ + +

- m -

+ + +

- o -

+ + +

- r -

+ + +

- s -

+ + +

- w -

+ + +

- x -

+
+ + + + diff --git a/functions_type.html b/functions_type.html new file mode 100644 index 00000000..b7cdacbe --- /dev/null +++ b/functions_type.html @@ -0,0 +1,122 @@ + + + + + + +array: Class Members - Typedefs + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+ +
+
+ + +
+ +
+ +
+
+ + + + diff --git a/hierarchy.html b/hierarchy.html new file mode 100644 index 00000000..b2bea003 --- /dev/null +++ b/hierarchy.html @@ -0,0 +1,118 @@ + + + + + + +array: Class Hierarchy + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class Hierarchy
+
+ + + + + diff --git a/image_8h.html b/image_8h.html new file mode 100644 index 00000000..d00853c8 --- /dev/null +++ b/image_8h.html @@ -0,0 +1,403 @@ + + + + + + +array: include/array/image.h File Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
image.h File Reference
+
+
+ +

Optional image-specific helpers and specializations. +More...

+
#include "array/array.h"
+
+

Go to the source code of this file.

+ + + + + + +

+Classes

class  shape_traits< chunky_image_shape< Channels, XStride > >
 
class  shape_traits< chunky_image_shape< Channels > >
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Typedefs

using image_shape = shape< dim<>, dim<>, dim<>>
 
+template<class T , class Alloc = std::allocator<T>>
using image = array< T, image_shape, Alloc >
 
+template<class T >
using image_ref = array_ref< T, image_shape >
 
+template<class T >
using const_image_ref = image_ref< const T >
 
template<index_t Channels = dynamic, index_t XStride = Channels>
using chunky_image_shape = shape< strided_dim< XStride >, dim<>, dense_dim< 0, Channels >>
 
+template<class T , index_t Channels = dynamic, index_t XStride = Channels, class Alloc = std::allocator<T>>
using chunky_image = array< T, chunky_image_shape< Channels, XStride >, Alloc >
 
+template<class T , index_t Channels = dynamic, index_t XStride = Channels>
using chunky_image_ref = array_ref< T, chunky_image_shape< Channels, XStride >>
 
+template<class T , index_t Channels = dynamic, index_t XStride = Channels>
using const_chunky_image_ref = chunky_image_ref< const T, Channels, XStride >
 
using planar_image_shape = shape< dense_dim<>, dim<>, dim<>>
 
+template<class T , class Alloc = std::allocator<T>>
using planar_image = array< T, planar_image_shape, Alloc >
 
+template<class T >
using planar_image_ref = array_ref< T, planar_image_shape >
 
+template<class T >
using const_planar_image_ref = planar_image_ref< const T >
 
+ + + +

+Enumerations

enum  crop_origin { zero, +crop + }
 
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

template<class Shape , class Fn >
void for_each_image_index (const Shape &s, Fn &&fn)
 
template<class Shape >
Shape crop_image_shape (Shape s, index_t x0, index_t y0, index_t x1, index_t y1, crop_origin origin=crop_origin::crop)
 
template<class T , class Shape >
array_ref< T, Shape > crop (const array_ref< T, Shape > &im, index_t x0, index_t y0, index_t x1, index_t y1, crop_origin origin=crop_origin::crop)
 
+template<class T , class Shape >
array_ref< const T, Shape > crop (const array< T, Shape > &im, index_t x0, index_t y0, index_t x1, index_t y1, crop_origin origin=crop_origin::crop)
 
+template<class T , class Shape >
array_ref< T, Shape > crop (array< T, Shape > &im, index_t x0, index_t y0, index_t x1, index_t y1, crop_origin origin=crop_origin::crop)
 
template<class T , class Shape >
auto slice_channel (const array_ref< T, Shape > &im, index_t channel)
 
+template<class T , class Shape , class Alloc >
auto slice_channel (const array< T, Shape, Alloc > &im, index_t channel)
 
+template<class T , class Shape , class Alloc >
auto slice_channel (array< T, Shape, Alloc > &im, index_t channel)
 
+

Detailed Description

+

Optional image-specific helpers and specializations.

+

Typedef Documentation

+ +
+
+ + + + +
using image_shape = shape<dim<>, dim<>, dim<>>
+
+

A generic image is any 3D array with dimensions x, y, c. c represents the channels of the image, typically it will have extent 3 or 4, with red, green, and blue mapped to indices in this dimension.

+ +
+
+ +
+
+ + + + +
using chunky_image_shape = shape<strided_dim<XStride>, dim<>, dense_dim<0, Channels>>
+
+

A 'chunky' image is an array with 3 dimensions x, y, c, where c is dense, and the dimension with the next stride is x. The stride in x may be larger than the number of channels, to allow for padding pixels to a convenient alignment. This is a common image storage format used by many programs working with images.

+ +
+
+ +
+
+ + + + +
using planar_image_shape = shape<dense_dim<>, dim<>, dim<>>
+
+

A 'planar' image is an array with dimensions x, y, c, where x is dense. This format is less common, but more convenient for optimization, particularly SIMD vectorization. Note that this shape also supports 'line-chunky' storage orders.

+ +
+
+

Function Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + +
void nda::for_each_image_index (const Shape & s,
Fn && fn 
)
+
+

Calls fn for each index in an image shape s. c is the innermost dimension of the loop nest.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Shape nda::crop_image_shape (Shape s,
index_t x0,
index_t y0,
index_t x1,
index_t y1,
crop_origin origin = crop_origin::crop 
)
+
+

Crop an image shape s to the indices [x0, x1) x [y0, y1). The origin of the new shape is determined by origin.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
array_ref<T, Shape> nda::crop (const array_ref< T, Shape > & im,
index_t x0,
index_t y0,
index_t x1,
index_t y1,
crop_origin origin = crop_origin::crop 
)
+
+

Crop the im image or image ref to the interval [x0, x1) x [y0, y1). The result is a ref of the input image. The origin of the result is determined by origin.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
auto nda::slice_channel (const array_ref< T, Shape > & im,
index_t channel 
)
+
+

Get a 2-dimensional ref of the Channel channel of the im image or image ref.

+ +
+
+
+ + + + diff --git a/image_8h_source.html b/image_8h_source.html new file mode 100644 index 00000000..27669ef1 --- /dev/null +++ b/image_8h_source.html @@ -0,0 +1,123 @@ + + + + + + +array: include/array/image.h Source File + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
image.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
18 #ifndef NDARRAY_IMAGE_H
19 #define NDARRAY_IMAGE_H
20 
21 #include "array/array.h"
22 
23 namespace nda {
24 
28 using image_shape = shape<dim<>, dim<>, dim<>>;
29 template <class T, class Alloc = std::allocator<T>>
31 template <class T>
33 template <class T>
35 
41 template <index_t Channels = dynamic, index_t XStride = Channels>
43 template <class T, index_t Channels = dynamic, index_t XStride = Channels,
44  class Alloc = std::allocator<T>>
46 template <class T, index_t Channels = dynamic, index_t XStride = Channels>
48 template <class T, index_t Channels = dynamic, index_t XStride = Channels>
50 
53 template <class Shape, class Fn>
54 void for_each_image_index(const Shape& s, Fn&& fn) {
55  // Images should always be iterated with c as the innermost loop. Even when
56  // the image is planar, the number of channels is generally small, and many
57  // operations use all of the channels at the same time (all-to-all
58  // communication in the c dimension).
59  for (index_t y : s.y()) {
60  for (index_t x : s.x()) {
61  for (index_t c : s.c()) {
62  fn(std::tuple<index_t, index_t, index_t>(x, y, c));
63  }
64  }
65  }
66 }
67 
68 template <index_t Channels, index_t XStride>
69 class shape_traits<chunky_image_shape<Channels, XStride>> {
70 public:
72 
73  template <class Fn>
74  static void for_each_index(const shape_type& s, Fn&& fn) {
75  for_each_image_index(s, fn);
76  }
77 
78  template <class Ptr, class Fn>
79  static void for_each_value(const shape_type& s, Ptr base, Fn&& fn) {
81  s, [=, fn = std::move(fn)](const typename shape_type::index_type& i) { fn(base[s[i]]); });
82  }
83 };
84 
85 template <index_t Channels>
86 class shape_traits<chunky_image_shape<Channels>> {
87 public:
89 
90  template <class Fn>
91  static void for_each_index(const shape_type& s, Fn&& fn) {
92  for_each_image_index(s, fn);
93  }
94 
95  // When Channels == XStride, we can implement for_each_value by fusing
96  // the x and c dimensions.
97  template <class Ptr, class Fn>
98  static void for_each_value(const shape_type& s, Ptr base, Fn&& fn) {
99  const index_t channels = s.c().extent();
100  if (channels == s.x().stride()) {
101  dense_shape<2> opt_s({s.x().min() * channels, s.x().extent() * channels}, s.y());
102  for_each_value_in_order(opt_s, base, fn);
103  } else {
104  for_each_value_in_order(s, base, fn);
105  }
106  }
107 };
108 
113 using planar_image_shape = shape<dense_dim<>, dim<>, dim<>>;
114 template <class T, class Alloc = std::allocator<T>>
116 template <class T>
118 template <class T>
120 
121 enum class crop_origin {
123  zero,
126  crop,
127 };
128 
131 template <class Shape>
132 Shape crop_image_shape(Shape s, index_t x0, index_t y0, index_t x1, index_t y1,
133  crop_origin origin = crop_origin::crop) {
134  s.x().set_extent(x1 - x0);
135  s.y().set_extent(y1 - y0);
136  switch (origin) {
137  case crop_origin::zero:
138  s.x().set_min(0);
139  s.y().set_min(0);
140  break;
141  case crop_origin::crop:
142  s.x().set_min(x0);
143  s.y().set_min(y0);
144  break;
145  }
146  return s;
147 }
148 
152 template <class T, class Shape>
154  index_t y1, crop_origin origin = crop_origin::crop) {
155  x0 = internal::max(x0, im.x().min());
156  y0 = internal::max(y0, im.y().min());
157  x1 = internal::min(x1, im.x().max() + 1);
158  y1 = internal::min(y1, im.y().max() + 1);
159  Shape cropped_shape = crop_image_shape(im.shape(), x0, y0, x1, y1, origin);
160  index_t c0 = im.c().min();
161  T* base = im.base() != nullptr ? &im(x0, y0, c0) : nullptr;
162  if (origin == crop_origin::crop) {
163  base = internal::pointer_add(base, -cropped_shape(x0, y0, c0));
164  }
165  return array_ref<T, Shape>(base, cropped_shape);
166 }
167 template <class T, class Shape>
169  index_t y1, crop_origin origin = crop_origin::crop) {
170  return crop(im.ref(), x0, y0, x1, y1, origin);
171 }
172 template <class T, class Shape>
174  crop_origin origin = crop_origin::crop) {
175  return crop(im.ref(), x0, y0, x1, y1, origin);
176 }
177 
180 template <class T, class Shape>
181 auto slice_channel(const array_ref<T, Shape>& im, index_t channel) {
182  return im(im.x(), im.y(), channel);
183 }
184 template <class T, class Shape, class Alloc>
185 auto slice_channel(const array<T, Shape, Alloc>& im, index_t channel) {
186  return slice_channel(im.ref(), channel);
187 }
188 template <class T, class Shape, class Alloc>
189 auto slice_channel(array<T, Shape, Alloc>& im, index_t channel) {
190  return slice_channel(im.ref(), channel);
191 }
192 
193 } // namespace nda
194 
195 #endif // NDARRAY_IMAGE_H
NDARRAY_HOST_DEVICE Shape & shape()
Definition: array.h:2095
+
constexpr index_t dynamic
Definition: array.h:99
+
index_of_rank< rank()> index_type
Definition: array.h:1076
+
Definition: array.h:1036
+
static NDARRAY_HOST_DEVICE void for_each_value(const Shape &shape, Ptr base, Fn &&fn)
Definition: array.h:1874
+
Definition: array.h:1953
+
Definition: array.h:1955
+
NDARRAY_HOST_DEVICE pointer base() const
Definition: array.h:2086
+
Shape crop_image_shape(Shape s, index_t x0, index_t y0, index_t x1, index_t y1, crop_origin origin=crop_origin::crop)
Definition: image.h:132
+
NDARRAY_HOST_DEVICE auto & x()
Definition: array.h:1274
+
Main header for array library.
+
Definition: absl.h:10
+
auto slice_channel(const array_ref< T, Shape > &im, index_t channel)
Definition: image.h:181
+
Definition: array.h:1859
+
array_ref< T, Shape > crop(const array_ref< T, Shape > &im, index_t x0, index_t y0, index_t x1, index_t y1, crop_origin origin=crop_origin::crop)
Definition: image.h:153
+
NDARRAY_HOST_DEVICE auto & x()
Definition: array.h:2122
+
void for_each_image_index(const Shape &s, Fn &&fn)
Definition: image.h:54
+
std::ptrdiff_t index_t
Definition: array.h:87
+
Definition: array.h:231
+
static NDARRAY_HOST_DEVICE void for_each_index(const Shape &shape, Fn &&fn)
Definition: array.h:1866
+
array_ref< T, Shape > ref()
Definition: array.h:2665
+
decltype(internal::make_default_dense_shape< Rank >()) dense_shape
Definition: array.h:1606
+
+ + + + diff --git a/index.html b/index.html new file mode 100644 index 00000000..e0c7a089 --- /dev/null +++ b/index.html @@ -0,0 +1,154 @@ + + + + + + +array: About + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + +
+ +
+
+ + +
+ +
+ +
+
+
About
+
+
+

This library provides a multidimensional array class for C++, with the following design goals:

    +
  • Enable specification of array parameters as compile-time constants per parameter, enabling more efficient code generation, while retaining run-time flexibility where needed.
  • +
  • Provide an API following the conventions of the C++ STL where possible.
  • +
  • Minimal dependencies and requirements (the library is currently a single header file, and depends only on the C++ STL).
  • +
+

The library uses some ideas established in other existing projects, such as numpy, Halide, and Eigen. Array shapes are specified as a list of N dimensions, where each dimension has parameters such as an extent and a stride. Array references and objects use shape objects to map N-dimensional indices to a flat index. N-dimensional indices are mapped to flat offsets with the following formula:

1 flat_offset = (x0 - min0)*stride0 + (x1 - min1)*stride1 + ... + (xN - minN)*strideN

where:

    +
  • xN are the indices in each dimension.
  • +
  • minN are the mins in each dimension. The min is the value of the first in-range index in this dimension (the max is minN + extentN - 1).
  • +
  • strideN are the distances in the flat offsets between elements in each dimension.
  • +
+

Arrays efficiently support advanced manipulations like cropping, slicing, and splitting arrays and loops, all while preserving compile-time constant parameters when possible. Although it is a heavily templated library, incorrect usage generates informative and helpful error messages. Typically, an issue will result in only one error message, located at the site of the problem in user code. This is something we test for.

+

Many other libraries offering multi-dimensional arrays or tensors allow compile-time constant shapes. However, most if not all of them only allow either all of the shape parameters to be compile-time constant, or none of them. This is really limiting; often only a few key parameters of a shape need to be compile-time constant for performance, while other dimensions need flexibility to accommodate runtime-valued shape parameters. Some examples of this are:

    +
  • 'Chunky' image formats with a small fixed number of channels.
  • +
  • Matrices where one dimension represent variables intrinsic to the problem, while the other dimension represents a number of samples of data.
  • +
  • Algorithms optimized by splitting or tiling intermediate stages will have intermediate buffers that have a constant extent in the dimensions that are split or tiled.
  • +
+

Some other features of the library are:

    +
  • CUDA support for use in __device__ functions.
  • +
  • Einstein reduction helpers, enabling many kinds of reductions and other array operations to be expressed safely.
  • +
+

For more detailed documentation, see the generated documentation.

+

Usage

+

Shapes

+

The basic types provided by the library are:

    +
  • dim<Min, Extent, Stride>, a description of a single dimension. The template parameters specify a compile-time constant min, extent, or stride, or are dynamic (meaning unknown) and are specified at runtime.
  • +
  • shape<Dim0, Dim1, ...>, a description of multiple dimensions. Dim0 is referred to as the innermost dimension.
  • +
  • array<T, Shape, Allocator>, a container following the conventions of std::vector where possible. This container manages the allocation of a buffer associated with a Shape.
  • +
  • array_ref<T, Shape>, a wrapper for addressing existing memory with a shape Shape.
  • +
+

To define an array, define a shape type, and use it to define an array object:

1 {c++}
2  using my_3d_shape_type = shape<dim<>, dim<>, dim<>>;
3  constexpr int width = 16;
4  constexpr int height = 10;
5  constexpr int depth = 3;
6  my_3d_shape_type my_3d_shape(width, height, depth);
7  array<int, my_3d_shape_type> my_array(my_3d_shape);

General shapes and arrays like this have the following built-in aliases:

    +
  • shape_of_rank<N>, an N-dimensional shape.
  • +
  • array_ref_of_rank<T, N> and array_of_rank<T, N, Allocator>, N-dimensional arrays with a shape of shape_of_rank<N>.
  • +
+

Access and iteration

+

Accessing array or array_ref is done via operator(...) and operator[index_type]. There are both variadic and index_type overloads of operator(). index_type is a specialization of std::tuple defined by shape (and array and array_ref), e.g. my_3d_shape_type::index_type.

1 {c++}
2  for (int z = 0; z < depth; z++) {
3  for (int y = 0; y < height; y++) {
4  for (int x = 0; x < width; x++) {
5  // Variadic version:
6  my_array(x, y, z) = 5;
7  // Or the index_type version:
8  my_array[{x, y, z}] = 5;
9  }
10  }
11  }

array::for_each_value and array_ref::for_each_value calls a function with a reference to each value in the array.

1 {c++}
2  my_array.for_each_value([](int& value) {
3  value = 5;
4  });

for_all_indices is a free function taking a shape object and a function to call with every index in the shape. for_each_index is similar, calling a free function with the index as an instance of the index type my_3d_shape_type::index_type.

1 {c++}
2  for_all_indices(my_3d_shape, [&](int x, int y, int z) {
3  my_array(x, y, z) = 5;
4  });
5  for_each_index(my_3d_shape, [&](my_3d_shape_type::index_type i) {
6  my_array[i] = 5;
7  });

The order in which each of for_each_value, for_each_index, and for_all_indices execute their traversal over the shape is defined by shape_traits<Shape>. The default implementation of shape_traits<Shape>::for_each_index iterates over the innermost dimension as the innermost loop, and proceeds in order to the outermost dimension.

1 {c++}
2  my_3d_shape_type my_shape(2, 2, 2);
3  for_all_indices(my_shape, [](int x, int y, int z) {
4  std::cout << x << ", " << y << ", " << z << std::endl;
5  });
6  // Output:
7  // 0, 0, 0
8  // 1, 0, 0
9  // 0, 1, 0
10  // 1, 1, 0
11  // 0, 0, 1
12  // 1, 0, 1
13  // 0, 1, 1
14  // 1, 1, 1

The default implementation of shape_traits<Shape>::for_each_value iterates over a dynamically optimized shape. The order will vary depending on the properties of the shape.

+

There are overloads of for_all_indices and for_each_index accepting a permutation to indicate the loop order. In this example, the permutation <2, 0, 1> iterates over the z dimension as the innermost loop, then x, then y.

1 {c++}
2  for_all_indices<2, 0, 1>(my_shape, [](int x, int y, int z) {
3  std::cout << x << ", " << y << ", " << z << std::endl;
4  });
5  // Output:
6  // 0, 0, 0
7  // 0, 0, 1
8  // 1, 0, 0
9  // 1, 0, 1
10  // 0, 1, 0
11  // 0, 1, 1
12  // 1, 1, 0
13  // 1, 1, 1

Compile-time constant shapes

+

In the previous examples, no array parameters are compile time constants, so all of these accesses and loops expand to a flat_offset expression where the mins, extents, and strides are runtime variables. This can prevent the compiler from generating efficient code. For example, the compiler may be able to auto-vectorize these loops, but if the stride of the dimension accessed by the vectorized loop is a runtime variable, the compiler will have to generate gathers and scatters instead of vector load and store instructions, even if the stride is one at runtime.

+

To avoid this, we need to make array parameters compile time constants. However, while making array parameters compile time constants helps the compiler generate efficient code, it also makes the program less flexible.

+

This library helps balance this tradeoff by enabling any of the array parameters to be compile time constants, but not require it. Which parameters should be made into compile time constants will vary depending on the use case. A common case is to make the innermost dimension have stride 1:

1 {c++}
2  using my_dense_3d_shape_type = shape<
3  dim</*Min=*/dynamic, /*Extent=*/dynamic, /*Stride=*/1>,
4  dim<>,
5  dim<>>;
6  array<char, my_dense_3d_shape_type> my_dense_array({16, 3, 3});
7  for (auto x : my_dense_array.x()) {
8  // The compiler knows that each loop iteration accesses
9  // elements that are contiguous in memory for contiguous x.
10  my_dense_array(x, y, z) = 0;
11  }

A dimension with unknown min and extent, and stride 1, is common enough that it has a built-in alias dense_dim<>, and shapes with a dense first dimension are common enough that shapes and arrays have the following built-in aliases:

    +
  • dense_shape<N>, an N-dimensional shape with the first dimension being dense.
  • +
  • dense_array_ref<T, N> and dense_array<T, N, Allocator>, N-dimensional arrays with a shape of dense_shape<N>.
  • +
+

There are other common examples that are easy to support. A very common array is an image where 3-channel RGB or 4-channel RGBA pixels are stored together in a 'chunky' format.

1 {c++}
2 template <int Channels, int XStride = Channels>
3 using chunky_image_shape = shape<
4  strided_dim</*Stride=*/XStride>,
5  dim<>,
6  dense_dim</*Min=*/0, /*Extent=*/Channels>>;
7 array<uint8_t, chunky_image_shape<3>> my_chunky_image({1920, 1080, {}});

strided_dim<> is another alias for dim<> where the min and extent are unknown, and the stride may be a compile-time constant. image.h is a small helper library of typical image shape and object types defined using arrays, including chunky_image_shape.

+

Another common example is matrices indexed (row, column) with the column dimension stored densely:

1 {c++}
2  using matrix_shape = shape<dim<>, dense_dim<>>;
3  array<double, matrix_shape> my_matrix({10, 4});
4  for (auto i : my_matrix.i()) {
5  for (auto j : my_matrix.j()) {
6  // This loop ordering is efficient for this type.
7  my_matrix(i, j) = 0.0;
8  }
9  }

There are also many use cases for matrices with small constant sizes. This library provides auto_allocator<T, N>, an std::allocator compatible allocator that only allocates buffers of N small fixed sized objects with automatic storage. This makes it possible to define a small matrix type that will not use any dynamic memory allocation:

1 {c++}
2 template <int M, int N>
3 using small_matrix_shape = shape<
4  dim<0, M>,
5  dense_dim<0, N>>;
6 template <typename T, int M, int N>
7 using small_matrix = array<T, small_matrix_shape<M, N>, auto_allocator<T, M*N>>;
8 small_matrix<float, 4, 4> my_small_matrix;
9 // my_small_matrix is only one fixed size allocation, no new/delete calls
10 // happen. sizeof(small_matrix) = sizeof(float) * 4 * 4 + (overhead)

matrix.h is a small helper library of typical matrix shape and object types defined using arrays, including the examples above.

+

Slicing, cropping, and splitting

+

Shapes and arrays can be sliced and cropped using interval<Min, Extent> objects, which are similar to dim<>s. They can have either a compile-time constant or runtime valued min and extent. range(begin, end) is a helper functions to construct an interval.

1 {c++}
2  // Slicing
3  array_ref_of_rank<int, 2> channel1 = my_array(_, _, 1);
4  array_ref_of_rank<int, 1> row4_channel2 = my_array(_, 4, 2);
5 
6  // Cropping
7  array_ref_of_rank<int, 3> top_left = my_array(interval<>{0, 2}, interval<>{0, 4}, _);
8  array_ref_of_rank<int, 2> center_channel0 = my_array(interval<>{1, 2}, interval<>{2, 4}, 0);

The _ or all constants are placeholders indicating the entire dimension should be preserved. Dimensions that are sliced are removed from the shape of the array.

+

When iterating a dim, it is possible to split it first by either a compile-time constant or a runtime-valued split factor. A split dim produces an iterator range that produces interval<> objects. This allows easy tiling of algorithms:

1 {c++}
2  constexpr index_t x_split_factor = 3;
3  const index_t y_split_factor = 5;
4  for (auto yo : split(my_array.y(), y_split_factor)) {
5  for (auto xo : split<x_split_factor>(my_array.x())) {
6  auto tile = my_array(xo, yo, _);
7  for (auto x : tile.x()) {
8  // The compiler knows this loop has a fixed extent x_split_factor!
9  tile(x, y, z) = x;
10  }
11  }
12  }

Both loops have extents that are not divided by their split factors. To avoid generating an array_ref referencing data out of bounds of the original array, the split iterators modify the last iteration. The behavior of each kind of split is different:

    +
  • Because the extent of yo can vary, it is reduced on the last iteration. This strategy can accommodate dimensions of any extent.
  • +
  • Because the extent of xo must be a constant, the last iteration will be shifted to overlap the previous iteration. This strategy requires the extent of the dimension being split is greater than the split factor (but not a multiple!)
  • +
+

Compile-time constant split factors produce ranges with compile-time extents, and shapes and arrays cropped with these ranges will have a corresponding dim<> with a compile-time constant extent. This allows potentially significant optimizations to be expressed relatively easily!

+

Einstein reductions

+

The ein_reduce.h header provides Einstein notation reductions and summation helpers, similar to np.einsum or tf.einsum. These are zero-cost abstractions for describing loops that allow expressing a wide variety of array operations. Einstein notation expression operands are constructed using the ein<i, j, ...>(x) helper function, where x can be any callable object, including an array<> or array_ref<>. i, j, ... are constexpr integers indicating which dimensions of the reduction operation are used to evaluate x. Therefore, the number of arguments of x must match the number of dimensions provided to ein. Operands can be combined into larger expressions using typical binary operators.

+

Einstein notation expressions can be evaluated using one of the following functions:

    +
  • ein_reduce(expression), evaluate an arbitrary Einstein notation expression.
  • +
  • lhs = make_ein_sum<T, i, j, ...>(rhs), evaluate the summation ein<i, j, ...>(lhs) += rhs, and return lhs. The shape of lhs is inferred from the expression.
  • +
+

Here are some examples using these reduction operations to compute summations:

1 {c++}
2  // Name the dimensions we use in Einstein reductions.
3  enum { i = 0, j = 1, k = 2, l = 3 };
4 
5  // Dot product dot1 = dot2 = x.y:
6  vector<float> x({10});
7  vector<float> y({10});
8  float dot1 = make_ein_sum<float>(ein<i>(x) * ein<i>(y));
9  float dot2 = 0.0f;
10  ein_reduce(ein(dot2) += ein<i>(x) * ein<i>(y));
11 
12  // Matrix multiply C1 = C2 = A*B:
13  matrix<float> A({10, 10});
14  matrix<float> B({10, 15});
15  matrix<float> C1({10, 15});
16  fill(C1, 0.0f);
17  ein_reduce(ein<i, j>(C1) += ein<i, k>(A) * ein<k, j>(B));
18  auto C2 = make_ein_sum<float, i, j>(ein<i, k>(A) * ein<k, j>(B));

We can use arbitrary functions as expression operands:

1 {c++}
2  // Cross product array crosses_n = x_n x y_n:
3  using vector_array = array<float, shape<dim<0, 3>, dense_dim<>>>;
4  vector_array xs({3, 100});
5  vector_array ys({3, 100});
6  vector_array crosses({3, 100});
7  auto epsilon3 = [](int i, int j, int k) { return sgn(j - i) * sgn(k - i) * sgn(k - j); };
8  ein_reduce(ein<i, l>(crosses) += ein<i, j, k>(epsilon3) * ein<j, l>(xs) * ein<k, l>(ys));

These operations generally produce loop nests that are as readily optimized by the compiler as hand-written loops. In this example, crosses, xs, and ys have shape shape<dim<0, 3>, dense_dim<>>, so the compiler will see small constant loops and likely be able to optimize this to similar efficiency as hand-written code, by unrolling and evaluating the function at compile time. The compiler also should be able to efficiently vectorize the l dimension of the ein_reduce, because that dimension has a constant stride 1.

+

The expression can be another kind of reduction, or not a reduction at all:

1 {c++}
2  // Matrix transpose AT = A^T:
3  matrix<float> AT({10, 10});
4  ein_reduce(ein<i, j>(AT) = ein<j, i>(A));
5 
6  // Maximum of each x-y plane of a 3D volume:
7  dense_array<float, 3> volume({8, 12, 20});
8  dense_array<float, 1> max_xy({20});
9  auto r = ein<k>(max_xy);
10  ein_reduce(r = max(r, ein<i, j, k>(volume)));

Reductions can have a mix of result and operand types:

1 {c++}
2  // Compute X1 = X2 = DFT[x]:
3  using complex = std::complex<float>;
4  dense_array<complex, 2> W({10, 10});
5  for_all_indices(W.shape(), [&](int j, int k) {
6  W(j, k) = exp(-2.0f * pi * complex(0, 1) * (static_cast<float>(j * k) / 10));
7  });
8  // Using `make_ein_sum`, returning the result:
9  auto X1 = make_ein_sum<complex, j>(ein<j, k>(W) * ein<k>(x));
10  // Using `ein_reduce`, computing the result in place:
11  vector<complex> X2({10}, 0.0f);
12  ein_reduce(ein<j>(X2) += ein<j, k>(W) * ein<k>(x));

These reductions also compose well with loop transformations like split and array operations like slicing and cropping. For example, a matrix multiplication can be tiled like so:

1 {c++}
2  // Adjust this depending on the target architecture. For AVX2, vectors are 256-bit.
3  constexpr index_t vector_size = 32 / sizeof(float);
4 
5  // We want the tiles to be big without spilling the accumulators to the stack.
6  constexpr index_t tile_rows = 4;
7  constexpr index_t tile_cols = vector_size * 3;
8 
9  for (auto io : split<tile_rows>(C.i())) {
10  for (auto jo : split<tile_cols>(C.j())) {
11  auto C_ijo = C(io, jo);
12  fill(C_ijo, 0.0f);
13  ein_reduce(ein<i, j>(C_ijo) += ein<i, k>(A) * ein<k, j>(B));
14  }
15  }

This generates the following machine code(*) for the inner loop using clang 18 with -O2 -ffast-math:

1 vbroadcastss (%rsi,%rdi,4), %ymm12
2 vmovups -64(%r12,%r15,4), %ymm13
3 vmovups -32(%r12,%r15,4), %ymm14
4 vmovups (%r12,%r15,4), %ymm15
5 addq %rbx, %r15
6 vfmadd231ps %ymm12, %ymm13, %ymm11
7 vfmadd231ps %ymm12, %ymm14, %ymm10
8 vfmadd231ps %ymm12, %ymm15, %ymm9
9 vbroadcastss (%r8,%rdi,4), %ymm12
10 vfmadd231ps %ymm12, %ymm13, %ymm8
11 vfmadd231ps %ymm12, %ymm14, %ymm7
12 vfmadd231ps %ymm12, %ymm15, %ymm6
13 vbroadcastss (%r10,%rdi,4), %ymm12
14 vfmadd231ps %ymm12, %ymm13, %ymm5
15 vfmadd231ps %ymm12, %ymm14, %ymm4
16 vfmadd231ps %ymm12, %ymm15, %ymm3
17 vbroadcastss (%rdx,%rdi,4), %ymm12
18 incq %rdi
19 vfmadd231ps %ymm13, %ymm12, %ymm2
20 vfmadd231ps %ymm14, %ymm12, %ymm1
21 vfmadd231ps %ymm12, %ymm15, %ymm0
22 cmpq %rdi, %r13
23 jne .LBB8_12

This is 40-50x faster than a naive C implementation of nested loops on my machine, and it should be within a factor of 2 of the peak possible performance. A similar example that is only a little more complicated achieves around 90% of the peak possible performance.

+

(*) Unfortunately, this doesn't generate performant code currently and requires a few tweaks to work around an issue in LLVM. See the matrix example for the code that produces the above assembly. To summarise, it is currently necessary to perform the accumulation into a temporary buffer instead of accumulating directly into the output.

+

CUDA support

+

Most of the functions in this library are marked with __device__, enabling them to be used in CUDA code. This includes array_ref<T, Shape> and most of its helper functions. The exceptions to this are functions and classes that allocate memory, primarily array<T, Shape, Alloc>.

+
+ + + + diff --git a/jquery.js b/jquery.js new file mode 100644 index 00000000..d52a1c77 --- /dev/null +++ b/jquery.js @@ -0,0 +1,68 @@ +/* + * jQuery JavaScript Library v1.7.1 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Mon Nov 21 21:11:03 2011 -0500 + */ +(function(bb,L){var av=bb.document,bu=bb.navigator,bl=bb.location;var b=(function(){var bF=function(b0,b1){return new bF.fn.init(b0,b1,bD)},bU=bb.jQuery,bH=bb.$,bD,bY=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase()},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null]}else{b2=bY.exec(b0)}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true)}else{b0=[b6.createElement(b1[1])]}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes}return bF.merge(this,b0)}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0)}this.length=1;this[0]=b5}this.context=av;this.selector=b0;return this}}else{if(!b4||b4.jquery){return(b4||b3).find(b0)}else{return this.constructor(b4).find(b0)}}}else{if(bF.isFunction(b0)){return b3.ready(b0)}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context}return bF.makeArray(b0,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return bK.call(this,0)},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0])},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1)}else{bF.merge(b2,b1)}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")"}}return b2},each:function(b1,b0){return bF.each(this,b1,b0)},ready:function(b0){bF.bindReady();bC.add(b0);return this},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","))},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2)}))},end:function(){return this.prevObject||this.constructor(null)},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={}}if(b3===b4){b5=this;--b4}for(;b40){return}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready")}}},bindReady:function(){if(bC){return}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1)}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bb.addEventListener("load",bF.ready,false)}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bb.attachEvent("onload",bF.ready);var b0=false;try{b0=bb.frameElement==null}catch(b1){}if(av.documentElement.doScroll&&b0){bw()}}}},isFunction:function(b0){return bF.type(b0)==="function"},isArray:Array.isArray||function(b0){return bF.type(b0)==="array"},isWindow:function(b0){return b0&&typeof b0==="object"&&"setInterval" in b0},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0)},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object"},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false}}catch(b1){return false}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0)},isEmptyObject:function(b1){for(var b0 in b1){return false}return true},error:function(b0){throw new Error(b0)},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null}b0=bF.trim(b0);if(bb.JSON&&bb.JSON.parse){return bb.JSON.parse(b0)}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))()}bF.error("Invalid JSON: "+b0)},parseXML:function(b2){var b0,b1;try{if(bb.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml")}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2)}}catch(b3){b0=L}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2)}return b0},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bb.execScript||function(b1){bb["eval"].call(bb,b1)})(b0)}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT)},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase()},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break}}}else{for(;b40&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b21?aJ.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx)}}}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aJ.call(arguments,0):bG;bC.notifyWith(bE,bB)}}if(e>1){for(;bv
a";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElement("select");bx=bG.appendChild(av.createElement("option"));bE=bv.getElementsByTagName("input")[0];bJ={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bF.getAttribute("style")),hrefNormalized:(bF.getAttribute("href")==="/a"),opacity:/^0.55/.test(bF.style.opacity),cssFloat:!!bF.style.cssFloat,checkOn:(bE.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true};bE.checked=true;bJ.noCloneChecked=bE.cloneNode(true).checked;bG.disabled=true;bJ.optDisabled=!bx.disabled;try{delete bv.test}catch(bC){bJ.deleteExpando=false}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bJ.noCloneEvent=false});bv.cloneNode(true).fireEvent("onclick")}bE=av.createElement("input");bE.value="t";bE.setAttribute("type","radio");bJ.radioValue=bE.value==="t";bE.setAttribute("checked","checked");bv.appendChild(bE);bD=av.createDocumentFragment();bD.appendChild(bv.lastChild);bJ.checkClone=bD.cloneNode(true).cloneNode(true).lastChild.checked;bJ.appendChecked=bE.checked;bD.removeChild(bE);bD.appendChild(bv);bv.innerHTML="";if(bb.getComputedStyle){bA=av.createElement("div");bA.style.width="0";bA.style.marginRight="0";bv.style.width="2px";bv.appendChild(bA);bJ.reliableMarginRight=(parseInt((bb.getComputedStyle(bA,null)||{marginRight:0}).marginRight,10)||0)===0}if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bB="on"+by;bw=(bB in bv);if(!bw){bv.setAttribute(bB,"return;");bw=(typeof bv[bB]==="function")}bJ[by+"Bubbles"]=bw}}bD.removeChild(bv);bD=bG=bx=bA=bv=bE=null;b(function(){var bM,bU,bV,bT,bN,bO,bL,bS,bR,e,bP,bQ=av.getElementsByTagName("body")[0];if(!bQ){return}bL=1;bS="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";bR="visibility:hidden;border:0;";e="style='"+bS+"border:5px solid #000;padding:0;'";bP="
";bM=av.createElement("div");bM.style.cssText=bR+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bQ.insertBefore(bM,bQ.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="
t
";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bJ.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);bv.innerHTML="";bv.style.width=bv.style.paddingLeft="1px";b.boxModel=bJ.boxModel=bv.offsetWidth===2;if(typeof bv.style.zoom!=="undefined"){bv.style.display="inline";bv.style.zoom=1;bJ.inlineBlockNeedsLayout=(bv.offsetWidth===2);bv.style.display="";bv.innerHTML="
";bJ.shrinkWrapBlocks=(bv.offsetWidth!==2)}bv.style.cssText=bS+bR;bv.innerHTML=bP;bU=bv.firstChild;bV=bU.firstChild;bN=bU.nextSibling.firstChild.firstChild;bO={doesNotAddBorder:(bV.offsetTop!==5),doesAddBorderForTableAndCells:(bN.offsetTop===5)};bV.style.position="fixed";bV.style.top="20px";bO.fixedPosition=(bV.offsetTop===20||bV.offsetTop===15);bV.style.position=bV.style.top="";bU.style.overflow="hidden";bU.style.position="relative";bO.subtractsBorderForOverflowNotVisible=(bV.offsetTop===-5);bO.doesNotIncludeMarginInBodyOffset=(bQ.offsetTop!==bL);bQ.removeChild(bM);bv=bM=null;b.extend(bJ,bO)});return bJ})();var aS=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e)},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return}if(!bw){if(bF){bx[bE]=bw=++b.uuid}else{bw=bE}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv)}else{e[bw].data=b.extend(e[bw].data,bv)}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={}}bA=bA.data}if(bz!==L){bA[b.camelCase(bv)]=bz}if(bB&&!bA[bv]){return bG.events}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)]}}else{bD=bA}return bD},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv]}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv]}else{bv=bv.split(" ")}}}for(bA=0,bz=bv.length;bA-1){return true}}return false},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.nodeName.toLowerCase()]||b.valHooks[bw.type];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv}bv=bw.value;return typeof bv==="string"?bv.replace(aU,""):bv==null?"":bv}return}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return}if(by){bB=bx.call(this,bA,bz.val())}else{bB=bx}if(bB==null){bB=""}else{if(typeof bB==="number"){bB+=""}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+""})}}}e=b.valHooks[this.nodeName.toLowerCase()]||b.valHooks[this.type];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB}})}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv=0});if(!e.length){bv.selectedIndex=-1}return e}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType;if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);return bw===null?L:bw}}},removeAttr:function(bx,bz){var by,bA,bv,e,bw=0;if(bz&&bx.nodeType===1){bA=bz.toLowerCase().split(af);e=bA.length;for(;bw=0)}}})});var bd=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/\bhover(\.\S+)?\b/,aO=/^key/,bf=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)")}return bv},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)))},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1")};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return}if(bJ.handler){bv=bJ;bJ=bv.handler}if(!bJ.guid){bJ.guid=b.guid++}bK=bD.events;if(!bK){bD.events=bK={}}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L};bB.elem=bx}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI=0){bG=bG.slice(0,-1);bw=true}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort()}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true)}}return}bv.result=L;if(!bv.target){bv.target=bA}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bb,bI])}}for(bC=0;bCbA){bH.push({elem:this,matches:bz.slice(bA)})}for(bC=0;bC0?this.on(e,null,bx,bw):this.trigger(e)};if(b.attrFn){b.attrFn[e]=true}if(aO.test(e)){b.event.fixHooks[e]=b.event.keyHooks}if(bf.test(e)){b.event.fixHooks[e]=b.event.mouseHooks}}); +/* + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ)}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift()}b3=bM(bV,b3,bZ)}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0]}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3)}else{bU=false}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5=""}else{b4=bW.pop()}if(b4==null){b4=e}bE.relative[b5](b6,b4,bT)}}else{b6=bW=[]}}if(!b6){b6=b3}if(!b6){by.error(b5||bV)}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6)}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX])}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX])}}}}}else{bF(b6,bY)}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY)}return bY};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e0};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[]}for(bS=0,bU=bE.order.length;bS":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS=0)){if(!bS){e.push(bV)}}else{if(bS){bR[bU]=false}}}}return false},ID:function(e){return e[1].replace(bK,"")},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0])}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0}else{if(e[2]){by.error(e[0])}}e[0]=bI++;return e},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT]}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" "}return bU},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR)}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT)}return false}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true}}return bU},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(bS,bR,e){return !!by(e[3],bS).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(bR,e){return e===0},last:function(bS,bR,e,bT){return bR===bT.length-1},even:function(bR,e){return e%2===0},odd:function(bR,e){return e%2===1},lt:function(bS,bR,e){return bRe[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV=0)}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV)}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1)};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx))}var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e}return bR};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU)}else{if(typeof bU.length==="number"){for(var e=bU.length;bS";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[]}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT}}e.removeChild(bR);e=bR=null})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS])}}bU=bT}return bU}}e.innerHTML="";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2)}}e=null})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="

";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ)}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ)}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ)}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ)}}else{return bF([],bZ)}}}try{return bF(bV.querySelectorAll(b4),bZ)}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU)}else{bU=bU.replace(/'/g,"\\$&")}if(b5&&b6){bV=bV.parentNode}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ)}}catch(b1){}finally{if(!bX){bW.removeAttribute("id")}}}}}return e(b4,bV,bZ,b3)};for(var bR in e){by[bR]=e[bR]}bT=null})()}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle")}catch(bT){bR=true}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV}}}catch(bX){}}return by(bY,null,null,[bW]).length>0}}})();(function(){var e=av.createElement("div");e.innerHTML="
";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1])}};e=null})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT0){bU=e;break}}}e=e[bR]}bZ[bT]=bU}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true)}}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16)}}else{by.contains=function(){return false}}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"")}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT0){for(bB=bA;bB=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw-1:b.find.matchesSelector(bz,by)){bv.push(bz);break}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return b.inArray(this[0],b(e))}return b.inArray(e.jquery?e[0]:e,this)},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(C(bx[0])||C(bw[0])?bw:b.unique(bw))},andSelf:function(){return this.add(this.prevObject)}});function C(e){return !e||!e.parentNode||e.parentNode.nodeType===11}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw)},next:function(e){return b.nth(e,2,"nextSibling")},prev:function(e){return b.nth(e,2,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw)},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw)},siblings:function(e){return b.sibling(e.parentNode.firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes)}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx)}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||a9.test(bw))&&aq.test(e)){bx=bx.reverse()}return this.pushStack(bx,e,P.call(arguments).join(","))}});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")"}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e)},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx)}bx=bx[bv]}return e},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break}}return by},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw)}}return e}});function aG(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e})}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e})}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1});if(bp.test(bw)){return b.filter(bw,bv,!e)}else{bw=b.filter(bw,bv)}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e})}function a(e){var bw=aR.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop())}}return bv}var aR="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ag=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,w=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},ac=a(av);ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div
","
"]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw))})}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0])}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild}return bw}).append(this)}return this},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv))})}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e)}else{bv.append(e)}})},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e)})},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this)})}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling)})}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw])}if(bw.parentNode){bw.parentNode.removeChild(bw)}}}return this},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"))}while(bv.firstChild){bv.removeChild(bv.firstChild)}}return this},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e)})},html:function(bx){if(bx===L){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(ag,""):null}else{if(typeof bx==="string"&&!ae.test(bx)&&(b.support.leadingWhitespace||!ar.test(bx))&&!ax[(d.exec(bx)||["",""])[1].toLowerCase()]){bx=bx.replace(R,"<$1>");try{for(var bw=0,bv=this.length;bw1&&bw0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by)}return this.pushStack(bz,e,bC.selector)}}});function bg(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked}}function E(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e)}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az)}}}function al(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||!ah.test("<"+by.nodeName)?by.cloneNode(true):al(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){ai(by,bz);e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){if(bv[bx]){ai(e[bx],bv[bx])}}}if(bA){t(by,bz);if(bw){e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){t(e[bx],bv[bx])}}}e=bv=null;return bz},clean:function(bw,by,bH,bA){var bF;by=by||av;if(typeof by.createElement==="undefined"){by=by.ownerDocument||by[0]&&by[0].ownerDocument||av}var bI=[],bB;for(var bE=0,bz;(bz=bw[bE])!=null;bE++){if(typeof bz==="number"){bz+=""}if(!bz){continue}if(typeof bz==="string"){if(!W.test(bz)){bz=by.createTextNode(bz)}else{bz=bz.replace(R,"<$1>");var bK=(d.exec(bz)||["",""])[1].toLowerCase(),bx=ax[bK]||ax._default,bD=bx[0],bv=by.createElement("div");if(by===av){ac.appendChild(bv)}else{a(by).appendChild(bv)}bv.innerHTML=bx[1]+bz+bx[2];while(bD--){bv=bv.lastChild}if(!b.support.tbody){var e=w.test(bz),bC=bK==="table"&&!e?bv.firstChild&&bv.firstChild.childNodes:bx[1]===""&&!e?bv.childNodes:[];for(bB=bC.length-1;bB>=0;--bB){if(b.nodeName(bC[bB],"tbody")&&!bC[bB].childNodes.length){bC[bB].parentNode.removeChild(bC[bB])}}}if(!b.support.leadingWhitespace&&ar.test(bz)){bv.insertBefore(by.createTextNode(ar.exec(bz)[0]),bv.firstChild)}bz=bv.childNodes}}var bG;if(!b.support.appendChecked){if(bz[0]&&typeof(bG=bz.length)==="number"){for(bB=0;bB=0){return bx+"px"}}else{return bx}}}});if(!b.support.opacity){b.cssHooks.opacity={get:function(bv,e){return au.test((e&&bv.currentStyle?bv.currentStyle.filter:bv.style.filter)||"")?(parseFloat(RegExp.$1)/100)+"":e?"1":""},set:function(by,bz){var bx=by.style,bv=by.currentStyle,e=b.isNumeric(bz)?"alpha(opacity="+bz*100+")":"",bw=bv&&bv.filter||bx.filter||"";bx.zoom=1;if(bz>=1&&b.trim(bw.replace(ak,""))===""){bx.removeAttribute("filter");if(bv&&!bv.filter){return}}bx.filter=ak.test(bw)?bw.replace(ak,e):bw+" "+e}}}b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw,bv){var e;b.swap(bw,{display:"inline-block"},function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}});if(av.defaultView&&av.defaultView.getComputedStyle){aI=function(by,bw){var bv,bx,e;bw=bw.replace(z,"-$1").toLowerCase();if((bx=by.ownerDocument.defaultView)&&(e=bx.getComputedStyle(by,null))){bv=e.getPropertyValue(bw);if(bv===""&&!b.contains(by.ownerDocument.documentElement,by)){bv=b.style(by,bw)}}return bv}}if(av.documentElement.currentStyle){aX=function(bz,bw){var bA,e,by,bv=bz.currentStyle&&bz.currentStyle[bw],bx=bz.style;if(bv===null&&bx&&(by=bx[bw])){bv=by}if(!bc.test(bv)&&bn.test(bv)){bA=bx.left;e=bz.runtimeStyle&&bz.runtimeStyle.left;if(e){bz.runtimeStyle.left=bz.currentStyle.left}bx.left=bw==="fontSize"?"1em":(bv||0);bv=bx.pixelLeft+"px";bx.left=bA;if(e){bz.runtimeStyle.left=e}}return bv===""?"auto":bv}}Z=aI||aX;function p(by,bw,bv){var bA=bw==="width"?by.offsetWidth:by.offsetHeight,bz=bw==="width"?an:a1,bx=0,e=bz.length;if(bA>0){if(bv!=="border"){for(;bx)<[^<]*)*<\/script>/gi,q=/^(?:select|textarea)/i,h=/\s+/,br=/([?&])_=[^&]*/,K=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,A=b.fn.load,aa={},r={},aE,s,aV=["*/"]+["*"];try{aE=bl.href}catch(aw){aE=av.createElement("a");aE.href="";aE=aE.href}s=K.exec(aE.toLowerCase())||[];function f(e){return function(by,bA){if(typeof by!=="string"){bA=by;by="*"}if(b.isFunction(bA)){var bx=by.toLowerCase().split(h),bw=0,bz=bx.length,bv,bB,bC;for(;bw=0){var e=bw.slice(by,bw.length);bw=bw.slice(0,by)}var bx="GET";if(bz){if(b.isFunction(bz)){bA=bz;bz=L}else{if(typeof bz==="object"){bz=b.param(bz,b.ajaxSettings.traditional);bx="POST"}}}var bv=this;b.ajax({url:bw,type:bx,dataType:"html",data:bz,complete:function(bC,bB,bD){bD=bC.responseText;if(bC.isResolved()){bC.done(function(bE){bD=bE});bv.html(e?b("
").append(bD.replace(a6,"")).find(e):bD)}if(bA){bv.each(bA,[bD,bB,bC])}}});return this},serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?b.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||q.test(this.nodeName)||aZ.test(this.type))}).map(function(e,bv){var bw=b(this).val();return bw==null?null:b.isArray(bw)?b.map(bw,function(by,bx){return{name:bv.name,value:by.replace(bs,"\r\n")}}):{name:bv.name,value:bw.replace(bs,"\r\n")}}).get()}});b.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bv){b.fn[bv]=function(bw){return this.on(bv,bw)}});b.each(["get","post"],function(e,bv){b[bv]=function(bw,by,bz,bx){if(b.isFunction(by)){bx=bx||bz;bz=by;by=L}return b.ajax({type:bv,url:bw,data:by,success:bz,dataType:bx})}});b.extend({getScript:function(e,bv){return b.get(e,L,bv,"script")},getJSON:function(e,bv,bw){return b.get(e,bv,bw,"json")},ajaxSetup:function(bv,e){if(e){am(bv,b.ajaxSettings)}else{e=bv;bv=b.ajaxSettings}am(bv,e);return bv},ajaxSettings:{url:aE,isLocal:aM.test(s[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aV},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":bb.String,"text html":true,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:f(aa),ajaxTransport:f(r),ajax:function(bz,bx){if(typeof bz==="object"){bx=bz;bz=L}bx=bx||{};var bD=b.ajaxSetup({},bx),bS=bD.context||bD,bG=bS!==bD&&(bS.nodeType||bS instanceof b)?b(bS):b.event,bR=b.Deferred(),bN=b.Callbacks("once memory"),bB=bD.statusCode||{},bC,bH={},bO={},bQ,by,bL,bE,bI,bA=0,bw,bK,bJ={readyState:0,setRequestHeader:function(bT,bU){if(!bA){var e=bT.toLowerCase();bT=bO[e]=bO[e]||bT;bH[bT]=bU}return this},getAllResponseHeaders:function(){return bA===2?bQ:null},getResponseHeader:function(bT){var e;if(bA===2){if(!by){by={};while((e=aD.exec(bQ))){by[e[1].toLowerCase()]=e[2]}}e=by[bT.toLowerCase()]}return e===L?null:e},overrideMimeType:function(e){if(!bA){bD.mimeType=e}return this},abort:function(e){e=e||"abort";if(bL){bL.abort(e)}bF(0,e);return this}};function bF(bZ,bU,b0,bW){if(bA===2){return}bA=2;if(bE){clearTimeout(bE)}bL=L;bQ=bW||"";bJ.readyState=bZ>0?4:0;var bT,b4,b3,bX=bU,bY=b0?bj(bD,bJ,b0):L,bV,b2;if(bZ>=200&&bZ<300||bZ===304){if(bD.ifModified){if((bV=bJ.getResponseHeader("Last-Modified"))){b.lastModified[bC]=bV}if((b2=bJ.getResponseHeader("Etag"))){b.etag[bC]=b2}}if(bZ===304){bX="notmodified";bT=true}else{try{b4=G(bD,bY);bX="success";bT=true}catch(b1){bX="parsererror";b3=b1}}}else{b3=bX;if(!bX||bZ){bX="error";if(bZ<0){bZ=0}}}bJ.status=bZ;bJ.statusText=""+(bU||bX);if(bT){bR.resolveWith(bS,[b4,bX,bJ])}else{bR.rejectWith(bS,[bJ,bX,b3])}bJ.statusCode(bB);bB=L;if(bw){bG.trigger("ajax"+(bT?"Success":"Error"),[bJ,bD,bT?b4:b3])}bN.fireWith(bS,[bJ,bX]);if(bw){bG.trigger("ajaxComplete",[bJ,bD]);if(!(--b.active)){b.event.trigger("ajaxStop")}}}bR.promise(bJ);bJ.success=bJ.done;bJ.error=bJ.fail;bJ.complete=bN.add;bJ.statusCode=function(bT){if(bT){var e;if(bA<2){for(e in bT){bB[e]=[bB[e],bT[e]]}}else{e=bT[bJ.status];bJ.then(e,e)}}return this};bD.url=((bz||bD.url)+"").replace(bq,"").replace(c,s[1]+"//");bD.dataTypes=b.trim(bD.dataType||"*").toLowerCase().split(h);if(bD.crossDomain==null){bI=K.exec(bD.url.toLowerCase());bD.crossDomain=!!(bI&&(bI[1]!=s[1]||bI[2]!=s[2]||(bI[3]||(bI[1]==="http:"?80:443))!=(s[3]||(s[1]==="http:"?80:443))))}if(bD.data&&bD.processData&&typeof bD.data!=="string"){bD.data=b.param(bD.data,bD.traditional)}aW(aa,bD,bx,bJ);if(bA===2){return false}bw=bD.global;bD.type=bD.type.toUpperCase();bD.hasContent=!aQ.test(bD.type);if(bw&&b.active++===0){b.event.trigger("ajaxStart")}if(!bD.hasContent){if(bD.data){bD.url+=(M.test(bD.url)?"&":"?")+bD.data;delete bD.data}bC=bD.url;if(bD.cache===false){var bv=b.now(),bP=bD.url.replace(br,"$1_="+bv);bD.url=bP+((bP===bD.url)?(M.test(bD.url)?"&":"?")+"_="+bv:"")}}if(bD.data&&bD.hasContent&&bD.contentType!==false||bx.contentType){bJ.setRequestHeader("Content-Type",bD.contentType)}if(bD.ifModified){bC=bC||bD.url;if(b.lastModified[bC]){bJ.setRequestHeader("If-Modified-Since",b.lastModified[bC])}if(b.etag[bC]){bJ.setRequestHeader("If-None-Match",b.etag[bC])}}bJ.setRequestHeader("Accept",bD.dataTypes[0]&&bD.accepts[bD.dataTypes[0]]?bD.accepts[bD.dataTypes[0]]+(bD.dataTypes[0]!=="*"?", "+aV+"; q=0.01":""):bD.accepts["*"]);for(bK in bD.headers){bJ.setRequestHeader(bK,bD.headers[bK])}if(bD.beforeSend&&(bD.beforeSend.call(bS,bJ,bD)===false||bA===2)){bJ.abort();return false}for(bK in {success:1,error:1,complete:1}){bJ[bK](bD[bK])}bL=aW(r,bD,bx,bJ);if(!bL){bF(-1,"No Transport")}else{bJ.readyState=1;if(bw){bG.trigger("ajaxSend",[bJ,bD])}if(bD.async&&bD.timeout>0){bE=setTimeout(function(){bJ.abort("timeout")},bD.timeout)}try{bA=1;bL.send(bH,bF)}catch(bM){if(bA<2){bF(-1,bM)}else{throw bM}}}return bJ},param:function(e,bw){var bv=[],by=function(bz,bA){bA=b.isFunction(bA)?bA():bA;bv[bv.length]=encodeURIComponent(bz)+"="+encodeURIComponent(bA)};if(bw===L){bw=b.ajaxSettings.traditional}if(b.isArray(e)||(e.jquery&&!b.isPlainObject(e))){b.each(e,function(){by(this.name,this.value)})}else{for(var bx in e){v(bx,e[bx],bw,by)}}return bv.join("&").replace(k,"+")}});function v(bw,by,bv,bx){if(b.isArray(by)){b.each(by,function(bA,bz){if(bv||ap.test(bw)){bx(bw,bz)}else{v(bw+"["+(typeof bz==="object"||b.isArray(bz)?bA:"")+"]",bz,bv,bx)}})}else{if(!bv&&by!=null&&typeof by==="object"){for(var e in by){v(bw+"["+e+"]",by[e],bv,bx)}}else{bx(bw,by)}}}b.extend({active:0,lastModified:{},etag:{}});function bj(bD,bC,bz){var bv=bD.contents,bB=bD.dataTypes,bw=bD.responseFields,by,bA,bx,e;for(bA in bw){if(bA in bz){bC[bw[bA]]=bz[bA]}}while(bB[0]==="*"){bB.shift();if(by===L){by=bD.mimeType||bC.getResponseHeader("content-type")}}if(by){for(bA in bv){if(bv[bA]&&bv[bA].test(by)){bB.unshift(bA);break}}}if(bB[0] in bz){bx=bB[0]}else{for(bA in bz){if(!bB[0]||bD.converters[bA+" "+bB[0]]){bx=bA;break}if(!e){e=bA}}bx=bx||e}if(bx){if(bx!==bB[0]){bB.unshift(bx)}return bz[bx]}}function G(bH,bz){if(bH.dataFilter){bz=bH.dataFilter(bz,bH.dataType)}var bD=bH.dataTypes,bG={},bA,bE,bw=bD.length,bB,bC=bD[0],bx,by,bF,bv,e;for(bA=1;bA=bw.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();bw.animatedProperties[this.prop]=true;for(bA in bw.animatedProperties){if(bw.animatedProperties[bA]!==true){e=false}}if(e){if(bw.overflow!=null&&!b.support.shrinkWrapBlocks){b.each(["","X","Y"],function(bC,bD){bz.style["overflow"+bD]=bw.overflow[bC]})}if(bw.hide){b(bz).hide()}if(bw.hide||bw.show){for(bA in bw.animatedProperties){b.style(bz,bA,bw.orig[bA]);b.removeData(bz,"fxshow"+bA,true);b.removeData(bz,"toggle"+bA,true)}}bv=bw.complete;if(bv){bw.complete=false;bv.call(bz)}}return false}else{if(bw.duration==Infinity){this.now=bx}else{bB=bx-this.startTime;this.state=bB/bw.duration;this.pos=b.easing[bw.animatedProperties[this.prop]](this.state,bB,0,1,bw.duration);this.now=this.start+((this.end-this.start)*this.pos)}this.update()}return true}};b.extend(b.fx,{tick:function(){var bw,bv=b.timers,e=0;for(;e").appendTo(e),bw=bv.css("display");bv.remove();if(bw==="none"||bw===""){if(!a8){a8=av.createElement("iframe");a8.frameBorder=a8.width=a8.height=0}e.appendChild(a8);if(!m||!a8.createElement){m=(a8.contentWindow||a8.contentDocument).document;m.write((av.compatMode==="CSS1Compat"?"":"")+"");m.close()}bv=m.createElement(bx);m.body.appendChild(bv);bw=b.css(bv,"display");e.removeChild(a8)}Q[bx]=bw}return Q[bx]}var V=/^t(?:able|d|h)$/i,ad=/^(?:body|html)$/i;if("getBoundingClientRect" in av.documentElement){b.fn.offset=function(bI){var by=this[0],bB;if(bI){return this.each(function(e){b.offset.setOffset(this,bI,e)})}if(!by||!by.ownerDocument){return null}if(by===by.ownerDocument.body){return b.offset.bodyOffset(by)}try{bB=by.getBoundingClientRect()}catch(bF){}var bH=by.ownerDocument,bw=bH.documentElement;if(!bB||!b.contains(bw,by)){return bB?{top:bB.top,left:bB.left}:{top:0,left:0}}var bC=bH.body,bD=aK(bH),bA=bw.clientTop||bC.clientTop||0,bE=bw.clientLeft||bC.clientLeft||0,bv=bD.pageYOffset||b.support.boxModel&&bw.scrollTop||bC.scrollTop,bz=bD.pageXOffset||b.support.boxModel&&bw.scrollLeft||bC.scrollLeft,bG=bB.top+bv-bA,bx=bB.left+bz-bE;return{top:bG,left:bx}}}else{b.fn.offset=function(bF){var bz=this[0];if(bF){return this.each(function(bG){b.offset.setOffset(this,bF,bG)})}if(!bz||!bz.ownerDocument){return null}if(bz===bz.ownerDocument.body){return b.offset.bodyOffset(bz)}var bC,bw=bz.offsetParent,bv=bz,bE=bz.ownerDocument,bx=bE.documentElement,bA=bE.body,bB=bE.defaultView,e=bB?bB.getComputedStyle(bz,null):bz.currentStyle,bD=bz.offsetTop,by=bz.offsetLeft;while((bz=bz.parentNode)&&bz!==bA&&bz!==bx){if(b.support.fixedPosition&&e.position==="fixed"){break}bC=bB?bB.getComputedStyle(bz,null):bz.currentStyle;bD-=bz.scrollTop;by-=bz.scrollLeft;if(bz===bw){bD+=bz.offsetTop;by+=bz.offsetLeft;if(b.support.doesNotAddBorder&&!(b.support.doesAddBorderForTableAndCells&&V.test(bz.nodeName))){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}bv=bw;bw=bz.offsetParent}if(b.support.subtractsBorderForOverflowNotVisible&&bC.overflow!=="visible"){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}e=bC}if(e.position==="relative"||e.position==="static"){bD+=bA.offsetTop;by+=bA.offsetLeft}if(b.support.fixedPosition&&e.position==="fixed"){bD+=Math.max(bx.scrollTop,bA.scrollTop);by+=Math.max(bx.scrollLeft,bA.scrollLeft)}return{top:bD,left:by}}}b.offset={bodyOffset:function(e){var bw=e.offsetTop,bv=e.offsetLeft;if(b.support.doesNotIncludeMarginInBodyOffset){bw+=parseFloat(b.css(e,"marginTop"))||0;bv+=parseFloat(b.css(e,"marginLeft"))||0}return{top:bw,left:bv}},setOffset:function(bx,bG,bA){var bB=b.css(bx,"position");if(bB==="static"){bx.style.position="relative"}var bz=b(bx),bv=bz.offset(),e=b.css(bx,"top"),bE=b.css(bx,"left"),bF=(bB==="absolute"||bB==="fixed")&&b.inArray("auto",[e,bE])>-1,bD={},bC={},bw,by;if(bF){bC=bz.position();bw=bC.top;by=bC.left}else{bw=parseFloat(e)||0;by=parseFloat(bE)||0}if(b.isFunction(bG)){bG=bG.call(bx,bA,bv)}if(bG.top!=null){bD.top=(bG.top-bv.top)+bw}if(bG.left!=null){bD.left=(bG.left-bv.left)+by}if("using" in bG){bG.using.call(bx,bD)}else{bz.css(bD)}}};b.fn.extend({position:function(){if(!this[0]){return null}var bw=this[0],bv=this.offsetParent(),bx=this.offset(),e=ad.test(bv[0].nodeName)?{top:0,left:0}:bv.offset();bx.top-=parseFloat(b.css(bw,"marginTop"))||0;bx.left-=parseFloat(b.css(bw,"marginLeft"))||0;e.top+=parseFloat(b.css(bv[0],"borderTopWidth"))||0;e.left+=parseFloat(b.css(bv[0],"borderLeftWidth"))||0;return{top:bx.top-e.top,left:bx.left-e.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||av.body;while(e&&(!ad.test(e.nodeName)&&b.css(e,"position")==="static")){e=e.offsetParent}return e})}});b.each(["Left","Top"],function(bv,e){var bw="scroll"+e;b.fn[bw]=function(bz){var bx,by;if(bz===L){bx=this[0];if(!bx){return null}by=aK(bx);return by?("pageXOffset" in by)?by[bv?"pageYOffset":"pageXOffset"]:b.support.boxModel&&by.document.documentElement[bw]||by.document.body[bw]:bx[bw]}return this.each(function(){by=aK(this);if(by){by.scrollTo(!bv?bz:b(by).scrollLeft(),bv?bz:b(by).scrollTop())}else{this[bw]=bz}})}});function aK(e){return b.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}b.each(["Height","Width"],function(bv,e){var bw=e.toLowerCase();b.fn["inner"+e]=function(){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,"padding")):this[bw]():null};b.fn["outer"+e]=function(by){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,by?"margin":"border")):this[bw]():null};b.fn[bw]=function(bz){var bA=this[0];if(!bA){return bz==null?null:this}if(b.isFunction(bz)){return this.each(function(bE){var bD=b(this);bD[bw](bz.call(this,bE,bD[bw]()))})}if(b.isWindow(bA)){var bB=bA.document.documentElement["client"+e],bx=bA.document.body;return bA.document.compatMode==="CSS1Compat"&&bB||bx&&bx["client"+e]||bB}else{if(bA.nodeType===9){return Math.max(bA.documentElement["client"+e],bA.body["scroll"+e],bA.documentElement["scroll"+e],bA.body["offset"+e],bA.documentElement["offset"+e])}else{if(bz===L){var bC=b.css(bA,bw),by=parseFloat(bC);return b.isNumeric(by)?by:bC}else{return this.css(bw,typeof bz==="string"?bz:bz+"px")}}}}});bb.jQuery=bb.$=b;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return b})}})(window);/* + * jQuery UI 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI + */ +(function(a,d){a.ui=a.ui||{};if(a.ui.version){return}a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(e,f){return typeof e==="number"?this.each(function(){var g=this;setTimeout(function(){a(g).focus();if(f){f.call(g)}},e)}):this._focus.apply(this,arguments)},scrollParent:function(){var e;if((a.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){e=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(a.curCSS(this,"position",1))&&(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}else{e=this.parents().filter(function(){return(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!e.length?a(document):e},zIndex:function(h){if(h!==d){return this.css("zIndex",h)}if(this.length){var f=a(this[0]),e,g;while(f.length&&f[0]!==document){e=f.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){g=parseInt(f.css("zIndex"),10);if(!isNaN(g)&&g!==0){return g}}f=f.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});a.each(["Width","Height"],function(g,e){var f=e==="Width"?["Left","Right"]:["Top","Bottom"],h=e.toLowerCase(),k={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};function j(m,l,i,n){a.each(f,function(){l-=parseFloat(a.curCSS(m,"padding"+this,true))||0;if(i){l-=parseFloat(a.curCSS(m,"border"+this+"Width",true))||0}if(n){l-=parseFloat(a.curCSS(m,"margin"+this,true))||0}});return l}a.fn["inner"+e]=function(i){if(i===d){return k["inner"+e].call(this)}return this.each(function(){a(this).css(h,j(this,i)+"px")})};a.fn["outer"+e]=function(i,l){if(typeof i!=="number"){return k["outer"+e].call(this,i)}return this.each(function(){a(this).css(h,j(this,i,true,l)+"px")})}});function c(g,e){var j=g.nodeName.toLowerCase();if("area"===j){var i=g.parentNode,h=i.name,f;if(!g.href||!h||i.nodeName.toLowerCase()!=="map"){return false}f=a("img[usemap=#"+h+"]")[0];return !!f&&b(f)}return(/input|select|textarea|button|object/.test(j)?!g.disabled:"a"==j?g.href||e:e)&&b(g)}function b(e){return !a(e).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.extend(a.expr[":"],{data:function(g,f,e){return !!a.data(g,e[3])},focusable:function(e){return c(e,!isNaN(a.attr(e,"tabindex")))},tabbable:function(g){var e=a.attr(g,"tabindex"),f=isNaN(e);return(f||e>=0)&&c(g,!f)}});a(function(){var e=document.body,f=e.appendChild(f=document.createElement("div"));f.offsetHeight;a.extend(f.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=f.offsetHeight===100;a.support.selectstart="onselectstart" in f;e.removeChild(f).style.display="none"});a.extend(a.ui,{plugin:{add:function(f,g,j){var h=a.ui[f].prototype;for(var e in j){h.plugins[e]=h.plugins[e]||[];h.plugins[e].push([g,j[e]])}},call:function(e,g,f){var j=e.plugins[g];if(!j||!e.element[0].parentNode){return}for(var h=0;h0){return true}h[e]=1;g=(h[e]>0);h[e]=0;return g},isOverAxis:function(f,e,g){return(f>e)&&(f<(e+g))},isOver:function(j,f,i,h,e,g){return a.ui.isOverAxis(j,i,e)&&a.ui.isOverAxis(f,h,g)}})})(jQuery);/* + * jQuery UI Widget 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Widget + */ +(function(b,d){if(b.cleanData){var c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)}}else{var a=b.fn.remove;b.fn.remove=function(e,f){return this.each(function(){if(!f){if(!e||b.filter(e,[this]).length){b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(g){}})}}return a.call(b(this),e,f)})}}b.widget=function(f,h,e){var g=f.split(".")[0],j;f=f.split(".")[1];j=g+"-"+f;if(!e){e=h;h=b.Widget}b.expr[":"][j]=function(k){return !!b.data(k,f)};b[g]=b[g]||{};b[g][f]=function(k,l){if(arguments.length){this._createWidget(k,l)}};var i=new h();i.options=b.extend(true,{},i.options);b[g][f].prototype=b.extend(true,i,{namespace:g,widgetName:f,widgetEventPrefix:b[g][f].prototype.widgetEventPrefix||f,widgetBaseClass:j},e);b.widget.bridge(f,b[g][f])};b.widget.bridge=function(f,e){b.fn[f]=function(i){var g=typeof i==="string",h=Array.prototype.slice.call(arguments,1),j=this;i=!g&&h.length?b.extend.apply(null,[true,i].concat(h)):i;if(g&&i.charAt(0)==="_"){return j}if(g){this.each(function(){var k=b.data(this,f),l=k&&b.isFunction(k[i])?k[i].apply(k,h):k;if(l!==k&&l!==d){j=l;return false}})}else{this.each(function(){var k=b.data(this,f);if(k){k.option(i||{})._init()}else{b.data(this,f,new e(i,this))}})}return j}};b.Widget=function(e,f){if(arguments.length){this._createWidget(e,f)}};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(f,g){b.data(g,this.widgetName,this);this.element=b(g);this.options=b.extend(true,{},this.options,this._getCreateOptions(),f);var e=this;this.element.bind("remove."+this.widgetName,function(){e.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(f,g){var e=f;if(arguments.length===0){return b.extend({},this.options)}if(typeof f==="string"){if(g===d){return this.options[f]}e={};e[f]=g}this._setOptions(e);return this},_setOptions:function(f){var e=this;b.each(f,function(g,h){e._setOption(g,h)});return this},_setOption:function(e,f){this.options[e]=f;if(e==="disabled"){this.widget()[f?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",f)}return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(e,f,g){var j,i,h=this.options[e];g=g||{};f=b.Event(f);f.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase();f.target=this.element[0];i=f.originalEvent;if(i){for(j in i){if(!(j in f)){f[j]=i[j]}}}this.element.trigger(f,g);return !(b.isFunction(h)&&h.call(this.element[0],f,g)===false||f.isDefaultPrevented())}}})(jQuery);/* + * jQuery UI Mouse 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Mouse + * + * Depends: + * jquery.ui.widget.js + */ +(function(b,c){var a=false;b(document).mouseup(function(d){a=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var d=this;this.element.bind("mousedown."+this.widgetName,function(e){return d._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===b.data(e.target,d.widgetName+".preventClickEvent")){b.removeData(e.target,d.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(f){if(a){return}(this._mouseStarted&&this._mouseUp(f));this._mouseDownEvent=f;var e=this,g=(f.which==1),d=(typeof this.options.cancel=="string"&&f.target.nodeName?b(f.target).closest(this.options.cancel).length:false);if(!g||d||!this._mouseCapture(f)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(f)&&this._mouseDelayMet(f)){this._mouseStarted=(this._mouseStart(f)!==false);if(!this._mouseStarted){f.preventDefault();return true}}if(true===b.data(f.target,this.widgetName+".preventClickEvent")){b.removeData(f.target,this.widgetName+".preventClickEvent")}this._mouseMoveDelegate=function(h){return e._mouseMove(h)};this._mouseUpDelegate=function(h){return e._mouseUp(h)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);f.preventDefault();a=true;return true},_mouseMove:function(d){if(b.browser.msie&&!(document.documentMode>=9)&&!d.button){return this._mouseUp(d)}if(this._mouseStarted){this._mouseDrag(d);return d.preventDefault()}if(this._mouseDistanceMet(d)&&this._mouseDelayMet(d)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,d)!==false);(this._mouseStarted?this._mouseDrag(d):this._mouseUp(d))}return !this._mouseStarted},_mouseUp:function(d){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;if(d.target==this._mouseDownEvent.target){b.data(d.target,this.widgetName+".preventClickEvent",true)}this._mouseStop(d)}return false},_mouseDistanceMet:function(d){return(Math.max(Math.abs(this._mouseDownEvent.pageX-d.pageX),Math.abs(this._mouseDownEvent.pageY-d.pageY))>=this.options.distance)},_mouseDelayMet:function(d){return this.mouseDelayMet},_mouseStart:function(d){},_mouseDrag:function(d){},_mouseStop:function(d){},_mouseCapture:function(d){return true}})})(jQuery);(function(c,d){c.widget("ui.resizable",c.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000},_create:function(){var f=this,k=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(k.aspectRatio),aspectRatio:k.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:k.helper||k.ghost||k.animate?k.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){this.element.wrap(c('
').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=k.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var l=this.handles.split(",");this.handles={};for(var g=0;g
');if(/sw|se|ne|nw/.test(j)){h.css({zIndex:++k.zIndex})}if("se"==j){h.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[j]=".ui-resizable-"+j;this.element.append(h)}}this._renderAxis=function(q){q=q||this.element;for(var n in this.handles){if(this.handles[n].constructor==String){this.handles[n]=c(this.handles[n],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=c(this.handles[n],this.element),p=0;p=/sw|ne|nw|se|n|s/.test(n)?o.outerHeight():o.outerWidth();var m=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");q.css(m,p);this._proportionallyResize()}if(!c(this.handles[n]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!f.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}f.axis=i&&i[1]?i[1]:"se"}});if(k.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){if(k.disabled){return}c(this).removeClass("ui-resizable-autohide");f._handles.show()},function(){if(k.disabled){return}if(!f.resizing){c(this).addClass("ui-resizable-autohide");f._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var e=function(g){c(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var f=this.element;f.after(this.originalElement.css({position:f.css("position"),width:f.outerWidth(),height:f.outerHeight(),top:f.css("top"),left:f.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(f){var g=false;for(var e in this.handles){if(c(this.handles[e])[0]==f.target){g=true}}return !this.options.disabled&&g},_mouseStart:function(g){var j=this.options,f=this.element.position(),e=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(e.is(".ui-draggable")||(/absolute/).test(e.css("position"))){e.css({position:"absolute",top:f.top,left:f.left})}this._renderProxy();var k=b(this.helper.css("left")),h=b(this.helper.css("top"));if(j.containment){k+=c(j.containment).scrollLeft()||0;h+=c(j.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:k,top:h};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:k,top:h};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:g.pageX,top:g.pageY};this.aspectRatio=(typeof j.aspectRatio=="number")?j.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var i=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",i=="auto"?this.axis+"-resize":i);e.addClass("ui-resizable-resizing");this._propagate("start",g);return true},_mouseDrag:function(e){var h=this.helper,g=this.options,m={},q=this,j=this.originalMousePosition,n=this.axis;var r=(e.pageX-j.left)||0,p=(e.pageY-j.top)||0;var i=this._change[n];if(!i){return false}var l=i.apply(this,[e,r,p]),k=c.browser.msie&&c.browser.version<7,f=this.sizeDiff;this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey){l=this._updateRatio(l,e)}l=this._respectSize(l,e);this._propagate("resize",e);h.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(l);this._trigger("resize",e,this.ui());return false},_mouseStop:function(h){this.resizing=false;var i=this.options,m=this;if(this._helper){var g=this._proportionallyResizeElements,e=g.length&&(/textarea/i).test(g[0].nodeName),f=e&&c.ui.hasScroll(g[0],"left")?0:m.sizeDiff.height,k=e?0:m.sizeDiff.width;var n={width:(m.helper.width()-k),height:(m.helper.height()-f)},j=(parseInt(m.element.css("left"),10)+(m.position.left-m.originalPosition.left))||null,l=(parseInt(m.element.css("top"),10)+(m.position.top-m.originalPosition.top))||null;if(!i.animate){this.element.css(c.extend(n,{top:l,left:j}))}m.helper.height(m.size.height);m.helper.width(m.size.width);if(this._helper&&!i.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",h);if(this._helper){this.helper.remove()}return false},_updateVirtualBoundaries:function(g){var j=this.options,i,h,f,k,e;e={minWidth:a(j.minWidth)?j.minWidth:0,maxWidth:a(j.maxWidth)?j.maxWidth:Infinity,minHeight:a(j.minHeight)?j.minHeight:0,maxHeight:a(j.maxHeight)?j.maxHeight:Infinity};if(this._aspectRatio||g){i=e.minHeight*this.aspectRatio;f=e.minWidth/this.aspectRatio;h=e.maxHeight*this.aspectRatio;k=e.maxWidth/this.aspectRatio;if(i>e.minWidth){e.minWidth=i}if(f>e.minHeight){e.minHeight=f}if(hl.width),s=a(l.height)&&i.minHeight&&(i.minHeight>l.height);if(h){l.width=i.minWidth}if(s){l.height=i.minHeight}if(t){l.width=i.maxWidth}if(m){l.height=i.maxHeight}var f=this.originalPosition.left+this.originalSize.width,p=this.position.top+this.size.height;var k=/sw|nw|w/.test(q),e=/nw|ne|n/.test(q);if(h&&k){l.left=f-i.minWidth}if(t&&k){l.left=f-i.maxWidth}if(s&&e){l.top=p-i.minHeight}if(m&&e){l.top=p-i.maxHeight}var n=!l.width&&!l.height;if(n&&!l.left&&l.top){l.top=null}else{if(n&&!l.top&&l.left){l.left=null}}return l},_proportionallyResize:function(){var k=this.options;if(!this._proportionallyResizeElements.length){return}var g=this.helper||this.element;for(var f=0;f');var e=c.browser.msie&&c.browser.version<7,g=(e?1:0),h=(e?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+h,height:this.element.outerHeight()+h,position:"absolute",left:this.elementOffset.left-g+"px",top:this.elementOffset.top-g+"px",zIndex:++i.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(g,f,e){return{width:this.originalSize.width+f}},w:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{left:i.left+f,width:g.width-f}},n:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{top:i.top+e,height:g.height-e}},s:function(g,f,e){return{height:this.originalSize.height+e}},se:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},sw:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[g,f,e]))},ne:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},nw:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[g,f,e]))}},_propagate:function(f,e){c.ui.plugin.call(this,f,[e,this.ui()]);(f!="resize"&&this._trigger(f,e,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});c.extend(c.ui.resizable,{version:"1.8.18"});c.ui.plugin.add("resizable","alsoResize",{start:function(f,g){var e=c(this).data("resizable"),i=e.options;var h=function(j){c(j).each(function(){var k=c(this);k.data("resizable-alsoresize",{width:parseInt(k.width(),10),height:parseInt(k.height(),10),left:parseInt(k.css("left"),10),top:parseInt(k.css("top"),10)})})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.parentNode){if(i.alsoResize.length){i.alsoResize=i.alsoResize[0];h(i.alsoResize)}else{c.each(i.alsoResize,function(j){h(j)})}}else{h(i.alsoResize)}},resize:function(g,i){var f=c(this).data("resizable"),j=f.options,h=f.originalSize,l=f.originalPosition;var k={height:(f.size.height-h.height)||0,width:(f.size.width-h.width)||0,top:(f.position.top-l.top)||0,left:(f.position.left-l.left)||0},e=function(m,n){c(m).each(function(){var q=c(this),r=c(this).data("resizable-alsoresize"),p={},o=n&&n.length?n:q.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];c.each(o,function(s,u){var t=(r[u]||0)+(k[u]||0);if(t&&t>=0){p[u]=t||null}});q.css(p)})};if(typeof(j.alsoResize)=="object"&&!j.alsoResize.nodeType){c.each(j.alsoResize,function(m,n){e(m,n)})}else{e(j.alsoResize)}},stop:function(e,f){c(this).removeData("resizable-alsoresize")}});c.ui.plugin.add("resizable","animate",{stop:function(i,n){var p=c(this).data("resizable"),j=p.options;var h=p._proportionallyResizeElements,e=h.length&&(/textarea/i).test(h[0].nodeName),f=e&&c.ui.hasScroll(h[0],"left")?0:p.sizeDiff.height,l=e?0:p.sizeDiff.width;var g={width:(p.size.width-l),height:(p.size.height-f)},k=(parseInt(p.element.css("left"),10)+(p.position.left-p.originalPosition.left))||null,m=(parseInt(p.element.css("top"),10)+(p.position.top-p.originalPosition.top))||null;p.element.animate(c.extend(g,m&&k?{top:m,left:k}:{}),{duration:j.animateDuration,easing:j.animateEasing,step:function(){var o={width:parseInt(p.element.css("width"),10),height:parseInt(p.element.css("height"),10),top:parseInt(p.element.css("top"),10),left:parseInt(p.element.css("left"),10)};if(h&&h.length){c(h[0]).css({width:o.width,height:o.height})}p._updateCache(o);p._propagate("resize",i)}})}});c.ui.plugin.add("resizable","containment",{start:function(f,r){var t=c(this).data("resizable"),j=t.options,l=t.element;var g=j.containment,k=(g instanceof c)?g.get(0):(/parent/.test(g))?l.parent().get(0):g;if(!k){return}t.containerElement=c(k);if(/document/.test(g)||g==document){t.containerOffset={left:0,top:0};t.containerPosition={left:0,top:0};t.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var n=c(k),i=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){i[p]=b(n.css("padding"+o))});t.containerOffset=n.offset();t.containerPosition=n.position();t.containerSize={height:(n.innerHeight()-i[3]),width:(n.innerWidth()-i[1])};var q=t.containerOffset,e=t.containerSize.height,m=t.containerSize.width,h=(c.ui.hasScroll(k,"left")?k.scrollWidth:m),s=(c.ui.hasScroll(k)?k.scrollHeight:e);t.parentData={element:k,left:q.left,top:q.top,width:h,height:s}}},resize:function(g,q){var t=c(this).data("resizable"),i=t.options,f=t.containerSize,p=t.containerOffset,m=t.size,n=t.position,r=t._aspectRatio||g.shiftKey,e={top:0,left:0},h=t.containerElement;if(h[0]!=document&&(/static/).test(h.css("position"))){e=p}if(n.left<(t._helper?p.left:0)){t.size.width=t.size.width+(t._helper?(t.position.left-p.left):(t.position.left-e.left));if(r){t.size.height=t.size.width/i.aspectRatio}t.position.left=i.helper?p.left:0}if(n.top<(t._helper?p.top:0)){t.size.height=t.size.height+(t._helper?(t.position.top-p.top):t.position.top);if(r){t.size.width=t.size.height*i.aspectRatio}t.position.top=t._helper?p.top:0}t.offset.left=t.parentData.left+t.position.left;t.offset.top=t.parentData.top+t.position.top;var l=Math.abs((t._helper?t.offset.left-e.left:(t.offset.left-e.left))+t.sizeDiff.width),s=Math.abs((t._helper?t.offset.top-e.top:(t.offset.top-p.top))+t.sizeDiff.height);var k=t.containerElement.get(0)==t.element.parent().get(0),j=/relative|absolute/.test(t.containerElement.css("position"));if(k&&j){l-=t.parentData.left}if(l+t.size.width>=t.parentData.width){t.size.width=t.parentData.width-l;if(r){t.size.height=t.size.width/t.aspectRatio}}if(s+t.size.height>=t.parentData.height){t.size.height=t.parentData.height-s;if(r){t.size.width=t.size.height*t.aspectRatio}}},stop:function(f,n){var q=c(this).data("resizable"),g=q.options,l=q.position,m=q.containerOffset,e=q.containerPosition,i=q.containerElement;var j=c(q.helper),r=j.offset(),p=j.outerWidth()-q.sizeDiff.width,k=j.outerHeight()-q.sizeDiff.height;if(q._helper&&!g.animate&&(/relative/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}if(q._helper&&!g.animate&&(/static/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}}});c.ui.plugin.add("resizable","ghost",{start:function(g,h){var e=c(this).data("resizable"),i=e.options,f=e.size;e.ghost=e.originalElement.clone();e.ghost.css({opacity:0.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:"");e.ghost.appendTo(e.helper)},resize:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost){e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})}},stop:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost&&e.helper){e.helper.get(0).removeChild(e.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(e,m){var p=c(this).data("resizable"),h=p.options,k=p.size,i=p.originalSize,j=p.originalPosition,n=p.axis,l=h._aspectRatio||e.shiftKey;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var g=Math.round((k.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1),f=Math.round((k.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f}else{if(/^(ne)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f}else{if(/^(sw)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.left=j.left-g}else{p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f;p.position.left=j.left-g}}}}});var b=function(e){return parseInt(e,10)||0};var a=function(e){return !isNaN(parseInt(e,10))}})(jQuery);/* + * jQuery hashchange event - v1.3 - 7/21/2010 + * http://benalman.com/projects/jquery-hashchange-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ +(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$(' + + + + +
+ +
+
matrix.h File Reference
+
+
+ +

Optional matrix-specific helpers and specializations. +More...

+
#include "array/array.h"
+
+

Go to the source code of this file.

+
+ + + +

+Classes

class  shape_traits< matrix_shape< Rows, Cols > >
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Typedefs

template<index_t Rows = dynamic, index_t Cols = dynamic>
using matrix_shape = shape< dim< dynamic, Rows >, dense_dim< dynamic, Cols >>
 
template<class T , index_t Rows = dynamic, index_t Cols = dynamic, class Alloc = std::allocator<T>>
using matrix = array< T, matrix_shape< Rows, Cols >, Alloc >
 
+template<class T , index_t Rows = dynamic, index_t Cols = dynamic>
using matrix_ref = array_ref< T, matrix_shape< Rows, Cols >>
 
+template<class T , index_t Rows = dynamic, index_t Cols = dynamic>
using const_matrix_ref = matrix_ref< const T, Rows, Cols >
 
template<index_t Length = dynamic>
using vector_shape = shape< dense_dim< dynamic, Length >>
 
+template<class T , index_t Length = dynamic, class Alloc = std::allocator<T>>
using vector = array< T, vector_shape< Length >, Alloc >
 
+template<class T , index_t Length = dynamic>
using vector_ref = array_ref< T, vector_shape< Length >>
 
+template<class T , index_t Length = dynamic>
using const_vector_ref = vector_ref< const T, Length >
 
template<class T , index_t Rows, index_t Cols>
using small_matrix = array< T, matrix_shape< Rows, Cols >, auto_allocator< T, Rows *Cols >>
 
+template<class T , index_t Length>
using small_vector = array< T, vector_shape< Length >, auto_allocator< T, Length >>
 
+ + + + +

+Functions

template<class Shape , class Fn >
void for_each_matrix_index (const Shape &s, Fn &&fn)
 
+

Detailed Description

+

Optional matrix-specific helpers and specializations.

+

Typedef Documentation

+ +
+
+ + + + +
using matrix_shape = shape<dim<dynamic, Rows>, dense_dim<dynamic, Cols>>
+
+

The standard matrix notation is to refer to elements by 'row, column'. To make this efficient for typical programs, we're going to make the second dimension the dense dim. This shape has the option of making the size of the matrix compile-time constant via the template parameters.

+ +
+
+ +
+
+ + + + +
using matrix = array<T, matrix_shape<Rows, Cols>, Alloc>
+
+

A matrix or matrix_ref is an array or array_ref with Shape = matrix_shape.

+ +
+
+ +
+
+ + + + +
using vector_shape = shape<dense_dim<dynamic, Length>>
+
+

A vector is just a 1-d array.

+ +
+
+ +
+
+ + + + +
using small_matrix = array<T, matrix_shape<Rows, Cols>, auto_allocator<T, Rows * Cols>>
+
+

A matrix with static dimensions Rows and Cols, with an auto_allocator.

+ +
+
+

Function Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + +
void nda::for_each_matrix_index (const Shape & s,
Fn && fn 
)
+
+

Calls fn for each index in a matrix shape s.

+ +
+
+ + + + + diff --git a/matrix_8h_source.html b/matrix_8h_source.html new file mode 100644 index 00000000..1a00f5f0 --- /dev/null +++ b/matrix_8h_source.html @@ -0,0 +1,114 @@ + + + + + + +array: include/array/matrix.h Source File + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
matrix.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
18 #ifndef NDARRAY_MATRIX_H
19 #define NDARRAY_MATRIX_H
20 
21 #include "array/array.h"
22 
23 namespace nda {
24 
30 template <index_t Rows = dynamic, index_t Cols = dynamic>
32 
35 template <class T, index_t Rows = dynamic, index_t Cols = dynamic, class Alloc = std::allocator<T>>
37 template <class T, index_t Rows = dynamic, index_t Cols = dynamic>
39 template <class T, index_t Rows = dynamic, index_t Cols = dynamic>
41 
43 template <index_t Length = dynamic>
45 
46 template <class T, index_t Length = dynamic, class Alloc = std::allocator<T>>
48 template <class T, index_t Length = dynamic>
50 template <class T, index_t Length = dynamic>
52 
55 template <class T, index_t Rows, index_t Cols>
57 template <class T, index_t Length>
59 
61 template <class Shape, class Fn>
62 void for_each_matrix_index(const Shape& s, Fn&& fn) {
63  for (index_t i : s.i()) {
64  for (index_t j : s.j()) {
65  fn(std::tuple<index_t, index_t>(i, j));
66  }
67  }
68 }
69 
70 template <index_t Rows, index_t Cols>
71 class shape_traits<matrix_shape<Rows, Cols>> {
72 public:
74 
75  template <class Fn>
76  static void for_each_index(const shape_type& s, Fn&& fn) {
77  for_each_matrix_index(s, fn);
78  }
79 
80  template <class Ptr, class Fn>
81  static void for_each_value(const shape_type& s, Ptr base, Fn&& fn) {
83  s, [=, fn = std::move(fn)](const typename shape_type::index_type& i) { fn(base[s[i]]); });
84  }
85 };
86 
87 } // namespace nda
88 
89 #endif // NDARRAY_MATRIX_H
index_of_rank< rank()> index_type
Definition: array.h:1076
+
Definition: array.h:1036
+
static NDARRAY_HOST_DEVICE void for_each_value(const Shape &shape, Ptr base, Fn &&fn)
Definition: array.h:1874
+
Definition: array.h:1953
+
Definition: array.h:1955
+
Main header for array library.
+
Definition: absl.h:10
+
Definition: array.h:1859
+
Definition: array.h:3065
+
std::ptrdiff_t index_t
Definition: array.h:87
+
Definition: array.h:231
+
void for_each_matrix_index(const Shape &s, Fn &&fn)
Definition: matrix.h:62
+
static NDARRAY_HOST_DEVICE void for_each_index(const Shape &shape, Fn &&fn)
Definition: array.h:1866
+
+ + + + diff --git a/md_CONTRIBUTING.html b/md_CONTRIBUTING.html new file mode 100644 index 00000000..a4cc8424 --- /dev/null +++ b/md_CONTRIBUTING.html @@ -0,0 +1,100 @@ + + + + + + +array: How to Contribute + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + +
+
+ + +
+ +
+ +
+
+
+
How to Contribute
+
+
+

We'd love to accept your patches and contributions to this project. There are just a few small guidelines you need to follow.

+

Contributor License Agreement

+

Contributions to this project must be accompanied by a Contributor License Agreement. You (or your employer) retain the copyright to your contribution; this simply gives us permission to use and redistribute your contributions as part of the project. Head over to https://cla.developers.google.com/ to see your current agreements on file or to sign a new one.

+

You generally only need to submit a CLA once, so if you've already submitted one (even if it was for a different project), you probably don't need to do it again.

+

Code reviews

+

All submissions, including submissions by project members, require review. We use GitHub pull requests for this purpose. Consult GitHub Help for more information on using pull requests.

+

Community Guidelines

+

This project follows Google's Open Source Community Guidelines.

+
+ + + + diff --git a/nav_f.png b/nav_f.png new file mode 100644 index 0000000000000000000000000000000000000000..72a58a529ed3a9ed6aa0c51a79cf207e026deee2 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQVE_ejv*C{Z|{2ZH7M}7UYxc) zn!W8uqtnIQ>_z8U literal 0 HcmV?d00001 diff --git a/nav_g.png b/nav_g.png new file mode 100644 index 0000000000000000000000000000000000000000..2093a237a94f6c83e19ec6e5fd42f7ddabdafa81 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^j6lrB!3HFm1ilyoDK$?Q$B+ufw|5PB85lU25BhtE tr?otc=hd~V+ws&_A@j8Fiv!KF$B+ufw|5=67#uj90@pIL wZ=Q8~_Ju`#59=RjDrmm`tMD@M=!-l18IR?&vFVdQ&MBb@0HFXL1|%O$WD@{VPM$7~Ar*{o?;hlAFyLXmaDC0y znK1_#cQqJWPES%4Uujug^TE?jMft$}Eq^WaR~)%f)vSNs&gek&x%A9X9sM + + + + + +array: Related Pages + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + +
+ +
+
+ + +
+ +
+ +
+
+
Related Pages
+
+
+
Here is a list of all related documentation pages:
+
+ + + + diff --git a/search/all_0.html b/search/all_0.html new file mode 100644 index 00000000..d54e0bd8 --- /dev/null +++ b/search/all_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_0.js b/search/all_0.js new file mode 100644 index 00000000..9ef7a31f --- /dev/null +++ b/search/all_0.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['all',['all',['../array_8h.html#ac1b8df81276b556535053bc15e7da68c',1,'nda']]], + ['allocator_5ftype',['allocator_type',['../classnda_1_1array.html#a85263a9e2d1f4da2cde00205ca6f8d08',1,'nda::array']]], + ['array',['array',['../classnda_1_1array.html',1,'nda']]], + ['array',['array',['../classnda_1_1array.html#a9cbcfcbf0173e1edaf4094bb36b34b31',1,'nda::array::array()'],['../classnda_1_1array.html#ab5192700ae6219b033f6189c9e107acf',1,'nda::array::array(const Shape &shape, const T &value, const Alloc &alloc)'],['../classnda_1_1array.html#a7c078dc760b41e16af85a2adcf20c9bf',1,'nda::array::array(const Shape &shape, const Alloc &alloc)'],['../classnda_1_1array.html#a774ae5d2eea9dc62d6d45605ac0c7b58',1,'nda::array::array(const array &other)'],['../classnda_1_1array.html#aed842c0465cf2a349c98a43d0aea51e2',1,'nda::array::array(const array &other, const Alloc &alloc)'],['../classnda_1_1array.html#af9cb440fd9a7e30b1d53f50ca6339ed7',1,'nda::array::array(array &&other)'],['../classnda_1_1array.html#a5d433dab95a40026beda80a8671b26ef',1,'nda::array::array(array &&other, const Alloc &alloc)']]], + ['array_2eh',['array.h',['../array_8h.html',1,'']]], + ['array_5fof_5frank',['array_of_rank',['../array_8h.html#aec3848811e2aae330fb669a23f30cd2e',1,'nda']]], + ['array_5fref',['array_ref',['../classnda_1_1array__ref.html',1,'nda']]], + ['array_5fref',['array_ref',['../classnda_1_1array__ref.html#ac5dd1d0ed235a23d1d5658cfb15e00b9',1,'nda::array_ref::array_ref(pointer base=nullptr, const Shape &shape=Shape())'],['../classnda_1_1array__ref.html#a477a69276fcfc5ef0e55851408e4cb9f',1,'nda::array_ref::array_ref(const array_ref &other)=default'],['../classnda_1_1array__ref.html#acf34a5e4381fc949489cd6dddb27cf3c',1,'nda::array_ref::array_ref(const array_ref< T, OtherShape > &other)']]], + ['array_5fref_5fof_5frank',['array_ref_of_rank',['../array_8h.html#a4edeffa5f4878abb67a08b3eccdc9d2a',1,'nda']]], + ['assign',['assign',['../classnda_1_1array.html#a5653922b5fd47d896f50ecb602cc6f98',1,'nda::array::assign(const array &other)'],['../classnda_1_1array.html#ab5ce5fbdb7855c3c5fbc420401de02c0',1,'nda::array::assign(Shape shape, const T &value)']]], + ['auto_5fallocator',['auto_allocator',['../classnda_1_1auto__allocator.html',1,'nda']]], + ['about',['About',['../index.html',1,'']]] +]; diff --git a/search/all_1.html b/search/all_1.html new file mode 100644 index 00000000..8cc6a1de --- /dev/null +++ b/search/all_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_1.js b/search/all_1.js new file mode 100644 index 00000000..0fbf6616 --- /dev/null +++ b/search/all_1.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['base',['base',['../classnda_1_1array__ref.html#ae10f9e3cb54d90b15a71f790d821e712',1,'nda::array_ref::base()'],['../classnda_1_1array.html#a8ae0eb182e9f3daffda7a2d70fab14f6',1,'nda::array::base()']]], + ['begin',['begin',['../classnda_1_1interval.html#aff27edf947d386512a5a9ac88bb2399e',1,'nda::interval::begin()'],['../array_8h.html#a074fffb7cad44b70b9a5dc0793560dfd',1,'nda::begin()']]], + ['broadcast_5fdim',['broadcast_dim',['../array_8h.html#a1c13f3faa99c074549d5f2265cc7ba1d',1,'nda']]] +]; diff --git a/search/all_10.html b/search/all_10.html new file mode 100644 index 00000000..c25484f2 --- /dev/null +++ b/search/all_10.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_10.js b/search/all_10.js new file mode 100644 index 00000000..8b623446 --- /dev/null +++ b/search/all_10.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['value_5ftype',['value_type',['../classnda_1_1array__ref.html#afb9ded5f49336ae503bb9f2035ea902b',1,'nda::array_ref::value_type()'],['../classnda_1_1array.html#afb9ded5f49336ae503bb9f2035ea902b',1,'nda::array::value_type()']]], + ['vector_5fshape',['vector_shape',['../matrix_8h.html#a19ca079501513b056a3819a8a1d71904',1,'nda']]] +]; diff --git a/search/all_11.html b/search/all_11.html new file mode 100644 index 00000000..3615c281 --- /dev/null +++ b/search/all_11.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_11.js b/search/all_11.js new file mode 100644 index 00000000..073ae147 --- /dev/null +++ b/search/all_11.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['width',['width',['../classnda_1_1shape.html#a4a8968cace8d3331f70c8cb1a7be4185',1,'nda::shape::width()'],['../classnda_1_1array__ref.html#a4a8968cace8d3331f70c8cb1a7be4185',1,'nda::array_ref::width()'],['../classnda_1_1array.html#aba1ae59e8ea89231b67e008dc4b03d07',1,'nda::array::width()']]] +]; diff --git a/search/all_12.html b/search/all_12.html new file mode 100644 index 00000000..abd082a5 --- /dev/null +++ b/search/all_12.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_12.js b/search/all_12.js new file mode 100644 index 00000000..11d9d1b2 --- /dev/null +++ b/search/all_12.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['x',['x',['../classnda_1_1shape.html#ac58f67021d52c625bb34bcd10e7dba57',1,'nda::shape::x()'],['../classnda_1_1array__ref.html#ac58f67021d52c625bb34bcd10e7dba57',1,'nda::array_ref::x()'],['../classnda_1_1array.html#adedb30a4a8d84863378e80cc522313a5',1,'nda::array::x()']]] +]; diff --git a/search/all_13.html b/search/all_13.html new file mode 100644 index 00000000..88fa6531 --- /dev/null +++ b/search/all_13.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_13.js b/search/all_13.js new file mode 100644 index 00000000..23b14b72 --- /dev/null +++ b/search/all_13.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['z_5forder_2eh',['z_order.h',['../z__order_8h.html',1,'']]] +]; diff --git a/search/all_2.html b/search/all_2.html new file mode 100644 index 00000000..d15ac65f --- /dev/null +++ b/search/all_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_2.js b/search/all_2.js new file mode 100644 index 00000000..66b716d5 --- /dev/null +++ b/search/all_2.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['cast',['cast',['../ein__reduce_8h.html#a04504a9b60455f3e094c1ef92e0caece',1,'nda']]], + ['chunky_5fimage_5fshape',['chunky_image_shape',['../image_8h.html#a249fdb84b708f002090a88bff2f24bc2',1,'nda']]], + ['clamp',['clamp',['../array_8h.html#a191ec3144f7249e6f2679ce4648e3c67',1,'nda::clamp(index_t x, index_t min, index_t max)'],['../array_8h.html#a14484b48d68ae36f12f40248f78f2b43',1,'nda::clamp(index_t x, const Range &r)']]], + ['clear',['clear',['../classnda_1_1array.html#ac8bb3912a3ce86b15842e79d0b421204',1,'nda::array']]], + ['convert_5fshape',['convert_shape',['../array_8h.html#aa632dc4e183e8b352b3b5fc49740f5e5',1,'nda::convert_shape(const ShapeSrc &src)'],['../array_8h.html#a581151c44eee997515985c82272c882a',1,'nda::convert_shape(const array_ref< T, OldShape > &a)']]], + ['copy',['copy',['../array_8h.html#a01b188d9c649d32dde879e9635553236',1,'nda']]], + ['copy_5fshape_5ftraits',['copy_shape_traits',['../classnda_1_1copy__shape__traits.html',1,'nda']]], + ['cref',['cref',['../classnda_1_1array__ref.html#a9b12a5debe0510d43c65b4c0e9ac70f0',1,'nda::array_ref']]], + ['crop',['crop',['../image_8h.html#abb22eefc64b333108c8690a5583c17ef',1,'nda']]], + ['crop_5fimage_5fshape',['crop_image_shape',['../image_8h.html#a91f4d38c179897ea0fc84c3c32199e78',1,'nda']]] +]; diff --git a/search/all_3.html b/search/all_3.html new file mode 100644 index 00000000..9f526c67 --- /dev/null +++ b/search/all_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_3.js b/search/all_3.js new file mode 100644 index 00000000..fed4dd0b --- /dev/null +++ b/search/all_3.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['data',['data',['../classnda_1_1array__ref.html#ab486420d3dc781972553446917d4b8af',1,'nda::array_ref::data()'],['../classnda_1_1array.html#a36e4d11a00a3572c87bf7e913e9b5ca1',1,'nda::array::data()']]], + ['dense_5farray',['dense_array',['../array_8h.html#a6fd5dd48fcb68ce48daff5d746cb297c',1,'nda']]], + ['dense_5farray_5fref',['dense_array_ref',['../array_8h.html#a3bbaedd9bb2f66c68d0dbc60fefafde1',1,'nda']]], + ['dense_5fdim',['dense_dim',['../array_8h.html#a00c87b9adb5a4f4ad386e78145eabc2f',1,'nda']]], + ['dense_5fshape',['dense_shape',['../array_8h.html#aa200a0a9e702ec0241adb18f351acbe2',1,'nda']]], + ['dim',['dim',['../classnda_1_1dim.html#a686aa62054ac7ca73764fe31194a5ff8',1,'nda::dim::dim(index_t min, index_t extent, index_t stride=DefaultStride)'],['../classnda_1_1dim.html#a2698a997cef9db0fb52c214f5daaa7e7',1,'nda::dim::dim(const dim< CopyMin, CopyExtent, CopyStride > &other)'],['../classnda_1_1shape.html#a719809b7b6ac1f5b7c80345003fb3fed',1,'nda::shape::dim()'],['../classnda_1_1shape.html#a094f7cc42bf8449e5afa9ac3c61dd306',1,'nda::shape::dim(size_t d) const ']]], + ['dim',['dim',['../classnda_1_1dim.html',1,'nda']]], + ['dims',['dims',['../classnda_1_1shape.html#a0fe377b16e5d8c0ee0d37d8c6ad3ba67',1,'nda::shape']]], + ['dims_5ftype',['dims_type',['../classnda_1_1shape.html#af0388cf8747db7b5851f2588d234aa04',1,'nda::shape']]], + ['dynamic',['dynamic',['../array_8h.html#adab240e3956fad6af13ebafd594e007b',1,'nda']]] +]; diff --git a/search/all_4.html b/search/all_4.html new file mode 100644 index 00000000..7b814aa9 --- /dev/null +++ b/search/all_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_4.js b/search/all_4.js new file mode 100644 index 00000000..302d1d25 --- /dev/null +++ b/search/all_4.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['ein',['ein',['../ein__reduce_8h.html#a5aa6163421edd4ccbbc3da74c6505e7d',1,'nda::ein(Op op)'],['../ein__reduce_8h.html#a6f688a219c0e3e3505fd362314dfdce8',1,'nda::ein(T &scalar)'],['../ein__reduce_8h.html#acec822fa92f9c968aa1e06618b1ba5f7',1,'nda::ein(T *x, size_t N)'],['../ein__reduce_8h.html#a2c3f1b7ac8f4a0ed403a92dc6e9274d6',1,'nda::ein(T(&x)[N])']]], + ['ein_5freduce',['ein_reduce',['../ein__reduce_8h.html#a9a5162bd8e63b8ca47f92b1db361f187',1,'nda']]], + ['ein_5freduce_2eh',['ein_reduce.h',['../ein__reduce_8h.html',1,'']]], + ['empty',['empty',['../classnda_1_1shape.html#aab43a7928dcecaeab73b980085280fa3',1,'nda::shape']]], + ['end',['end',['../classnda_1_1interval.html#ae939570ab7ef11ef979f480fc9e0a1b1',1,'nda::interval']]], + ['equal',['equal',['../array_8h.html#a000b1575954b4090010bd13bf07582f7',1,'nda']]], + ['extent',['extent',['../classnda_1_1interval.html#a8d67ee86467dd9c72448c873ccd44cd5',1,'nda::interval']]] +]; diff --git a/search/all_5.html b/search/all_5.html new file mode 100644 index 00000000..d8de5560 --- /dev/null +++ b/search/all_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_5.js b/search/all_5.js new file mode 100644 index 00000000..acc8fe98 --- /dev/null +++ b/search/all_5.js @@ -0,0 +1,16 @@ +var searchData= +[ + ['fill',['fill',['../array_8h.html#a5f24975ef5bc1a5ab2e91297dfede713',1,'nda']]], + ['fixed_5fdense_5fshape',['fixed_dense_shape',['../array_8h.html#ac7b935efb37c2765a3aae7b2ecaeec26',1,'nda']]], + ['fixed_5fdim',['fixed_dim',['../array_8h.html#adb0209166945d62a1629fc11e434ac98',1,'nda']]], + ['fixed_5finterval',['fixed_interval',['../array_8h.html#a211cabf0fcc1a09e896e0af76704dd6f',1,'nda']]], + ['flat_5fmin',['flat_min',['../classnda_1_1shape.html#aff932e9efe2a5008c18640ce8511cbdf',1,'nda::shape']]], + ['flat_5foffset',['flat_offset',['../classnda_1_1dim.html#a64e5e3f2fb394906c42db9a60905a5d2',1,'nda::dim']]], + ['for_5feach_5fimage_5findex',['for_each_image_index',['../image_8h.html#a091367fadb4a9f2bcc2cce86510b333e',1,'nda']]], + ['for_5feach_5fin_5fz_5forder',['for_each_in_z_order',['../z__order_8h.html#a10f3e8b3c937a0136735ee3c82a0dc0f',1,'nda']]], + ['for_5feach_5findex',['for_each_index',['../classnda_1_1shape__traits.html#ad448f38a01290588e4f8967731898875',1,'nda::shape_traits::for_each_index()'],['../array_8h.html#aeedf4c4fe3a73f56a9f72ea34a2b6dad',1,'nda::for_each_index()']]], + ['for_5feach_5findex_5fin_5forder',['for_each_index_in_order',['../array_8h.html#acf31907f3bad61a417e225e5e135b7df',1,'nda']]], + ['for_5feach_5fmatrix_5findex',['for_each_matrix_index',['../matrix_8h.html#af063b25124f0dc1ceaf9bfe1918d426e',1,'nda']]], + ['for_5feach_5fvalue',['for_each_value',['../classnda_1_1shape__traits.html#a9e28d6fd81c177065f94b14e84f94151',1,'nda::shape_traits::for_each_value()'],['../classnda_1_1copy__shape__traits.html#a77faeb731a53f5f224253b680ff88336',1,'nda::copy_shape_traits::for_each_value()'],['../classnda_1_1array__ref.html#a64cfed71aabfac7d25e6d8f6a4ee8fe2',1,'nda::array_ref::for_each_value()'],['../classnda_1_1array.html#a73569de89267bd0df19702b44aadb849',1,'nda::array::for_each_value()']]], + ['for_5feach_5fvalue_5fin_5forder',['for_each_value_in_order',['../array_8h.html#a926d23314527bd0010642a211ed7b146',1,'nda']]] +]; diff --git a/search/all_6.html b/search/all_6.html new file mode 100644 index 00000000..9ba0cc2b --- /dev/null +++ b/search/all_6.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_6.js b/search/all_6.js new file mode 100644 index 00000000..d0c02f38 --- /dev/null +++ b/search/all_6.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['generate',['generate',['../array_8h.html#a097abdcd257c2c969ab07162957f2f88',1,'nda']]], + ['get_5fallocator',['get_allocator',['../classnda_1_1array.html#a085cd7aaff57eee6b414cd8e8e8bf0ad',1,'nda::array']]] +]; diff --git a/search/all_7.html b/search/all_7.html new file mode 100644 index 00000000..9384ec9b --- /dev/null +++ b/search/all_7.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_7.js b/search/all_7.js new file mode 100644 index 00000000..74895784 --- /dev/null +++ b/search/all_7.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['how_20to_20contribute',['How to Contribute',['../md_CONTRIBUTING.html',1,'']]] +]; diff --git a/search/all_8.html b/search/all_8.html new file mode 100644 index 00000000..37566c5d --- /dev/null +++ b/search/all_8.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_8.js b/search/all_8.js new file mode 100644 index 00000000..d50ff28b --- /dev/null +++ b/search/all_8.js @@ -0,0 +1,21 @@ +var searchData= +[ + ['i',['i',['../classnda_1_1shape.html#a504d6bc3b1206cfdea4ede9129e9caee',1,'nda::shape::i()'],['../classnda_1_1array__ref.html#a504d6bc3b1206cfdea4ede9129e9caee',1,'nda::array_ref::i()'],['../classnda_1_1array.html#a2770acc12189beee7859043d88439d51',1,'nda::array::i()']]], + ['image_2eh',['image.h',['../image_8h.html',1,'']]], + ['image_5fshape',['image_shape',['../image_8h.html#ab16c89cd2b804f25799ddaac21799b74',1,'nda']]], + ['index_5fiterator',['index_iterator',['../classnda_1_1index__iterator.html#a62df1f8cbacb16c289873af363c67f7f',1,'nda::index_iterator']]], + ['index_5fiterator',['index_iterator',['../classnda_1_1index__iterator.html',1,'nda']]], + ['index_5fof_5frank',['index_of_rank',['../array_8h.html#ad7866b82526d5276e559a3bc02e09686',1,'nda']]], + ['index_5ft',['index_t',['../array_8h.html#a26493ae85adc5b160363a05a6cd4f11e',1,'nda']]], + ['index_5ftype',['index_type',['../classnda_1_1shape.html#a97955e667dea657b46e7a1c6dc8662b0',1,'nda::shape']]], + ['interval',['interval',['../classnda_1_1interval.html',1,'nda']]], + ['interval',['interval',['../classnda_1_1interval.html#a4dee77951e705492364157324fd8d412',1,'nda::interval::interval(index_t min, index_t extent)'],['../classnda_1_1interval.html#aff8471c16c498902142cff7bcd07425c',1,'nda::interval::interval(const interval< CopyMin, CopyExtent > &other)']]], + ['is_5fcompact',['is_compact',['../classnda_1_1shape.html#abd45f97dc64adf81fe521d5433646a14',1,'nda::shape']]], + ['is_5fcompatible',['is_compatible',['../array_8h.html#ac68a87c9486d77bb1c2c8bc8f3587290',1,'nda']]], + ['is_5fexplicitly_5fcompatible',['is_explicitly_compatible',['../array_8h.html#aef30cae2d67c4103d15cfbcfff0f349a',1,'nda']]], + ['is_5fin_5frange',['is_in_range',['../classnda_1_1interval.html#acd5fea1c30fe8fcb65f11afd864be619',1,'nda::interval::is_in_range(index_t at) const '],['../classnda_1_1interval.html#a62124bc4a9f1d56d964af2f2b69933da',1,'nda::interval::is_in_range(const interval< OtherMin, OtherExtent > &at) const '],['../classnda_1_1shape.html#a4a4bb5bc425aec205499251ad4254152',1,'nda::shape::is_in_range()']]], + ['is_5fone_5fto_5fone',['is_one_to_one',['../classnda_1_1shape.html#a0438eea3c7137c00a30a62175798bff2',1,'nda::shape']]], + ['is_5fresolved',['is_resolved',['../classnda_1_1shape.html#a26d0a400bf6c6fc454b241f9bf22cf4f',1,'nda::shape']]], + ['is_5fscalar',['is_scalar',['../classnda_1_1shape.html#a861fe2369858d96f8d9eb67318b89e89',1,'nda::shape::is_scalar()'],['../classnda_1_1array__ref.html#a861fe2369858d96f8d9eb67318b89e89',1,'nda::array_ref::is_scalar()'],['../classnda_1_1array.html#a861fe2369858d96f8d9eb67318b89e89',1,'nda::array::is_scalar()']]], + ['is_5fsubset_5fof',['is_subset_of',['../classnda_1_1shape.html#aa6eabf385d230a7322100376dad699ec',1,'nda::shape']]] +]; diff --git a/search/all_9.html b/search/all_9.html new file mode 100644 index 00000000..c8c51023 --- /dev/null +++ b/search/all_9.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_9.js b/search/all_9.js new file mode 100644 index 00000000..e9cefe33 --- /dev/null +++ b/search/all_9.js @@ -0,0 +1,20 @@ +var searchData= +[ + ['make_5farray',['make_array',['../array_8h.html#a7b4a05d3f1a2fe00507e35bc10c516dd',1,'nda']]], + ['make_5farray_5fref',['make_array_ref',['../array_8h.html#a1ce93c483b477a4339650673058b60ba',1,'nda']]], + ['make_5fcompact',['make_compact',['../array_8h.html#ab5aeff46be2236fb32a203dfd2c0f6fe',1,'nda']]], + ['make_5fcompact_5fcopy',['make_compact_copy',['../array_8h.html#aac7f1b977c6d8977a608e96331cb44fd',1,'nda']]], + ['make_5fcompact_5fmove',['make_compact_move',['../array_8h.html#a4f444a4f82c3bdb70ba8aac5cdebe641',1,'nda']]], + ['make_5fcopy',['make_copy',['../array_8h.html#a7c58e26230741655aa32a915844758b5',1,'nda::make_copy(const array_ref< T, ShapeSrc > &src, const Alloc &alloc=Alloc())'],['../array_8h.html#a9c7d8cbb1a7ea679f9b0bba99d3d3150',1,'nda::make_copy(const array_ref< T, ShapeSrc > &src, const ShapeDst &shape, const Alloc &alloc=Alloc())']]], + ['make_5fein_5freduce_5fshape',['make_ein_reduce_shape',['../ein__reduce_8h.html#a7689fd5b57271dccb3d2d89f6c82d7c3',1,'nda']]], + ['make_5fein_5fsum',['make_ein_sum',['../ein__reduce_8h.html#af05e87f38452d1e7015eec619dcfb502',1,'nda']]], + ['make_5fmove',['make_move',['../array_8h.html#ae489781dfd7c05851bcc3bb770c25cb5',1,'nda']]], + ['make_5fshape',['make_shape',['../array_8h.html#acc77f5082e94f21c95849a1eefd016c3',1,'nda']]], + ['matrix',['matrix',['../matrix_8h.html#a6d932cdaa3dec58da49d4421dcc1f120',1,'nda']]], + ['matrix_2eh',['matrix.h',['../matrix_8h.html',1,'']]], + ['matrix_5fshape',['matrix_shape',['../matrix_8h.html#aaa130e57b659bcdf77735b38445aa975',1,'nda']]], + ['max',['max',['../classnda_1_1interval.html#a32c3f5335a9e4a6577da22ab6265d5ec',1,'nda::interval']]], + ['min',['min',['../classnda_1_1interval.html#acd9e0f9afe70a779088830a1aadf1868',1,'nda::interval::min()'],['../ein__reduce_8h.html#adbf4a1e9bc0aad43e7db974ef620d10d',1,'nda::min()']]], + ['move',['move',['../array_8h.html#aa94eb16dc22298d492152075dc8b3825',1,'nda']]], + ['move_5freinterpret_5fshape',['move_reinterpret_shape',['../array_8h.html#ab424a858ee8c8c675cd05db0e969cbb7',1,'nda']]] +]; diff --git a/search/all_a.html b/search/all_a.html new file mode 100644 index 00000000..4cb31f0c --- /dev/null +++ b/search/all_a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_a.js b/search/all_a.js new file mode 100644 index 00000000..11a2e9ad --- /dev/null +++ b/search/all_a.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['operator_20reference',['operator reference',['../classnda_1_1array__ref.html#a9da40a48bba2a09ee038aa9b2167c4d1',1,'nda::array_ref::operator reference()'],['../classnda_1_1array.html#a6d78072c3bbceeba3af7e7397f9b32e7',1,'nda::array::operator reference()']]], + ['operator_21_3d',['operator!=',['../classnda_1_1array__ref.html#aaf8d591fa163c447614f3fb32c039ba1',1,'nda::array_ref::operator!=()'],['../classnda_1_1array.html#a638f083b28e54c375647ce4b2d26a319',1,'nda::array::operator!=()']]], + ['operator_2a',['operator*',['../classnda_1_1index__iterator.html#abdd857d441092df709d943bd31e99950',1,'nda::index_iterator']]], + ['operator_3d',['operator=',['../classnda_1_1array.html#a45cd313b8ae4725bd46434747d77ba6d',1,'nda::array::operator=(const array &other)'],['../classnda_1_1array.html#ab4f4887bc4b87814a48bce11d846078c',1,'nda::array::operator=(array &&other)']]], + ['operator_3d_3d',['operator==',['../classnda_1_1interval.html#a9e386dd63e96d87ce8e0ee90b5bd4d8b',1,'nda::interval::operator==()'],['../classnda_1_1dim.html#afa804a735c8490decbfc233b1622c092',1,'nda::dim::operator==()'],['../classnda_1_1shape.html#a9c855e64a8a1336ffc7f704aa8101e31',1,'nda::shape::operator==()']]], + ['operator_5b_5d',['operator[]',['../classnda_1_1shape.html#a2e1352209053b18d9abbd7174b940d44',1,'nda::shape::operator[](const index_type &indices) const '],['../classnda_1_1shape.html#ae12935485bf90173a7a6c244b4a9c6fc',1,'nda::shape::operator[](const std::tuple< Args... > &args) const '],['../classnda_1_1array__ref.html#a9caca6ef754e57ec518aa27710f18ae2',1,'nda::array_ref::operator[](const index_type &indices) const '],['../classnda_1_1array__ref.html#ae12935485bf90173a7a6c244b4a9c6fc',1,'nda::array_ref::operator[](const std::tuple< Args... > &args) const '],['../classnda_1_1array.html#ae0d227928b333d03dcaa54bbc1baaec5',1,'nda::array::operator[](const index_type &indices)'],['../classnda_1_1array.html#a62832cea95b599bc923e67bad4e5f15e',1,'nda::array::operator[](const std::tuple< Args... > &args)']]] +]; diff --git a/search/all_b.html b/search/all_b.html new file mode 100644 index 00000000..d34a612e --- /dev/null +++ b/search/all_b.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_b.js b/search/all_b.js new file mode 100644 index 00000000..d19a3257 --- /dev/null +++ b/search/all_b.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['planar_5fimage_5fshape',['planar_image_shape',['../image_8h.html#a2a779d0c5d66e8119c1347a564192b2c',1,'nda']]] +]; diff --git a/search/all_c.html b/search/all_c.html new file mode 100644 index 00000000..c1ae2cae --- /dev/null +++ b/search/all_c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_c.js b/search/all_c.js new file mode 100644 index 00000000..e44410bf --- /dev/null +++ b/search/all_c.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['range',['range',['../array_8h.html#aaaa66a68a53c7780294f443c9da40fb8',1,'nda::range(index_t begin, index_t end)'],['../array_8h.html#a41e4d24524ff36ed841fa23295347628',1,'nda::range(index_t begin)']]], + ['rank',['rank',['../classnda_1_1shape.html#ae60fb5d209978ccc3054eb2181fb0ec7',1,'nda::shape::rank()'],['../classnda_1_1array__ref.html#ae60fb5d209978ccc3054eb2181fb0ec7',1,'nda::array_ref::rank()'],['../classnda_1_1array.html#ae60fb5d209978ccc3054eb2181fb0ec7',1,'nda::array::rank()']]], + ['ref',['ref',['../classnda_1_1array.html#a7381d7211fb39c8c18f8ed7a82212d1e',1,'nda::array']]], + ['reinterpret',['reinterpret',['../array_8h.html#a94904069da979eb472c385bc6d98ad82',1,'nda']]], + ['reinterpret_5fconst',['reinterpret_const',['../array_8h.html#a11efc76a7f3b6677b9110c33d91e4198',1,'nda']]], + ['reinterpret_5fshape',['reinterpret_shape',['../array_8h.html#afe5286df6ef0b7546aa6eed5642ec3e9',1,'nda']]], + ['reorder',['reorder',['../array_8h.html#ac330ca487f4b29eb13861850de98a38f',1,'nda']]], + ['reshape',['reshape',['../classnda_1_1array.html#a6af03addbc4e320d097a5a3315b0f579',1,'nda::array']]], + ['resolve',['resolve',['../classnda_1_1shape.html#a8472f3f7cc197a1fc281879d13e3e767',1,'nda::shape']]], + ['rows',['rows',['../classnda_1_1shape.html#a930cd5d87507c6f01d1b94eba554ab07',1,'nda::shape::rows()'],['../classnda_1_1array__ref.html#a930cd5d87507c6f01d1b94eba554ab07',1,'nda::array_ref::rows()'],['../classnda_1_1array.html#af1bd18ed0d2b99c1f1dcaac8a827c2ee',1,'nda::array::rows()']]] +]; diff --git a/search/all_d.html b/search/all_d.html new file mode 100644 index 00000000..712223c6 --- /dev/null +++ b/search/all_d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_d.js b/search/all_d.js new file mode 100644 index 00000000..6eaaf22b --- /dev/null +++ b/search/all_d.js @@ -0,0 +1,19 @@ +var searchData= +[ + ['set_5fshape',['set_shape',['../classnda_1_1array__ref.html#ae5c50ce361082d4224ec63235fdbea14',1,'nda::array_ref::set_shape()'],['../classnda_1_1array.html#a3d2d7869d4d7672eac4ec70ec7430313',1,'nda::array::set_shape()']]], + ['shape',['shape',['../classnda_1_1shape.html',1,'nda']]], + ['shape',['shape',['../classnda_1_1shape.html#ad2930f9a3298d7056000f4d2e577216b',1,'nda::shape::shape()'],['../classnda_1_1array__ref.html#ae4afafe235c4b2ee9cbe01eb21ed37c6',1,'nda::array_ref::shape()'],['../classnda_1_1array.html#a801ab858e1e46482c60b289c07470a34',1,'nda::array::shape()']]], + ['shape_5fof_5frank',['shape_of_rank',['../array_8h.html#a61e0c3b2fc19efea03b595a9fbe2ba23',1,'nda']]], + ['shape_5ftraits',['shape_traits',['../classnda_1_1shape__traits.html',1,'nda']]], + ['shape_5ftraits_3c_20chunky_5fimage_5fshape_3c_20channels_20_3e_20_3e',['shape_traits< chunky_image_shape< Channels > >',['../classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_01_4_01_4.html',1,'nda']]], + ['shape_5ftraits_3c_20chunky_5fimage_5fshape_3c_20channels_2c_20xstride_20_3e_20_3e',['shape_traits< chunky_image_shape< Channels, XStride > >',['../classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_00_01_x_stride_01_4_01_4.html',1,'nda']]], + ['shape_5ftraits_3c_20matrix_5fshape_3c_20rows_2c_20cols_20_3e_20_3e',['shape_traits< matrix_shape< Rows, Cols > >',['../classnda_1_1shape__traits_3_01matrix__shape_3_01_rows_00_01_cols_01_4_01_4.html',1,'nda']]], + ['shape_5ftype',['shape_type',['../classnda_1_1array__ref.html#ae3bf5f9e6825d36ce1fd319992cb92e0',1,'nda::array_ref::shape_type()'],['../classnda_1_1array.html#ae3bf5f9e6825d36ce1fd319992cb92e0',1,'nda::array::shape_type()']]], + ['size',['size',['../classnda_1_1shape.html#aadb3dffdda75e22336c27b38443508e3',1,'nda::shape']]], + ['slice_5fchannel',['slice_channel',['../image_8h.html#a37a34c2873107d3752b6a9d8eedaf5c4',1,'nda']]], + ['small_5fmatrix',['small_matrix',['../matrix_8h.html#ae755b11e5aa2d7bb50602095326df77c',1,'nda']]], + ['split',['split',['../array_8h.html#a3d05a3211e2c3a5e86eb63559ae4a7ca',1,'nda::split(const interval< Min, Extent > &v)'],['../array_8h.html#aad010fde354a851daf6ad43533c758ca',1,'nda::split(const interval< Min, Extent > &v, index_t inner_extent)']]], + ['stride',['stride',['../classnda_1_1dim.html#adff752e8489af854a04a1ac0ebdf5701',1,'nda::dim']]], + ['strided_5fdim',['strided_dim',['../array_8h.html#a9025cb1177525c1b8587b589ca647e4e',1,'nda']]], + ['swap',['swap',['../classnda_1_1array.html#aeb1ffc3054bf81f0c41e7e38a2025813',1,'nda::array::swap()'],['../array_8h.html#a842dbbf31ce75db1a54a7b498df53995',1,'nda::swap()']]] +]; diff --git a/search/all_e.html b/search/all_e.html new file mode 100644 index 00000000..d553ffa2 --- /dev/null +++ b/search/all_e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_e.js b/search/all_e.js new file mode 100644 index 00000000..fa3db763 --- /dev/null +++ b/search/all_e.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['transform_5findex',['transform_index',['../array_8h.html#a0a2ce3b0013fef322816a39276cc7f1f',1,'nda']]], + ['transform_5findices',['transform_indices',['../array_8h.html#a53fc9c2c8ebf4e41570bfee8ece7a27b',1,'nda']]], + ['transpose',['transpose',['../array_8h.html#af2e4d426486c09a1a9520aa95975be5a',1,'nda::transpose(const shape< Dims... > &shape)'],['../array_8h.html#ae104ce770dff1fe22fd6d68591be9647',1,'nda::transpose(const array_ref< T, OldShape > &a)']]] +]; diff --git a/search/all_f.html b/search/all_f.html new file mode 100644 index 00000000..c77391a0 --- /dev/null +++ b/search/all_f.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_f.js b/search/all_f.js new file mode 100644 index 00000000..f7d23190 --- /dev/null +++ b/search/all_f.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['uninitialized_5fallocator',['uninitialized_allocator',['../classnda_1_1uninitialized__allocator.html',1,'nda']]], + ['uninitialized_5fauto_5fallocator',['uninitialized_auto_allocator',['../array_8h.html#a574fafc712a9b945bad45a98e95a5bcf',1,'nda']]], + ['uninitialized_5fstd_5fallocator',['uninitialized_std_allocator',['../array_8h.html#a8aaf81b16b0c4bc1c603dbb31f640b23',1,'nda']]], + ['unresolved',['unresolved',['../array_8h.html#a09cbcb2625d5f9587be3b3961bb894fe',1,'nda']]] +]; diff --git a/search/classes_0.html b/search/classes_0.html new file mode 100644 index 00000000..025587a7 --- /dev/null +++ b/search/classes_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_0.js b/search/classes_0.js new file mode 100644 index 00000000..2bbf68db --- /dev/null +++ b/search/classes_0.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['array',['array',['../classnda_1_1array.html',1,'nda']]], + ['array_5fref',['array_ref',['../classnda_1_1array__ref.html',1,'nda']]], + ['auto_5fallocator',['auto_allocator',['../classnda_1_1auto__allocator.html',1,'nda']]] +]; diff --git a/search/classes_1.html b/search/classes_1.html new file mode 100644 index 00000000..86dc4ffe --- /dev/null +++ b/search/classes_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_1.js b/search/classes_1.js new file mode 100644 index 00000000..81cd868b --- /dev/null +++ b/search/classes_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['copy_5fshape_5ftraits',['copy_shape_traits',['../classnda_1_1copy__shape__traits.html',1,'nda']]] +]; diff --git a/search/classes_2.html b/search/classes_2.html new file mode 100644 index 00000000..014caf80 --- /dev/null +++ b/search/classes_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_2.js b/search/classes_2.js new file mode 100644 index 00000000..f6f9a87e --- /dev/null +++ b/search/classes_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['dim',['dim',['../classnda_1_1dim.html',1,'nda']]] +]; diff --git a/search/classes_3.html b/search/classes_3.html new file mode 100644 index 00000000..2e972011 --- /dev/null +++ b/search/classes_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_3.js b/search/classes_3.js new file mode 100644 index 00000000..3e0edf23 --- /dev/null +++ b/search/classes_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['index_5fiterator',['index_iterator',['../classnda_1_1index__iterator.html',1,'nda']]], + ['interval',['interval',['../classnda_1_1interval.html',1,'nda']]] +]; diff --git a/search/classes_4.html b/search/classes_4.html new file mode 100644 index 00000000..776fee37 --- /dev/null +++ b/search/classes_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_4.js b/search/classes_4.js new file mode 100644 index 00000000..271a54bc --- /dev/null +++ b/search/classes_4.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['shape',['shape',['../classnda_1_1shape.html',1,'nda']]], + ['shape_5ftraits',['shape_traits',['../classnda_1_1shape__traits.html',1,'nda']]], + ['shape_5ftraits_3c_20chunky_5fimage_5fshape_3c_20channels_20_3e_20_3e',['shape_traits< chunky_image_shape< Channels > >',['../classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_01_4_01_4.html',1,'nda']]], + ['shape_5ftraits_3c_20chunky_5fimage_5fshape_3c_20channels_2c_20xstride_20_3e_20_3e',['shape_traits< chunky_image_shape< Channels, XStride > >',['../classnda_1_1shape__traits_3_01chunky__image__shape_3_01_channels_00_01_x_stride_01_4_01_4.html',1,'nda']]], + ['shape_5ftraits_3c_20matrix_5fshape_3c_20rows_2c_20cols_20_3e_20_3e',['shape_traits< matrix_shape< Rows, Cols > >',['../classnda_1_1shape__traits_3_01matrix__shape_3_01_rows_00_01_cols_01_4_01_4.html',1,'nda']]] +]; diff --git a/search/classes_5.html b/search/classes_5.html new file mode 100644 index 00000000..69bbcc8b --- /dev/null +++ b/search/classes_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_5.js b/search/classes_5.js new file mode 100644 index 00000000..f609c37e --- /dev/null +++ b/search/classes_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['uninitialized_5fallocator',['uninitialized_allocator',['../classnda_1_1uninitialized__allocator.html',1,'nda']]] +]; diff --git a/search/close.png b/search/close.png new file mode 100644 index 0000000000000000000000000000000000000000..9342d3dfeea7b7c4ee610987e717804b5a42ceb9 GIT binary patch literal 273 zcmV+s0q*{ZP)4(RlMby96)VwnbG{ zbe&}^BDn7x>$<{ck4zAK-=nT;=hHG)kmplIF${xqm8db3oX6wT3bvp`TE@m0cg;b) zBuSL}5?N7O(iZLdAlz@)b)Rd~DnSsSX&P5qC`XwuFwcAYLC+d2>+1(8on;wpt8QIC X2MT$R4iQDd00000NkvXXu0mjfia~GN literal 0 HcmV?d00001 diff --git a/search/files_0.html b/search/files_0.html new file mode 100644 index 00000000..0b637cf9 --- /dev/null +++ b/search/files_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/files_0.js b/search/files_0.js new file mode 100644 index 00000000..974b1b5c --- /dev/null +++ b/search/files_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['array_2eh',['array.h',['../array_8h.html',1,'']]] +]; diff --git a/search/files_1.html b/search/files_1.html new file mode 100644 index 00000000..1094e74a --- /dev/null +++ b/search/files_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/files_1.js b/search/files_1.js new file mode 100644 index 00000000..42a96773 --- /dev/null +++ b/search/files_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['ein_5freduce_2eh',['ein_reduce.h',['../ein__reduce_8h.html',1,'']]] +]; diff --git a/search/files_2.html b/search/files_2.html new file mode 100644 index 00000000..a08dbd36 --- /dev/null +++ b/search/files_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/files_2.js b/search/files_2.js new file mode 100644 index 00000000..a609633d --- /dev/null +++ b/search/files_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['image_2eh',['image.h',['../image_8h.html',1,'']]] +]; diff --git a/search/files_3.html b/search/files_3.html new file mode 100644 index 00000000..647fc8d0 --- /dev/null +++ b/search/files_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/files_3.js b/search/files_3.js new file mode 100644 index 00000000..056038b8 --- /dev/null +++ b/search/files_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['matrix_2eh',['matrix.h',['../matrix_8h.html',1,'']]] +]; diff --git a/search/files_4.html b/search/files_4.html new file mode 100644 index 00000000..186557a6 --- /dev/null +++ b/search/files_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/files_4.js b/search/files_4.js new file mode 100644 index 00000000..23b14b72 --- /dev/null +++ b/search/files_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['z_5forder_2eh',['z_order.h',['../z__order_8h.html',1,'']]] +]; diff --git a/search/functions_0.html b/search/functions_0.html new file mode 100644 index 00000000..6bc52b61 --- /dev/null +++ b/search/functions_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_0.js b/search/functions_0.js new file mode 100644 index 00000000..acb2fe0a --- /dev/null +++ b/search/functions_0.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['array',['array',['../classnda_1_1array.html#a9cbcfcbf0173e1edaf4094bb36b34b31',1,'nda::array::array()'],['../classnda_1_1array.html#ab5192700ae6219b033f6189c9e107acf',1,'nda::array::array(const Shape &shape, const T &value, const Alloc &alloc)'],['../classnda_1_1array.html#a7c078dc760b41e16af85a2adcf20c9bf',1,'nda::array::array(const Shape &shape, const Alloc &alloc)'],['../classnda_1_1array.html#a774ae5d2eea9dc62d6d45605ac0c7b58',1,'nda::array::array(const array &other)'],['../classnda_1_1array.html#aed842c0465cf2a349c98a43d0aea51e2',1,'nda::array::array(const array &other, const Alloc &alloc)'],['../classnda_1_1array.html#af9cb440fd9a7e30b1d53f50ca6339ed7',1,'nda::array::array(array &&other)'],['../classnda_1_1array.html#a5d433dab95a40026beda80a8671b26ef',1,'nda::array::array(array &&other, const Alloc &alloc)']]], + ['array_5fref',['array_ref',['../classnda_1_1array__ref.html#ac5dd1d0ed235a23d1d5658cfb15e00b9',1,'nda::array_ref::array_ref(pointer base=nullptr, const Shape &shape=Shape())'],['../classnda_1_1array__ref.html#a477a69276fcfc5ef0e55851408e4cb9f',1,'nda::array_ref::array_ref(const array_ref &other)=default'],['../classnda_1_1array__ref.html#acf34a5e4381fc949489cd6dddb27cf3c',1,'nda::array_ref::array_ref(const array_ref< T, OtherShape > &other)']]], + ['assign',['assign',['../classnda_1_1array.html#a5653922b5fd47d896f50ecb602cc6f98',1,'nda::array::assign(const array &other)'],['../classnda_1_1array.html#ab5ce5fbdb7855c3c5fbc420401de02c0',1,'nda::array::assign(Shape shape, const T &value)']]] +]; diff --git a/search/functions_1.html b/search/functions_1.html new file mode 100644 index 00000000..648831fd --- /dev/null +++ b/search/functions_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_1.js b/search/functions_1.js new file mode 100644 index 00000000..0c3f5920 --- /dev/null +++ b/search/functions_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['base',['base',['../classnda_1_1array__ref.html#ae10f9e3cb54d90b15a71f790d821e712',1,'nda::array_ref::base()'],['../classnda_1_1array.html#a8ae0eb182e9f3daffda7a2d70fab14f6',1,'nda::array::base()']]], + ['begin',['begin',['../classnda_1_1interval.html#aff27edf947d386512a5a9ac88bb2399e',1,'nda::interval::begin()'],['../array_8h.html#a074fffb7cad44b70b9a5dc0793560dfd',1,'nda::begin()']]] +]; diff --git a/search/functions_2.html b/search/functions_2.html new file mode 100644 index 00000000..c93d0894 --- /dev/null +++ b/search/functions_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_2.js b/search/functions_2.js new file mode 100644 index 00000000..08a4e7e1 --- /dev/null +++ b/search/functions_2.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['cast',['cast',['../ein__reduce_8h.html#a04504a9b60455f3e094c1ef92e0caece',1,'nda']]], + ['clamp',['clamp',['../array_8h.html#a191ec3144f7249e6f2679ce4648e3c67',1,'nda::clamp(index_t x, index_t min, index_t max)'],['../array_8h.html#a14484b48d68ae36f12f40248f78f2b43',1,'nda::clamp(index_t x, const Range &r)']]], + ['clear',['clear',['../classnda_1_1array.html#ac8bb3912a3ce86b15842e79d0b421204',1,'nda::array']]], + ['convert_5fshape',['convert_shape',['../array_8h.html#aa632dc4e183e8b352b3b5fc49740f5e5',1,'nda::convert_shape(const ShapeSrc &src)'],['../array_8h.html#a581151c44eee997515985c82272c882a',1,'nda::convert_shape(const array_ref< T, OldShape > &a)']]], + ['copy',['copy',['../array_8h.html#a01b188d9c649d32dde879e9635553236',1,'nda']]], + ['cref',['cref',['../classnda_1_1array__ref.html#a9b12a5debe0510d43c65b4c0e9ac70f0',1,'nda::array_ref']]], + ['crop',['crop',['../image_8h.html#abb22eefc64b333108c8690a5583c17ef',1,'nda']]], + ['crop_5fimage_5fshape',['crop_image_shape',['../image_8h.html#a91f4d38c179897ea0fc84c3c32199e78',1,'nda']]] +]; diff --git a/search/functions_3.html b/search/functions_3.html new file mode 100644 index 00000000..caa48ea2 --- /dev/null +++ b/search/functions_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_3.js b/search/functions_3.js new file mode 100644 index 00000000..4591c772 --- /dev/null +++ b/search/functions_3.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['data',['data',['../classnda_1_1array__ref.html#ab486420d3dc781972553446917d4b8af',1,'nda::array_ref::data()'],['../classnda_1_1array.html#a36e4d11a00a3572c87bf7e913e9b5ca1',1,'nda::array::data()']]], + ['dim',['dim',['../classnda_1_1dim.html#a686aa62054ac7ca73764fe31194a5ff8',1,'nda::dim::dim(index_t min, index_t extent, index_t stride=DefaultStride)'],['../classnda_1_1dim.html#a2698a997cef9db0fb52c214f5daaa7e7',1,'nda::dim::dim(const dim< CopyMin, CopyExtent, CopyStride > &other)'],['../classnda_1_1shape.html#a719809b7b6ac1f5b7c80345003fb3fed',1,'nda::shape::dim()'],['../classnda_1_1shape.html#a094f7cc42bf8449e5afa9ac3c61dd306',1,'nda::shape::dim(size_t d) const ']]], + ['dims',['dims',['../classnda_1_1shape.html#a0fe377b16e5d8c0ee0d37d8c6ad3ba67',1,'nda::shape']]] +]; diff --git a/search/functions_4.html b/search/functions_4.html new file mode 100644 index 00000000..a9c64adf --- /dev/null +++ b/search/functions_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_4.js b/search/functions_4.js new file mode 100644 index 00000000..9d699df8 --- /dev/null +++ b/search/functions_4.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['ein',['ein',['../ein__reduce_8h.html#a5aa6163421edd4ccbbc3da74c6505e7d',1,'nda::ein(Op op)'],['../ein__reduce_8h.html#a6f688a219c0e3e3505fd362314dfdce8',1,'nda::ein(T &scalar)'],['../ein__reduce_8h.html#acec822fa92f9c968aa1e06618b1ba5f7',1,'nda::ein(T *x, size_t N)'],['../ein__reduce_8h.html#a2c3f1b7ac8f4a0ed403a92dc6e9274d6',1,'nda::ein(T(&x)[N])']]], + ['ein_5freduce',['ein_reduce',['../ein__reduce_8h.html#a9a5162bd8e63b8ca47f92b1db361f187',1,'nda']]], + ['empty',['empty',['../classnda_1_1shape.html#aab43a7928dcecaeab73b980085280fa3',1,'nda::shape']]], + ['end',['end',['../classnda_1_1interval.html#ae939570ab7ef11ef979f480fc9e0a1b1',1,'nda::interval']]], + ['equal',['equal',['../array_8h.html#a000b1575954b4090010bd13bf07582f7',1,'nda']]], + ['extent',['extent',['../classnda_1_1interval.html#a8d67ee86467dd9c72448c873ccd44cd5',1,'nda::interval']]] +]; diff --git a/search/functions_5.html b/search/functions_5.html new file mode 100644 index 00000000..9d135fa0 --- /dev/null +++ b/search/functions_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_5.js b/search/functions_5.js new file mode 100644 index 00000000..64c0184f --- /dev/null +++ b/search/functions_5.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['fill',['fill',['../array_8h.html#a5f24975ef5bc1a5ab2e91297dfede713',1,'nda']]], + ['flat_5fmin',['flat_min',['../classnda_1_1shape.html#aff932e9efe2a5008c18640ce8511cbdf',1,'nda::shape']]], + ['flat_5foffset',['flat_offset',['../classnda_1_1dim.html#a64e5e3f2fb394906c42db9a60905a5d2',1,'nda::dim']]], + ['for_5feach_5fimage_5findex',['for_each_image_index',['../image_8h.html#a091367fadb4a9f2bcc2cce86510b333e',1,'nda']]], + ['for_5feach_5fin_5fz_5forder',['for_each_in_z_order',['../z__order_8h.html#a10f3e8b3c937a0136735ee3c82a0dc0f',1,'nda']]], + ['for_5feach_5findex',['for_each_index',['../classnda_1_1shape__traits.html#ad448f38a01290588e4f8967731898875',1,'nda::shape_traits::for_each_index()'],['../array_8h.html#aeedf4c4fe3a73f56a9f72ea34a2b6dad',1,'nda::for_each_index()']]], + ['for_5feach_5findex_5fin_5forder',['for_each_index_in_order',['../array_8h.html#acf31907f3bad61a417e225e5e135b7df',1,'nda']]], + ['for_5feach_5fmatrix_5findex',['for_each_matrix_index',['../matrix_8h.html#af063b25124f0dc1ceaf9bfe1918d426e',1,'nda']]], + ['for_5feach_5fvalue',['for_each_value',['../classnda_1_1shape__traits.html#a9e28d6fd81c177065f94b14e84f94151',1,'nda::shape_traits::for_each_value()'],['../classnda_1_1copy__shape__traits.html#a77faeb731a53f5f224253b680ff88336',1,'nda::copy_shape_traits::for_each_value()'],['../classnda_1_1array__ref.html#a64cfed71aabfac7d25e6d8f6a4ee8fe2',1,'nda::array_ref::for_each_value()'],['../classnda_1_1array.html#a73569de89267bd0df19702b44aadb849',1,'nda::array::for_each_value()']]], + ['for_5feach_5fvalue_5fin_5forder',['for_each_value_in_order',['../array_8h.html#a926d23314527bd0010642a211ed7b146',1,'nda']]] +]; diff --git a/search/functions_6.html b/search/functions_6.html new file mode 100644 index 00000000..5fca897b --- /dev/null +++ b/search/functions_6.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_6.js b/search/functions_6.js new file mode 100644 index 00000000..d0c02f38 --- /dev/null +++ b/search/functions_6.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['generate',['generate',['../array_8h.html#a097abdcd257c2c969ab07162957f2f88',1,'nda']]], + ['get_5fallocator',['get_allocator',['../classnda_1_1array.html#a085cd7aaff57eee6b414cd8e8e8bf0ad',1,'nda::array']]] +]; diff --git a/search/functions_7.html b/search/functions_7.html new file mode 100644 index 00000000..02631a34 --- /dev/null +++ b/search/functions_7.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_7.js b/search/functions_7.js new file mode 100644 index 00000000..bbb906b3 --- /dev/null +++ b/search/functions_7.js @@ -0,0 +1,14 @@ +var searchData= +[ + ['i',['i',['../classnda_1_1shape.html#a504d6bc3b1206cfdea4ede9129e9caee',1,'nda::shape::i()'],['../classnda_1_1array__ref.html#a504d6bc3b1206cfdea4ede9129e9caee',1,'nda::array_ref::i()'],['../classnda_1_1array.html#a2770acc12189beee7859043d88439d51',1,'nda::array::i()']]], + ['index_5fiterator',['index_iterator',['../classnda_1_1index__iterator.html#a62df1f8cbacb16c289873af363c67f7f',1,'nda::index_iterator']]], + ['interval',['interval',['../classnda_1_1interval.html#a4dee77951e705492364157324fd8d412',1,'nda::interval::interval(index_t min, index_t extent)'],['../classnda_1_1interval.html#aff8471c16c498902142cff7bcd07425c',1,'nda::interval::interval(const interval< CopyMin, CopyExtent > &other)']]], + ['is_5fcompact',['is_compact',['../classnda_1_1shape.html#abd45f97dc64adf81fe521d5433646a14',1,'nda::shape']]], + ['is_5fcompatible',['is_compatible',['../array_8h.html#ac68a87c9486d77bb1c2c8bc8f3587290',1,'nda']]], + ['is_5fexplicitly_5fcompatible',['is_explicitly_compatible',['../array_8h.html#aef30cae2d67c4103d15cfbcfff0f349a',1,'nda']]], + ['is_5fin_5frange',['is_in_range',['../classnda_1_1interval.html#acd5fea1c30fe8fcb65f11afd864be619',1,'nda::interval::is_in_range(index_t at) const '],['../classnda_1_1interval.html#a62124bc4a9f1d56d964af2f2b69933da',1,'nda::interval::is_in_range(const interval< OtherMin, OtherExtent > &at) const '],['../classnda_1_1shape.html#a4a4bb5bc425aec205499251ad4254152',1,'nda::shape::is_in_range()']]], + ['is_5fone_5fto_5fone',['is_one_to_one',['../classnda_1_1shape.html#a0438eea3c7137c00a30a62175798bff2',1,'nda::shape']]], + ['is_5fresolved',['is_resolved',['../classnda_1_1shape.html#a26d0a400bf6c6fc454b241f9bf22cf4f',1,'nda::shape']]], + ['is_5fscalar',['is_scalar',['../classnda_1_1shape.html#a861fe2369858d96f8d9eb67318b89e89',1,'nda::shape::is_scalar()'],['../classnda_1_1array__ref.html#a861fe2369858d96f8d9eb67318b89e89',1,'nda::array_ref::is_scalar()'],['../classnda_1_1array.html#a861fe2369858d96f8d9eb67318b89e89',1,'nda::array::is_scalar()']]], + ['is_5fsubset_5fof',['is_subset_of',['../classnda_1_1shape.html#aa6eabf385d230a7322100376dad699ec',1,'nda::shape']]] +]; diff --git a/search/functions_8.html b/search/functions_8.html new file mode 100644 index 00000000..ff370959 --- /dev/null +++ b/search/functions_8.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_8.js b/search/functions_8.js new file mode 100644 index 00000000..e2f66d0b --- /dev/null +++ b/search/functions_8.js @@ -0,0 +1,17 @@ +var searchData= +[ + ['make_5farray',['make_array',['../array_8h.html#a7b4a05d3f1a2fe00507e35bc10c516dd',1,'nda']]], + ['make_5farray_5fref',['make_array_ref',['../array_8h.html#a1ce93c483b477a4339650673058b60ba',1,'nda']]], + ['make_5fcompact',['make_compact',['../array_8h.html#ab5aeff46be2236fb32a203dfd2c0f6fe',1,'nda']]], + ['make_5fcompact_5fcopy',['make_compact_copy',['../array_8h.html#aac7f1b977c6d8977a608e96331cb44fd',1,'nda']]], + ['make_5fcompact_5fmove',['make_compact_move',['../array_8h.html#a4f444a4f82c3bdb70ba8aac5cdebe641',1,'nda']]], + ['make_5fcopy',['make_copy',['../array_8h.html#a7c58e26230741655aa32a915844758b5',1,'nda::make_copy(const array_ref< T, ShapeSrc > &src, const Alloc &alloc=Alloc())'],['../array_8h.html#a9c7d8cbb1a7ea679f9b0bba99d3d3150',1,'nda::make_copy(const array_ref< T, ShapeSrc > &src, const ShapeDst &shape, const Alloc &alloc=Alloc())']]], + ['make_5fein_5freduce_5fshape',['make_ein_reduce_shape',['../ein__reduce_8h.html#a7689fd5b57271dccb3d2d89f6c82d7c3',1,'nda']]], + ['make_5fein_5fsum',['make_ein_sum',['../ein__reduce_8h.html#af05e87f38452d1e7015eec619dcfb502',1,'nda']]], + ['make_5fmove',['make_move',['../array_8h.html#ae489781dfd7c05851bcc3bb770c25cb5',1,'nda']]], + ['make_5fshape',['make_shape',['../array_8h.html#acc77f5082e94f21c95849a1eefd016c3',1,'nda']]], + ['max',['max',['../classnda_1_1interval.html#a32c3f5335a9e4a6577da22ab6265d5ec',1,'nda::interval']]], + ['min',['min',['../classnda_1_1interval.html#acd9e0f9afe70a779088830a1aadf1868',1,'nda::interval::min()'],['../ein__reduce_8h.html#adbf4a1e9bc0aad43e7db974ef620d10d',1,'nda::min()']]], + ['move',['move',['../array_8h.html#aa94eb16dc22298d492152075dc8b3825',1,'nda']]], + ['move_5freinterpret_5fshape',['move_reinterpret_shape',['../array_8h.html#ab424a858ee8c8c675cd05db0e969cbb7',1,'nda']]] +]; diff --git a/search/functions_9.html b/search/functions_9.html new file mode 100644 index 00000000..1d345831 --- /dev/null +++ b/search/functions_9.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_9.js b/search/functions_9.js new file mode 100644 index 00000000..11a2e9ad --- /dev/null +++ b/search/functions_9.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['operator_20reference',['operator reference',['../classnda_1_1array__ref.html#a9da40a48bba2a09ee038aa9b2167c4d1',1,'nda::array_ref::operator reference()'],['../classnda_1_1array.html#a6d78072c3bbceeba3af7e7397f9b32e7',1,'nda::array::operator reference()']]], + ['operator_21_3d',['operator!=',['../classnda_1_1array__ref.html#aaf8d591fa163c447614f3fb32c039ba1',1,'nda::array_ref::operator!=()'],['../classnda_1_1array.html#a638f083b28e54c375647ce4b2d26a319',1,'nda::array::operator!=()']]], + ['operator_2a',['operator*',['../classnda_1_1index__iterator.html#abdd857d441092df709d943bd31e99950',1,'nda::index_iterator']]], + ['operator_3d',['operator=',['../classnda_1_1array.html#a45cd313b8ae4725bd46434747d77ba6d',1,'nda::array::operator=(const array &other)'],['../classnda_1_1array.html#ab4f4887bc4b87814a48bce11d846078c',1,'nda::array::operator=(array &&other)']]], + ['operator_3d_3d',['operator==',['../classnda_1_1interval.html#a9e386dd63e96d87ce8e0ee90b5bd4d8b',1,'nda::interval::operator==()'],['../classnda_1_1dim.html#afa804a735c8490decbfc233b1622c092',1,'nda::dim::operator==()'],['../classnda_1_1shape.html#a9c855e64a8a1336ffc7f704aa8101e31',1,'nda::shape::operator==()']]], + ['operator_5b_5d',['operator[]',['../classnda_1_1shape.html#a2e1352209053b18d9abbd7174b940d44',1,'nda::shape::operator[](const index_type &indices) const '],['../classnda_1_1shape.html#ae12935485bf90173a7a6c244b4a9c6fc',1,'nda::shape::operator[](const std::tuple< Args... > &args) const '],['../classnda_1_1array__ref.html#a9caca6ef754e57ec518aa27710f18ae2',1,'nda::array_ref::operator[](const index_type &indices) const '],['../classnda_1_1array__ref.html#ae12935485bf90173a7a6c244b4a9c6fc',1,'nda::array_ref::operator[](const std::tuple< Args... > &args) const '],['../classnda_1_1array.html#ae0d227928b333d03dcaa54bbc1baaec5',1,'nda::array::operator[](const index_type &indices)'],['../classnda_1_1array.html#a62832cea95b599bc923e67bad4e5f15e',1,'nda::array::operator[](const std::tuple< Args... > &args)']]] +]; diff --git a/search/functions_a.html b/search/functions_a.html new file mode 100644 index 00000000..8eb5e562 --- /dev/null +++ b/search/functions_a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_a.js b/search/functions_a.js new file mode 100644 index 00000000..e44410bf --- /dev/null +++ b/search/functions_a.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['range',['range',['../array_8h.html#aaaa66a68a53c7780294f443c9da40fb8',1,'nda::range(index_t begin, index_t end)'],['../array_8h.html#a41e4d24524ff36ed841fa23295347628',1,'nda::range(index_t begin)']]], + ['rank',['rank',['../classnda_1_1shape.html#ae60fb5d209978ccc3054eb2181fb0ec7',1,'nda::shape::rank()'],['../classnda_1_1array__ref.html#ae60fb5d209978ccc3054eb2181fb0ec7',1,'nda::array_ref::rank()'],['../classnda_1_1array.html#ae60fb5d209978ccc3054eb2181fb0ec7',1,'nda::array::rank()']]], + ['ref',['ref',['../classnda_1_1array.html#a7381d7211fb39c8c18f8ed7a82212d1e',1,'nda::array']]], + ['reinterpret',['reinterpret',['../array_8h.html#a94904069da979eb472c385bc6d98ad82',1,'nda']]], + ['reinterpret_5fconst',['reinterpret_const',['../array_8h.html#a11efc76a7f3b6677b9110c33d91e4198',1,'nda']]], + ['reinterpret_5fshape',['reinterpret_shape',['../array_8h.html#afe5286df6ef0b7546aa6eed5642ec3e9',1,'nda']]], + ['reorder',['reorder',['../array_8h.html#ac330ca487f4b29eb13861850de98a38f',1,'nda']]], + ['reshape',['reshape',['../classnda_1_1array.html#a6af03addbc4e320d097a5a3315b0f579',1,'nda::array']]], + ['resolve',['resolve',['../classnda_1_1shape.html#a8472f3f7cc197a1fc281879d13e3e767',1,'nda::shape']]], + ['rows',['rows',['../classnda_1_1shape.html#a930cd5d87507c6f01d1b94eba554ab07',1,'nda::shape::rows()'],['../classnda_1_1array__ref.html#a930cd5d87507c6f01d1b94eba554ab07',1,'nda::array_ref::rows()'],['../classnda_1_1array.html#af1bd18ed0d2b99c1f1dcaac8a827c2ee',1,'nda::array::rows()']]] +]; diff --git a/search/functions_b.html b/search/functions_b.html new file mode 100644 index 00000000..fa9cff56 --- /dev/null +++ b/search/functions_b.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_b.js b/search/functions_b.js new file mode 100644 index 00000000..90a58aae --- /dev/null +++ b/search/functions_b.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['set_5fshape',['set_shape',['../classnda_1_1array__ref.html#ae5c50ce361082d4224ec63235fdbea14',1,'nda::array_ref::set_shape()'],['../classnda_1_1array.html#a3d2d7869d4d7672eac4ec70ec7430313',1,'nda::array::set_shape()']]], + ['shape',['shape',['../classnda_1_1shape.html#ad2930f9a3298d7056000f4d2e577216b',1,'nda::shape::shape()'],['../classnda_1_1array__ref.html#ae4afafe235c4b2ee9cbe01eb21ed37c6',1,'nda::array_ref::shape()'],['../classnda_1_1array.html#a801ab858e1e46482c60b289c07470a34',1,'nda::array::shape()']]], + ['size',['size',['../classnda_1_1shape.html#aadb3dffdda75e22336c27b38443508e3',1,'nda::shape']]], + ['slice_5fchannel',['slice_channel',['../image_8h.html#a37a34c2873107d3752b6a9d8eedaf5c4',1,'nda']]], + ['split',['split',['../array_8h.html#a3d05a3211e2c3a5e86eb63559ae4a7ca',1,'nda::split(const interval< Min, Extent > &v)'],['../array_8h.html#aad010fde354a851daf6ad43533c758ca',1,'nda::split(const interval< Min, Extent > &v, index_t inner_extent)']]], + ['stride',['stride',['../classnda_1_1dim.html#adff752e8489af854a04a1ac0ebdf5701',1,'nda::dim']]], + ['swap',['swap',['../classnda_1_1array.html#aeb1ffc3054bf81f0c41e7e38a2025813',1,'nda::array::swap()'],['../array_8h.html#a842dbbf31ce75db1a54a7b498df53995',1,'nda::swap()']]] +]; diff --git a/search/functions_c.html b/search/functions_c.html new file mode 100644 index 00000000..fce7a6b1 --- /dev/null +++ b/search/functions_c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_c.js b/search/functions_c.js new file mode 100644 index 00000000..fa3db763 --- /dev/null +++ b/search/functions_c.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['transform_5findex',['transform_index',['../array_8h.html#a0a2ce3b0013fef322816a39276cc7f1f',1,'nda']]], + ['transform_5findices',['transform_indices',['../array_8h.html#a53fc9c2c8ebf4e41570bfee8ece7a27b',1,'nda']]], + ['transpose',['transpose',['../array_8h.html#af2e4d426486c09a1a9520aa95975be5a',1,'nda::transpose(const shape< Dims... > &shape)'],['../array_8h.html#ae104ce770dff1fe22fd6d68591be9647',1,'nda::transpose(const array_ref< T, OldShape > &a)']]] +]; diff --git a/search/functions_d.html b/search/functions_d.html new file mode 100644 index 00000000..82b2b0cf --- /dev/null +++ b/search/functions_d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_d.js b/search/functions_d.js new file mode 100644 index 00000000..073ae147 --- /dev/null +++ b/search/functions_d.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['width',['width',['../classnda_1_1shape.html#a4a8968cace8d3331f70c8cb1a7be4185',1,'nda::shape::width()'],['../classnda_1_1array__ref.html#a4a8968cace8d3331f70c8cb1a7be4185',1,'nda::array_ref::width()'],['../classnda_1_1array.html#aba1ae59e8ea89231b67e008dc4b03d07',1,'nda::array::width()']]] +]; diff --git a/search/functions_e.html b/search/functions_e.html new file mode 100644 index 00000000..557ae9a4 --- /dev/null +++ b/search/functions_e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_e.js b/search/functions_e.js new file mode 100644 index 00000000..11d9d1b2 --- /dev/null +++ b/search/functions_e.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['x',['x',['../classnda_1_1shape.html#ac58f67021d52c625bb34bcd10e7dba57',1,'nda::shape::x()'],['../classnda_1_1array__ref.html#ac58f67021d52c625bb34bcd10e7dba57',1,'nda::array_ref::x()'],['../classnda_1_1array.html#adedb30a4a8d84863378e80cc522313a5',1,'nda::array::x()']]] +]; diff --git a/search/mag_sel.png b/search/mag_sel.png new file mode 100644 index 0000000000000000000000000000000000000000..81f6040a2092402b4d98f9ffa8855d12a0d4ca17 GIT binary patch literal 563 zcmV-30?hr1P)zxx&tqG15pu7)IiiXFflOc2k;dXd>%13GZAy? zRz!q0=|E6a6vV)&ZBS~G9oe0kbqyw1*gvY`{Pop2oKq#FlzgXt@Xh-7fxh>}`Fxg> z$%N%{$!4=5nM{(;=c!aG1Ofr^Do{u%Ih{^&Fc@H2)+a-?TBXrw5DW&z%Nb6mQ!L9O zl}b@6mB?f=tX3;#vl)}ggh(Vpyh(IK z(Mb0D{l{U$FsRjP;!{($+bsaaVi8T#1c0V#qEIOCYa9@UVLV`f__E81L;?WEaRA;Y zUH;rZ;vb;mk7JX|$=i3O~&If0O@oZfLg8gfIjW=dcBsz;gI=!{-r4# z4%6v$&~;q^j7Fo67yJ(NJWuX+I~I!tj^nW3?}^9bq|<3^+vapS5sgM^x7!cs(+mMT z&y%j};&~po+YO)3hoUH4E*E;e9>?R6SS&`X)p`njycAVcg{rEb41T{~Hk(bl-7eSb zmFxA2uIqo#@R?lKm50ND`~6Nfn|-b1|L6O98vt3Tx@gKz#isxO002ovPDHLkV1kyW B_l^Jn literal 0 HcmV?d00001 diff --git a/search/nomatches.html b/search/nomatches.html new file mode 100644 index 00000000..b1ded27e --- /dev/null +++ b/search/nomatches.html @@ -0,0 +1,12 @@ + + + + + + + +
+
No Matches
+
+ + diff --git a/search/pages_0.html b/search/pages_0.html new file mode 100644 index 00000000..0db7267b --- /dev/null +++ b/search/pages_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/pages_0.js b/search/pages_0.js new file mode 100644 index 00000000..82086061 --- /dev/null +++ b/search/pages_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['about',['About',['../index.html',1,'']]] +]; diff --git a/search/pages_1.html b/search/pages_1.html new file mode 100644 index 00000000..2c67a8ef --- /dev/null +++ b/search/pages_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/pages_1.js b/search/pages_1.js new file mode 100644 index 00000000..74895784 --- /dev/null +++ b/search/pages_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['how_20to_20contribute',['How to Contribute',['../md_CONTRIBUTING.html',1,'']]] +]; diff --git a/search/search.css b/search/search.css new file mode 100644 index 00000000..4d7612ff --- /dev/null +++ b/search/search.css @@ -0,0 +1,271 @@ +/*---------------- Search Box */ + +#FSearchBox { + float: left; +} + +#MSearchBox { + white-space : nowrap; + position: absolute; + float: none; + display: inline; + margin-top: 8px; + right: 0px; + width: 170px; + z-index: 102; + background-color: white; +} + +#MSearchBox .left +{ + display:block; + position:absolute; + left:10px; + width:20px; + height:19px; + background:url('search_l.png') no-repeat; + background-position:right; +} + +#MSearchSelect { + display:block; + position:absolute; + width:20px; + height:19px; +} + +.left #MSearchSelect { + left:4px; +} + +.right #MSearchSelect { + right:5px; +} + +#MSearchField { + display:block; + position:absolute; + height:19px; + background:url('search_m.png') repeat-x; + border:none; + width:111px; + margin-left:20px; + padding-left:4px; + color: #909090; + outline: none; + font: 9pt Arial, Verdana, sans-serif; +} + +#FSearchBox #MSearchField { + margin-left:15px; +} + +#MSearchBox .right { + display:block; + position:absolute; + right:10px; + top:0px; + width:20px; + height:19px; + background:url('search_r.png') no-repeat; + background-position:left; +} + +#MSearchClose { + display: none; + position: absolute; + top: 4px; + background : none; + border: none; + margin: 0px 4px 0px 0px; + padding: 0px 0px; + outline: none; +} + +.left #MSearchClose { + left: 6px; +} + +.right #MSearchClose { + right: 2px; +} + +.MSearchBoxActive #MSearchField { + color: #000000; +} + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #90A5CE; + background-color: #F9FAFC; + z-index: 1; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt Arial, Verdana, sans-serif; + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: monospace; + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: #000000; + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: #000000; + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: #FFFFFF; + background-color: #3D578C; + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + width: 60ex; + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #000; + background-color: #EEF1F7; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; + padding-bottom: 15px; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +body.SRPage { + margin: 5px 2px; +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; +} + +.SRResult { + display: none; +} + +DIV.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.searchresult { + background-color: #F0F3F8; +} + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: url("../tab_a.png"); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/search/search.js b/search/search.js new file mode 100644 index 00000000..dedce3bf --- /dev/null +++ b/search/search.js @@ -0,0 +1,791 @@ +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair + { + idxChar = searchValue.substr(0, 2); + } + + var resultsPage; + var resultsPageWithSearch; + var hasResultsPage; + + var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); + if (idx!=-1) + { + var hexCode=idx.toString(16); + resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else // nothing available for this search term + { + resultsPage = this.resultsPath + '/nomatches.html'; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + } + + window.frames.MSearchResults.location = resultsPageWithSearch; + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + + if (domPopupSearchResultsWindow.style.display!='block') + { + var domSearchBox = this.DOMSearchBox(); + this.DOMSearchClose().style.display = 'inline'; + if (this.insideFrame) + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + domPopupSearchResultsWindow.style.position = 'relative'; + domPopupSearchResultsWindow.style.display = 'block'; + var width = document.body.clientWidth - 8; // the -8 is for IE :-( + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResults.style.width = width + 'px'; + } + else + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; + var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + } + } + + this.lastSearchValue = searchValue; + this.lastResultsPage = resultsPage; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + + var searchField = this.DOMSearchField(); + + if (searchField.value == this.searchLabel) // clear "Search" term upon entry + { + searchField.value = ''; + this.searchActive = true; + } + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.DOMSearchField().value = this.searchLabel; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName == 'DIV' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName == 'DIV' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + parent.document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults() +{ + var results = document.getElementById("SRResults"); + for (var e=0; ek7RCwB~R6VQOP#AvB$vH7i{6H{96zot$7cZT<7246EF5Np6N}+$IbiG6W zg#87A+NFaX+=_^xM1#gCtshC=E{%9^uQX_%?YwXvo{#q&MnpJ8uh(O?ZRc&~_1%^SsPxG@rfElJg-?U zm!Cz-IOn(qJP3kDp-^~qt+FGbl=5jNli^Wj_xIBG{Rc0en{!oFvyoNC7{V~T8}b>| z=jL2WIReZzX(YN(_9fV;BBD$VXQIxNasAL8ATvEu822WQ%mvv4FO#qs` BFGc_W literal 0 HcmV?d00001 diff --git a/search/search_r.png b/search/search_r.png new file mode 100644 index 0000000000000000000000000000000000000000..97ee8b439687084201b79c6f776a41f495c6392a GIT binary patch literal 612 zcmV-q0-ODbP)PbXFRCwB?)W514K@j&X?z2*SxFI6-@HT2E2K=9X9%Pb zEK*!TBw&g(DMC;|A)uGlRkOS9vd-?zNs%bR4d$w+ox_iFnE8fvIvv7^5<(>Te12Li z7C)9srCzmK{ZcNM{YIl9j{DePFgOWiS%xG@5CnnnJa4nvY<^glbz7^|-ZY!dUkAwd z{gaTC@_>b5h~;ug#R0wRL0>o5!hxm*s0VW?8dr}O#zXTRTnrQm_Z7z1Mrnx>&p zD4qifUjzLvbVVWi?l?rUzwt^sdb~d!f_LEhsRVIXZtQ=qSxuxqm zEX#tf>$?M_Y1-LSDT)HqG?`%-%ZpY!#{N!rcNIiL;G7F0`l?)mNGTD9;f9F5Up3Kg zw}a<-JylhG&;=!>B+fZaCX+?C+kHYrP%c?X2!Zu_olK|GcS4A70HEy;vn)I0>0kLH z`jc(WIaaHc7!HS@f*^R^Znx8W=_jIl2oWJoQ*h1^$FX!>*PqR1J8k|fw}w_y}TpE>7m8DqDO<3z`OzXt$ccSejbEZCg@0000 + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/typedefs_0.js b/search/typedefs_0.js new file mode 100644 index 00000000..24c6a07e --- /dev/null +++ b/search/typedefs_0.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['allocator_5ftype',['allocator_type',['../classnda_1_1array.html#a85263a9e2d1f4da2cde00205ca6f8d08',1,'nda::array']]], + ['array_5fof_5frank',['array_of_rank',['../array_8h.html#aec3848811e2aae330fb669a23f30cd2e',1,'nda']]], + ['array_5fref_5fof_5frank',['array_ref_of_rank',['../array_8h.html#a4edeffa5f4878abb67a08b3eccdc9d2a',1,'nda']]] +]; diff --git a/search/typedefs_1.html b/search/typedefs_1.html new file mode 100644 index 00000000..6edac96b --- /dev/null +++ b/search/typedefs_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/typedefs_1.js b/search/typedefs_1.js new file mode 100644 index 00000000..3619373e --- /dev/null +++ b/search/typedefs_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['broadcast_5fdim',['broadcast_dim',['../array_8h.html#a1c13f3faa99c074549d5f2265cc7ba1d',1,'nda']]] +]; diff --git a/search/typedefs_2.html b/search/typedefs_2.html new file mode 100644 index 00000000..cc5cc404 --- /dev/null +++ b/search/typedefs_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/typedefs_2.js b/search/typedefs_2.js new file mode 100644 index 00000000..cca7fe0f --- /dev/null +++ b/search/typedefs_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['chunky_5fimage_5fshape',['chunky_image_shape',['../image_8h.html#a249fdb84b708f002090a88bff2f24bc2',1,'nda']]] +]; diff --git a/search/typedefs_3.html b/search/typedefs_3.html new file mode 100644 index 00000000..3fdb8f26 --- /dev/null +++ b/search/typedefs_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/typedefs_3.js b/search/typedefs_3.js new file mode 100644 index 00000000..db13b431 --- /dev/null +++ b/search/typedefs_3.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['dense_5farray',['dense_array',['../array_8h.html#a6fd5dd48fcb68ce48daff5d746cb297c',1,'nda']]], + ['dense_5farray_5fref',['dense_array_ref',['../array_8h.html#a3bbaedd9bb2f66c68d0dbc60fefafde1',1,'nda']]], + ['dense_5fdim',['dense_dim',['../array_8h.html#a00c87b9adb5a4f4ad386e78145eabc2f',1,'nda']]], + ['dense_5fshape',['dense_shape',['../array_8h.html#aa200a0a9e702ec0241adb18f351acbe2',1,'nda']]], + ['dims_5ftype',['dims_type',['../classnda_1_1shape.html#af0388cf8747db7b5851f2588d234aa04',1,'nda::shape']]] +]; diff --git a/search/typedefs_4.html b/search/typedefs_4.html new file mode 100644 index 00000000..fb508194 --- /dev/null +++ b/search/typedefs_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/typedefs_4.js b/search/typedefs_4.js new file mode 100644 index 00000000..e013cb1e --- /dev/null +++ b/search/typedefs_4.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['fixed_5fdense_5fshape',['fixed_dense_shape',['../array_8h.html#ac7b935efb37c2765a3aae7b2ecaeec26',1,'nda']]], + ['fixed_5fdim',['fixed_dim',['../array_8h.html#adb0209166945d62a1629fc11e434ac98',1,'nda']]], + ['fixed_5finterval',['fixed_interval',['../array_8h.html#a211cabf0fcc1a09e896e0af76704dd6f',1,'nda']]] +]; diff --git a/search/typedefs_5.html b/search/typedefs_5.html new file mode 100644 index 00000000..0ad02a6c --- /dev/null +++ b/search/typedefs_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/typedefs_5.js b/search/typedefs_5.js new file mode 100644 index 00000000..57c5deda --- /dev/null +++ b/search/typedefs_5.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['image_5fshape',['image_shape',['../image_8h.html#ab16c89cd2b804f25799ddaac21799b74',1,'nda']]], + ['index_5fof_5frank',['index_of_rank',['../array_8h.html#ad7866b82526d5276e559a3bc02e09686',1,'nda']]], + ['index_5ft',['index_t',['../array_8h.html#a26493ae85adc5b160363a05a6cd4f11e',1,'nda']]], + ['index_5ftype',['index_type',['../classnda_1_1shape.html#a97955e667dea657b46e7a1c6dc8662b0',1,'nda::shape']]] +]; diff --git a/search/typedefs_6.html b/search/typedefs_6.html new file mode 100644 index 00000000..10007d2c --- /dev/null +++ b/search/typedefs_6.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/typedefs_6.js b/search/typedefs_6.js new file mode 100644 index 00000000..a6411798 --- /dev/null +++ b/search/typedefs_6.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['matrix',['matrix',['../matrix_8h.html#a6d932cdaa3dec58da49d4421dcc1f120',1,'nda']]], + ['matrix_5fshape',['matrix_shape',['../matrix_8h.html#aaa130e57b659bcdf77735b38445aa975',1,'nda']]] +]; diff --git a/search/typedefs_7.html b/search/typedefs_7.html new file mode 100644 index 00000000..4e61d873 --- /dev/null +++ b/search/typedefs_7.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/typedefs_7.js b/search/typedefs_7.js new file mode 100644 index 00000000..d19a3257 --- /dev/null +++ b/search/typedefs_7.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['planar_5fimage_5fshape',['planar_image_shape',['../image_8h.html#a2a779d0c5d66e8119c1347a564192b2c',1,'nda']]] +]; diff --git a/search/typedefs_8.html b/search/typedefs_8.html new file mode 100644 index 00000000..4d3d6b60 --- /dev/null +++ b/search/typedefs_8.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/typedefs_8.js b/search/typedefs_8.js new file mode 100644 index 00000000..4019b7b9 --- /dev/null +++ b/search/typedefs_8.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['shape_5fof_5frank',['shape_of_rank',['../array_8h.html#a61e0c3b2fc19efea03b595a9fbe2ba23',1,'nda']]], + ['shape_5ftype',['shape_type',['../classnda_1_1array__ref.html#ae3bf5f9e6825d36ce1fd319992cb92e0',1,'nda::array_ref::shape_type()'],['../classnda_1_1array.html#ae3bf5f9e6825d36ce1fd319992cb92e0',1,'nda::array::shape_type()']]], + ['small_5fmatrix',['small_matrix',['../matrix_8h.html#ae755b11e5aa2d7bb50602095326df77c',1,'nda']]], + ['strided_5fdim',['strided_dim',['../array_8h.html#a9025cb1177525c1b8587b589ca647e4e',1,'nda']]] +]; diff --git a/search/typedefs_9.html b/search/typedefs_9.html new file mode 100644 index 00000000..8dbf62fd --- /dev/null +++ b/search/typedefs_9.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/typedefs_9.js b/search/typedefs_9.js new file mode 100644 index 00000000..e337ebe0 --- /dev/null +++ b/search/typedefs_9.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['uninitialized_5fauto_5fallocator',['uninitialized_auto_allocator',['../array_8h.html#a574fafc712a9b945bad45a98e95a5bcf',1,'nda']]], + ['uninitialized_5fstd_5fallocator',['uninitialized_std_allocator',['../array_8h.html#a8aaf81b16b0c4bc1c603dbb31f640b23',1,'nda']]] +]; diff --git a/search/typedefs_a.html b/search/typedefs_a.html new file mode 100644 index 00000000..411981ef --- /dev/null +++ b/search/typedefs_a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/typedefs_a.js b/search/typedefs_a.js new file mode 100644 index 00000000..8b623446 --- /dev/null +++ b/search/typedefs_a.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['value_5ftype',['value_type',['../classnda_1_1array__ref.html#afb9ded5f49336ae503bb9f2035ea902b',1,'nda::array_ref::value_type()'],['../classnda_1_1array.html#afb9ded5f49336ae503bb9f2035ea902b',1,'nda::array::value_type()']]], + ['vector_5fshape',['vector_shape',['../matrix_8h.html#a19ca079501513b056a3819a8a1d71904',1,'nda']]] +]; diff --git a/search/variables_0.html b/search/variables_0.html new file mode 100644 index 00000000..3835278f --- /dev/null +++ b/search/variables_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/variables_0.js b/search/variables_0.js new file mode 100644 index 00000000..ef10ee54 --- /dev/null +++ b/search/variables_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['all',['all',['../array_8h.html#ac1b8df81276b556535053bc15e7da68c',1,'nda']]] +]; diff --git a/search/variables_1.html b/search/variables_1.html new file mode 100644 index 00000000..3c65cf26 --- /dev/null +++ b/search/variables_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/variables_1.js b/search/variables_1.js new file mode 100644 index 00000000..cbaca319 --- /dev/null +++ b/search/variables_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['dynamic',['dynamic',['../array_8h.html#adab240e3956fad6af13ebafd594e007b',1,'nda']]] +]; diff --git a/search/variables_2.html b/search/variables_2.html new file mode 100644 index 00000000..7b43e0ac --- /dev/null +++ b/search/variables_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/variables_2.js b/search/variables_2.js new file mode 100644 index 00000000..4d3a8b6d --- /dev/null +++ b/search/variables_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['unresolved',['unresolved',['../array_8h.html#a09cbcb2625d5f9587be3b3961bb894fe',1,'nda']]] +]; diff --git a/splitbar.png b/splitbar.png new file mode 100644 index 0000000000000000000000000000000000000000..fe895f2c58179b471a22d8320b39a4bd7312ec8e GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^Yzz!63>-{AmhX=Jf(#6djGiuzAr*{o?=JLmPLyc> z_*`QK&+BH@jWrYJ7>r6%keRM@)Qyv8R=enp0jiI>aWlGyB58O zFVR20d+y`K7vDw(hJF3;>dD*3-?v=<8M)@x|EEGLnJsniYK!2U1 Y!`|5biEc?d1`HDhPgg&ebxsLQ02F6;9RL6T literal 0 HcmV?d00001 diff --git a/sync_off.png b/sync_off.png new file mode 100644 index 0000000000000000000000000000000000000000..3b443fc62892114406e3d399421b2a881b897acc GIT binary patch literal 853 zcmV-b1FHOqP)oT|#XixUYy%lpuf3i8{fX!o zUyDD0jOrAiT^tq>fLSOOABs-#u{dV^F$b{L9&!2=9&RmV;;8s^x&UqB$PCj4FdKbh zoB1WTskPUPu05XzFbA}=KZ-GP1fPpAfSs>6AHb12UlR%-i&uOlTpFNS7{jm@mkU1V zh`nrXr~+^lsV-s1dkZOaI|kYyVj3WBpPCY{n~yd%u%e+d=f%`N0FItMPtdgBb@py; zq@v6NVArhyTC7)ULw-Jy8y42S1~4n(3LkrW8mW(F-4oXUP3E`e#g**YyqI7h-J2zK zK{m9##m4ri!7N>CqQqCcnI3hqo1I;Yh&QLNY4T`*ptiQGozK>FF$!$+84Z`xwmeMh zJ0WT+OH$WYFALEaGj2_l+#DC3t7_S`vHpSivNeFbP6+r50cO8iu)`7i%Z4BTPh@_m3Tk!nAm^)5Bqnr%Ov|Baunj#&RPtRuK& z4RGz|D5HNrW83-#ydk}tVKJrNmyYt-sTxLGlJY5nc&Re zU4SgHNPx8~Yxwr$bsju?4q&%T1874xxzq+_%?h8_ofw~(bld=o3iC)LUNR*BY%c0y zWd_jX{Y8`l%z+ol1$@Qa?Cy!(0CVIEeYpKZ`(9{z>3$CIe;pJDQk$m3p}$>xBm4lb zKo{4S)`wdU9Ba9jJbVJ0C=SOefZe%d$8=2r={nu<_^a3~>c#t_U6dye5)JrR(_a^E f@}b6j1K9lwFJq@>o)+Ry00000NkvXXu0mjfWa5j* literal 0 HcmV?d00001 diff --git a/sync_on.png b/sync_on.png new file mode 100644 index 0000000000000000000000000000000000000000..e08320fb64e6fa33b573005ed6d8fe294e19db76 GIT binary patch literal 845 zcmV-T1G4;yP)Y;xxyHF2B5Wzm| zOOGupOTn@c(JmBOl)e;XMNnZuiTJP>rM8<|Q`7I_))aP?*T)ow&n59{}X4$3Goat zgjs?*aasfbrokzG5cT4K=uG`E14xZl@z)F={P0Y^?$4t z>v!teRnNZym<6h{7sLyF1V0HsfEl+l6TrZpsfr1}luH~F7L}ktXu|*uVX^RG$L0`K zWs3j|0tIvVe(N%_?2{(iCPFGf#B6Hjy6o&}D$A%W%jfO8_W%ZO#-mh}EM$LMn7joJ z05dHr!5Y92g+31l<%i1(=L1a1pXX+OYnalY>31V4K}BjyRe3)9n#;-cCVRD_IG1fT zOKGeNY8q;TL@K{dj@D^scf&VCs*-Jb>8b>|`b*osv52-!A?BpbYtTQBns5EAU**$m zSnVSm(teh>tQi*S*A>#ySc=n;`BHz`DuG4&g4Kf8lLhca+zvZ7t7RflD6-i-mcK=M z!=^P$*u2)bkY5asG4gsss!Hn%u~>}kIW`vMs%lJLH+u*9<4PaV_c6U`KqWXQH%+Nu zTv41O(^ZVi@qhjQdG!fbZw&y+2o!iYymO^?ud3{P*HdoX83YV*Uu_HB=?U&W9%AU# z80}k1SS-CXTU7dcQlsm<^oYLxVSseqY6NO}dc`Nj?8vrhNuCdm@^{a3AQ_>6myOj+ z`1RsLUXF|dm|3k7s2jD(B{rzE>WI2scH8i1;=O5Cc9xB3^aJk%fQjqsu+kH#0=_5a z0nCE8@dbQa-|YIuUVvG0L_IwHMEhOj$Mj4Uq05 X8=0q~qBNan00000NkvXXu0mjfptF>5 literal 0 HcmV?d00001 diff --git a/tab_a.png b/tab_a.png new file mode 100644 index 0000000000000000000000000000000000000000..3b725c41c5a527a3a3e40097077d0e206a681247 GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QlXwMjv*C{Z|8b*H5dputLHD# z=<0|*y7z(Vor?d;H&?EG&cXR}?!j-Lm&u1OOI7AIF5&c)RFE;&p0MYK>*Kl@eiymD r@|NpwKX@^z+;{u_Z~trSBfrMKa%3`zocFjEXaR$#tDnm{r-UW|TZ1%4 literal 0 HcmV?d00001 diff --git a/tab_b.png b/tab_b.png new file mode 100644 index 0000000000000000000000000000000000000000..e2b4a8638cb3496a016eaed9e16ffc12846dea18 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QU#tajv*C{Z}0l@H7kg?K0Lnr z!j&C6_(~HV9oQ0Pa6x{-v0AGV_E?vLn=ZI-;YrdjIl`U`uzuDWSP?o#Dmo{%SgM#oan kX~E1%D-|#H#QbHoIja2U-MgvsK&LQxy85}Sb4q9e0Efg%P5=M^ literal 0 HcmV?d00001 diff --git a/tabs.css b/tabs.css new file mode 100644 index 00000000..9cf578f2 --- /dev/null +++ b/tabs.css @@ -0,0 +1,60 @@ +.tabs, .tabs2, .tabs3 { + background-image: url('tab_b.png'); + width: 100%; + z-index: 101; + font-size: 13px; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +} + +.tabs2 { + font-size: 10px; +} +.tabs3 { + font-size: 9px; +} + +.tablist { + margin: 0; + padding: 0; + display: table; +} + +.tablist li { + float: left; + display: table-cell; + background-image: url('tab_b.png'); + line-height: 36px; + list-style: none; +} + +.tablist a { + display: block; + padding: 0 20px; + font-weight: bold; + background-image:url('tab_s.png'); + background-repeat:no-repeat; + background-position:right; + color: #283A5D; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; + outline: none; +} + +.tabs3 .tablist a { + padding: 0 10px; +} + +.tablist a:hover { + background-image: url('tab_h.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); + text-decoration: none; +} + +.tablist li.current a { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} diff --git a/z__order_8h.html b/z__order_8h.html new file mode 100644 index 00000000..cabc1bb8 --- /dev/null +++ b/z__order_8h.html @@ -0,0 +1,152 @@ + + + + + + +array: include/array/z_order.h File Reference + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
z_order.h File Reference
+
+
+ +

Helpers for traversing multi-dimensional ranges in z-order. +More...

+
#include "array.h"
+#include <algorithm>
+#include <functional>
+
+

Go to the source code of this file.

+ + + + + + + + +

+Functions

template<class... Ranges, class Fn >
NDARRAY_UNIQUE void for_each_in_z_order (const std::tuple< Ranges... > &ranges, const Fn &fn)
 
+template<class Fn , class... Ranges>
NDARRAY_UNIQUE void for_all_in_z_order (const std::tuple< Ranges... > &ranges, const Fn &fn)
 
+

Detailed Description

+

Helpers for traversing multi-dimensional ranges in z-order.

+

Function Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + +
NDARRAY_UNIQUE void nda::for_each_in_z_order (const std::tuple< Ranges... > & ranges,
const Fn & fn 
)
+
+

Iterate over a multi-dimensional iterator range in "z-order", by following a z-order curve. This ordering may be useful for optimizing for locality. The iterators must be random access iterators.

+ +
+
+
+ + + + diff --git a/z__order_8h_source.html b/z__order_8h_source.html new file mode 100644 index 00000000..c7ab5945 --- /dev/null +++ b/z__order_8h_source.html @@ -0,0 +1,105 @@ + + + + + + +array: include/array/z_order.h Source File + + + + + + + + + + + +
+
+ + + + + + +
+
array +
+
C++ library for multi-dimensional arrays
+
+
+ + + + + + +
+
+ + +
+ +
+ + +
+
+
+
z_order.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
18 #ifndef NDARRAY_Z_ORDER_H
19 #define NDARRAY_Z_ORDER_H
20 
21 #include "array.h"
22 
23 #include <algorithm>
24 #include <functional>
25 
26 namespace nda {
27 
28 namespace internal {
29 
30 inline index_t next_power_of_two(index_t x) {
31  index_t result = 1;
32  while (result < x) {
33  result <<= 1;
34  }
35  return result;
36 }
37 
38 // TODO: This probably doesn't need fn to be inlined, and it would reduce template instantiations
39 // to use std::function instead.
40 template <size_t Rank, class Fn>
41 NDARRAY_UNIQUE void for_each_index_in_z_order_impl(const std::array<index_t, Rank>& end,
42  std::array<index_t, Rank> z, index_t dim, index_t step, const Fn& fn) {
43  if (dim == 0 && step == 1) {
44  // We're at the innermost step of the traversal, call fn for the two neighboring points we have.
45  fn(z);
46  z[0] += 1;
47  if (z[0] < end[0]) {
48  fn(z);
49  }
50  } else if (dim == 0) {
51  // We're on the innermost dimension, but not the innermost step.
52  // Move to the next step for the outermost dimension.
53  for_each_index_in_z_order_impl(end, z, Rank - 1, step >> 1, fn);
54  z[0] += step;
55  if (z[0] < end[0]) {
56  for_each_index_in_z_order_impl(end, z, Rank - 1, step >> 1, fn);
57  }
58  } else {
59  // Move to the next dimension for the same step.
60  for_each_index_in_z_order_impl(end, z, dim - 1, step, fn);
61  z[dim] += step;
62  if (z[dim] < end[dim]) {
63  for_each_index_in_z_order_impl(end, z, dim - 1, step, fn);
64  }
65  }
66 }
67 
68 // TODO: If this conformed more to the rest of the array API, perhaps it could be
69 // exposed as a user API.
70 template <class Extents, class Fn>
71 NDARRAY_UNIQUE void for_each_index_in_z_order(const Extents& extents, const Fn& fn) {
72  constexpr index_t Rank = std::tuple_size<Extents>::value;
73  // Get the ends of the iteration space as an array.
74  const auto end = tuple_to_array<index_t>(extents, make_index_sequence<Rank>());
75  const index_t max_extent = *std::max_element(end.begin(), end.end());
76  const index_t step = std::max<index_t>(1, next_power_of_two(max_extent) >> 1);
77  std::array<index_t, Rank> z = {{0,}};
78  for_each_index_in_z_order_impl(end, z, Rank - 1, step, fn);
79 }
80 
81 template <class... Ranges, class Fn, size_t... Is>
82 NDARRAY_UNIQUE void for_each_in_z_order_impl(
83  const std::tuple<Ranges...>& ranges, const Fn& fn, index_sequence<Is...>) {
84  constexpr size_t Rank = sizeof...(Is);
85  std::array<index_t, Rank> extents = {
86  {(std::end(std::get<Is>(ranges)) - std::begin(std::get<Is>(ranges)))...}};
87  for_each_index_in_z_order(extents, [&](const std::array<index_t, Rank>& i) {
88  fn(std::make_tuple(*(std::begin(std::get<Is>(ranges)) + std::get<Is>(i))...));
89  });
90 }
91 
92 } // namespace internal
93 
98 template <class... Ranges, class Fn>
99 NDARRAY_UNIQUE void for_each_in_z_order(
100  const std::tuple<Ranges...>& ranges, const Fn& fn) {
101  internal::for_each_in_z_order_impl(
102  ranges, fn, internal::make_index_sequence<sizeof...(Ranges)>());
103 }
104 template <class Fn, class... Ranges>
105 NDARRAY_UNIQUE void for_all_in_z_order(
106  const std::tuple<Ranges...>& ranges, const Fn& fn) {
107  internal::for_each_in_z_order_impl(
108  ranges, [&](const auto& i) { internal::apply(fn, i); },
109  internal::make_index_sequence<sizeof...(Ranges)>());
110 }
111 
112 } // namespace nda
113 
114 #endif // NDARRAY_Z_ORDER_H
NDARRAY_UNIQUE void for_each_in_z_order(const std::tuple< Ranges... > &ranges, const Fn &fn)
Definition: z_order.h:99
+
Main header for array library.
+
Definition: absl.h:10
+
std::ptrdiff_t index_t
Definition: array.h:87
+
+ + + +