Better headers (with my name in it :D). Added new header nd_array
This commit is contained in:
parent
b210eb3d81
commit
edf2571487
4 changed files with 177 additions and 0 deletions
|
@ -1,3 +1,10 @@
|
|||
//
|
||||
// binary_output.hpp
|
||||
//
|
||||
// Created by Joshua Moerman on 05/22/11.
|
||||
// Copyright 2011 Vadovas. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef BINARY_OUTPUT_HPP
|
||||
#define BINARY_OUTPUT_HPP
|
||||
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
//
|
||||
// brainfuck.hpp
|
||||
//
|
||||
// Created by Joshua Moerman on 05/22/11.
|
||||
// Copyright 2011 Vadovas. All rights reserved.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
//
|
||||
// counting_iterator.hpp
|
||||
//
|
||||
// Created by Joshua Moerman on 05/22/11.
|
||||
// Copyright 2011 Vadovas. All rights reserved.
|
||||
//
|
||||
|
||||
/*
|
||||
|
||||
USAGE:
|
||||
|
|
156
nd_array/nd_array.hpp
Normal file
156
nd_array/nd_array.hpp
Normal file
|
@ -0,0 +1,156 @@
|
|||
//
|
||||
// nd_array.hpp
|
||||
//
|
||||
// Created by Joshua Moerman on 10/25/11.
|
||||
// Copyright 2011 Vadovas. All rights reserved.
|
||||
//
|
||||
|
||||
/*
|
||||
Dynamic multi-dimensional array.
|
||||
With the usual c-syntax: v[x][y][z].
|
||||
Memory is allocated as one big block, instead of multiple smaller blocks (which is the case with std::vector<std::vector<...>>).
|
||||
Showed no difference in speed compared to std::vector<std::vector<...>> (in release build), so you better can use std::vector.
|
||||
|
||||
This class can be used te reinterpret a big chunk of memory as a n-dimensional array. (Could be useful if your legacy-code gives you somthing like that).
|
||||
|
||||
It is templated in number of dimensions (and of course type). With extra effort you could make the dimension dynamic (ie not compile-time, but run-time), I leave that as an excercise to the reader.
|
||||
*/
|
||||
|
||||
#ifndef AwesomeAttractorND_nd_array_hpp
|
||||
#define AwesomeAttractorND_nd_array_hpp
|
||||
|
||||
#include <stdexcept>
|
||||
#include <numeric>
|
||||
#include <iterator>
|
||||
#include <array> // C++11, right here :D (if this fails, try using tr1)
|
||||
|
||||
template <typename T, size_t dimension>
|
||||
class nd_array{
|
||||
public:
|
||||
typedef T & reference;
|
||||
typedef T const & const_reference;
|
||||
typedef T * iterator;
|
||||
typedef T const * const_iterator;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
typedef T const * const_pointer;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
/*
|
||||
NOTE: I actually wanted to make a specialisation for N = 0, but this is not possible in class scope, so it had to be in namespace-scope. Problem with the specialisation then is that the outer-class isn't specialised, while the inner is, this is also not possible. So either I had to make this class completly out of the nd_array class (which would require a lot of templating), OR I check things in an non-templated way. I chose for the latter, since it was easier to make. The first one is actually beter (it would have better types, which make dimensionality-errors a type-error, instead of an exception).
|
||||
*/
|
||||
template <size_type N>
|
||||
struct proxy {
|
||||
nd_array * const data;
|
||||
size_t const offset;
|
||||
|
||||
proxy(nd_array * const c, size_t o)
|
||||
: data(c)
|
||||
, offset(o)
|
||||
{}
|
||||
|
||||
proxy<N-1> operator[](size_t y){
|
||||
if (N == 0) throw std::logic_error("called operator[] on a value");
|
||||
return proxy<N-1>(data, data->sizes[dimension - N]*offset + y);
|
||||
}
|
||||
|
||||
operator reference(){
|
||||
if (N != 0) throw std::logic_error("using a non-value");
|
||||
return *(data->data + offset);
|
||||
}
|
||||
|
||||
reference operator=(T const & n){
|
||||
if (N != 0) throw std::logic_error("assignment to a non-value");
|
||||
return *(data->data + offset) = n;
|
||||
}
|
||||
};
|
||||
|
||||
template <size_type N>
|
||||
struct const_proxy {
|
||||
nd_array const * const data;
|
||||
size_t const offset;
|
||||
|
||||
const_proxy(nd_array const * const c, size_t o)
|
||||
: data(c)
|
||||
, offset(o)
|
||||
{}
|
||||
|
||||
const_proxy<N-1> operator[](size_t y) const {
|
||||
if (N == 0) throw std::logic_error("called operator[] on a value");
|
||||
return const_proxy<N-1>(data, data->sizes[dimension - N]*offset + y);
|
||||
}
|
||||
|
||||
operator const_reference() const {
|
||||
if (N != 0) throw std::logic_error("using a non-value");
|
||||
return *(data->data + offset);
|
||||
}
|
||||
};
|
||||
|
||||
nd_array(size_type width, size_type height)
|
||||
: data(0)
|
||||
, sizes()
|
||||
{
|
||||
if (dimension != 2) throw std::logic_error("wrong constructor");
|
||||
sizes[0] = width;
|
||||
sizes[1] = height;
|
||||
data = new T[width*height];
|
||||
}
|
||||
|
||||
nd_array(size_type width, size_type height, size_type depth)
|
||||
: data(0)
|
||||
, sizes()
|
||||
{
|
||||
if (dimension != 3) throw std::logic_error("wrong constructor");
|
||||
sizes[0] = width;
|
||||
sizes[1] = height;
|
||||
sizes[2] = depth;
|
||||
data = new T[width*height*depth];
|
||||
}
|
||||
|
||||
~nd_array(){
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
size_type get_size(size_type d) const {
|
||||
return sizes[d];
|
||||
}
|
||||
|
||||
size_type size() const {
|
||||
return std::accumulate(sizes.begin(), sizes.end(), 1, std::multiplies<size_type>());
|
||||
}
|
||||
|
||||
proxy<dimension-1> operator[](size_t x){
|
||||
return proxy<dimension-1>(this, x);
|
||||
}
|
||||
|
||||
const_proxy<dimension-1> operator[](size_t x) const {
|
||||
return const_proxy<dimension-1>(this, x);
|
||||
}
|
||||
|
||||
iterator begin(){
|
||||
return data;
|
||||
}
|
||||
|
||||
iterator end(){
|
||||
size_type length = size();
|
||||
return data + length;
|
||||
}
|
||||
|
||||
const_iterator cbegin() const {
|
||||
return data;
|
||||
}
|
||||
|
||||
const_iterator cend() const {
|
||||
size_type length = size();
|
||||
return data + length;
|
||||
}
|
||||
|
||||
private:
|
||||
T * data;
|
||||
std::array<size_type, dimension> sizes;
|
||||
};
|
||||
|
||||
#endif
|
Reference in a new issue