Skip to content

Instantly share code, notes, and snippets.

@2bbb
Last active January 13, 2016 13:37
Show Gist options
  • Select an option

  • Save 2bbb/f1a167dfdd23fbd2033e to your computer and use it in GitHub Desktop.

Select an option

Save 2bbb/f1a167dfdd23fbd2033e to your computer and use it in GitHub Desktop.
flex_array
#include <iostream>
#include <array>
namespace bbb {
template <typename type>
using get_type = typename type::type;
namespace sequences {
template <typename type, type ... ns>
struct integer_sequence {
using value_type = type;
static constexpr std::size_t size() noexcept { return sizeof...(ns); }
};
namespace impl {
template <typename t>
struct wrapper { using type = t; };
template <typename integer_type, integer_type n, integer_type ... ns>
struct make_integer_sequence {
using type = get_type<get_type<std::conditional<
n == 0,
wrapper<integer_sequence<integer_type, ns ...>>,
make_integer_sequence<integer_type, n - 1, n - 1, ns ...>
>>>;
};
};
template <typename type, type n>
using make_integer_sequence = get_type<impl::make_integer_sequence<type, n>>;
template <std::size_t ... ns>
using index_sequence = integer_sequence<std::size_t, ns ...>;
template <std::size_t n>
using make_index_sequence = make_integer_sequence<std::size_t, n>;
template <typename... types>
using index_sequence_for = make_index_sequence<sizeof...(types)>;
};
using namespace sequences;
template <std::size_t size, std::size_t ... sizes>
struct multiply {
static constexpr std::size_t value = size * multiply<sizes ...>::value;
};
template <std::size_t size>
struct multiply<size> {
static constexpr std::size_t value = size;
};
template <typename value_t, std::size_t size_, std::size_t ... sizes>
struct flex_array {
using value_type = value_t;
using inner_flex_array = flex_array<value_type, sizes ...>;
std::array<inner_flex_array *, size_> arr;
template <std::size_t ... indecies>
flex_array(value_type *body, std::size_t offset, index_sequence<indecies ...>)
: arr({new flex_array<value_t, sizes ...>(body, offset + indecies * multiply<sizes ...>::value) ...}) {}
flex_array(value_type *body, std::size_t offset = 0)
: flex_array(body, offset, make_index_sequence<size_>()) {}
std::size_t size() const { return size_; }
std::size_t rank() const { return sizeof...(sizes) + 1; }
flex_array<value_t, sizes ...> &operator[](std::size_t index) { return *(arr[index]); }
const flex_array<value_t, sizes ...> &operator[](std::size_t index) const { return *(arr[index]); }
};
template <typename value_t, std::size_t size_>
struct flex_array<value_t, size_> {
using value_type = value_t;
value_type * const body;
flex_array(value_type *body, std::size_t offset = 0)
: body(body + offset) {}
std::size_t size() const { return size_; }
std::size_t rank() const { return 1; }
value_type &operator[](std::size_t index) { return body[index]; }
const value_type &operator[](std::size_t index) const { return body[index]; }
};
};
int main(int argc, char *argv[]) {
int *x = new int[64];
for(std::size_t i = 0; i < 64; i++) { x[i] = i + 1; }
bbb::flex_array<int, 4, 4, 4> xs(x);
std::cout << "xs.rank(): " << xs.rank() << std::endl;
for(std::size_t i = 0; i < 3; i++) std::cout << xs[i][i][i] << ", ";
std::cout << xs[3][3][3] << std::endl;
bbb::flex_array<int, 32, 2> ys(x);
std::cout << "ys.rank(): " << ys.rank() << std::endl;
std::cout << ys[16][0] << ", " << ys[16][1] << ", " << ys[17][0];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment