/usr/include/xtensor/xgenerator.hpp is in xtensor-dev 0.10.11-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 | /***************************************************************************
* Copyright (c) 2016, Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
* *
* Distributed under the terms of the BSD 3-Clause License. *
* *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/
#ifndef XGENERATOR_HPP
#define XGENERATOR_HPP
#include <algorithm>
#include <cstddef>
#include <numeric>
#include <tuple>
#include <type_traits>
#include <utility>
#include "xexpression.hpp"
#include "xiterable.hpp"
#include "xstrides.hpp"
#include "xutils.hpp"
namespace xt
{
/**************
* xgenerator *
**************/
template <class F, class R, class S>
class xgenerator;
template <class C, class R, class S>
struct xiterable_inner_types<xgenerator<C, R, S>>
{
using inner_shape_type = S;
using const_stepper = xindexed_stepper<xgenerator<C, R, S>>;
using stepper = const_stepper;
using const_iterator = xiterator<const_stepper, inner_shape_type*, DEFAULT_LAYOUT>;
using iterator = const_iterator;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using reverse_iterator = std::reverse_iterator<iterator>;
};
/**
* @class xgenerator
* @brief Multidimensional function operating on indices.
*
* The xgenerator class implements a multidimensional function,
* generating a value from the supplied indices.
*
* @tparam F the function type
* @tparam R the return type of the function
* @tparam S the shape type of the generator
*/
template <class F, class R, class S>
class xgenerator : public xexpression<xgenerator<F, R, S>>,
public xexpression_const_iterable<xgenerator<F, R, S>>
{
public:
using self_type = xgenerator<F, R, S>;
using functor_type = typename std::remove_reference<F>::type;
using value_type = R;
using reference = value_type;
using const_reference = value_type;
using pointer = value_type*;
using const_pointer = const value_type*;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using iterable_base = xexpression_const_iterable<self_type>;
using inner_shape_type = typename iterable_base::inner_shape_type;
using shape_type = inner_shape_type;
using strides_type = S;
using stepper = typename iterable_base::stepper;
using const_stepper = typename iterable_base::const_stepper;
static constexpr layout_type static_layout = layout_type::any;
static constexpr bool contiguous_layout = false;
template <class Func>
xgenerator(Func&& f, const S& shape) noexcept;
size_type size() const noexcept;
size_type dimension() const noexcept;
const inner_shape_type& shape() const noexcept;
layout_type layout() const noexcept;
template <class... Args>
const_reference operator()(Args... args) const;
const_reference operator[](const xindex& index) const;
const_reference operator[](size_type i) const;
template <class It>
const_reference element(It first, It last) const;
template <class O>
bool broadcast_shape(O& shape) const;
template <class O>
bool is_trivial_broadcast(const O& /*strides*/) const noexcept;
template <class O>
const_stepper stepper_begin(const O& shape) const noexcept;
template <class O>
const_stepper stepper_end(const O& shape, layout_type) const noexcept;
private:
functor_type m_f;
inner_shape_type m_shape;
};
/*****************************
* xgenerator implementation *
*****************************/
/**
* @name Constructor
*/
//@{
/**
* Constructs an xgenerator applying the specified function over the
* given shape.
* @param f the function to apply
* @param shape the shape of the xgenerator
*/
template <class F, class R, class S>
template <class Func>
inline xgenerator<F, R, S>::xgenerator(Func&& f, const S& shape) noexcept
: m_f(std::forward<Func>(f)), m_shape(shape)
{
}
//@}
/**
* @name Size and shape
*/
//@{
/**
* Returns the size of the expression.
*/
template <class F, class R, class S>
inline auto xgenerator<F, R, S>::size() const noexcept -> size_type
{
return compute_size(shape());
}
/**
* Returns the number of dimensions of the function.
*/
template <class F, class R, class S>
inline auto xgenerator<F, R, S>::dimension() const noexcept -> size_type
{
return m_shape.size();
}
/**
* Returns the shape of the xgenerator.
*/
template <class F, class R, class S>
inline auto xgenerator<F, R, S>::shape() const noexcept -> const inner_shape_type&
{
return m_shape;
}
template <class F, class R, class S>
inline layout_type xgenerator<F, R, S>::layout() const noexcept
{
return static_layout;
}
//@}
/**
* @name Data
*/
/**
* Returns the evaluated element at the specified position in the function.
* @param args a list of indices specifying the position in the function. Indices
* must be unsigned integers, the number of indices should be equal or greater than
* the number of dimensions of the function.
*/
template <class F, class R, class S>
template <class... Args>
inline auto xgenerator<F, R, S>::operator()(Args... args) const -> const_reference
{
XTENSOR_ASSERT(check_index(shape(), args...));
return m_f(args...);
}
template <class F, class R, class S>
inline auto xgenerator<F, R, S>::operator[](const xindex& index) const -> const_reference
{
return element(index.begin(), index.end());
}
template <class F, class R, class S>
inline auto xgenerator<F, R, S>::operator[](size_type i) const -> const_reference
{
return operator()(i);
}
/**
* Returns a constant reference to the element at the specified position in the function.
* @param first iterator starting the sequence of indices
* @param last iterator ending the sequence of indices
* The number of indices in the sequence should be equal to or greater
* than the number of dimensions of the container.
*/
template <class F, class R, class S>
template <class It>
inline auto xgenerator<F, R, S>::element(It first, It last) const -> const_reference
{
XTENSOR_ASSERT(check_element_index(shape(), first, last));
return m_f.element(first, last);
}
//@}
/**
* @name Broadcasting
*/
//@{
/**
* Broadcast the shape of the function to the specified parameter.
* @param shape the result shape
* @return a boolean indicating whether the broadcasting is trivial
*/
template <class F, class R, class S>
template <class O>
inline bool xgenerator<F, R, S>::broadcast_shape(O& shape) const
{
return xt::broadcast_shape(m_shape, shape);
}
/**
* Compares the specified strides with those of the container to see whether
* the broadcasting is trivial.
* @return a boolean indicating whether the broadcasting is trivial
*/
template <class F, class R, class S>
template <class O>
inline bool xgenerator<F, R, S>::is_trivial_broadcast(const O& /*strides*/) const noexcept
{
return false;
}
//@}
template <class F, class R, class S>
template <class O>
inline auto xgenerator<F, R, S>::stepper_begin(const O& shape) const noexcept -> const_stepper
{
size_type offset = shape.size() - dimension();
return const_stepper(this, offset);
}
template <class F, class R, class S>
template <class O>
inline auto xgenerator<F, R, S>::stepper_end(const O& shape, layout_type) const noexcept -> const_stepper
{
size_type offset = shape.size() - dimension();
return const_stepper(this, offset, true);
}
namespace detail
{
#ifdef X_OLD_CLANG
template <class Functor, class I>
inline auto make_xgenerator(Functor&& f, std::initializer_list<I> shape) noexcept
{
using shape_type = std::vector<std::size_t>;
using type = xgenerator<Functor, typename Functor::value_type, shape_type>;
return type(std::forward<Functor>(f), forward_sequence<shape_type>(shape));
}
#else
template <class Functor, class I, std::size_t L>
inline auto make_xgenerator(Functor&& f, const I (&shape)[L]) noexcept
{
using shape_type = std::array<std::size_t, L>;
using type = xgenerator<Functor, typename Functor::value_type, shape_type>;
return type(std::forward<Functor>(f), forward_sequence<shape_type>(shape));
}
#endif
template <class Functor, class S>
inline auto make_xgenerator(Functor&& f, S&& shape) noexcept
{
using type = xgenerator<Functor, typename Functor::value_type, std::decay_t<S>>;
return type(std::forward<Functor>(f), std::forward<S>(shape));
}
}
}
#endif
|