turns out that a vector of vectors is just as fast
This commit is contained in:
parent
7b1e7fd7e3
commit
43d96ffb6d
7 changed files with 248 additions and 93 deletions
|
@ -28,6 +28,7 @@
|
||||||
428EFECF145AF6E0001DBE1B /* Canvas.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Canvas.hpp; sourceTree = "<group>"; };
|
428EFECF145AF6E0001DBE1B /* Canvas.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Canvas.hpp; sourceTree = "<group>"; };
|
||||||
428EFED4145AFAB4001DBE1B /* Tonemapper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Tonemapper.hpp; sourceTree = "<group>"; };
|
428EFED4145AFAB4001DBE1B /* Tonemapper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Tonemapper.hpp; sourceTree = "<group>"; };
|
||||||
42C2D1521461676B001BF28D /* Image.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Image.hpp; sourceTree = "<group>"; };
|
42C2D1521461676B001BF28D /* Image.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Image.hpp; sourceTree = "<group>"; };
|
||||||
|
42C2D1611461894E001BF28D /* Logging.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Logging.hpp; sourceTree = "<group>"; };
|
||||||
42D2E11D1456175C00FBC16A /* AwesomeAttractorND */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = AwesomeAttractorND; sourceTree = BUILT_PRODUCTS_DIR; };
|
42D2E11D1456175C00FBC16A /* AwesomeAttractorND */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = AwesomeAttractorND; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
42D2E1211456175C00FBC16A /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
|
42D2E1211456175C00FBC16A /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
|
||||||
42D2E1231456175C00FBC16A /* AwesomeAttractorND.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = AwesomeAttractorND.1; sourceTree = "<group>"; };
|
42D2E1231456175C00FBC16A /* AwesomeAttractorND.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = AwesomeAttractorND.1; sourceTree = "<group>"; };
|
||||||
|
@ -65,6 +66,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
42D2E1211456175C00FBC16A /* main.cpp */,
|
42D2E1211456175C00FBC16A /* main.cpp */,
|
||||||
|
42C2D1611461894E001BF28D /* Logging.hpp */,
|
||||||
42D2E12A1456176800FBC16A /* nd_array.hpp */,
|
42D2E12A1456176800FBC16A /* nd_array.hpp */,
|
||||||
428EFECF145AF6E0001DBE1B /* Canvas.hpp */,
|
428EFECF145AF6E0001DBE1B /* Canvas.hpp */,
|
||||||
428EFED4145AFAB4001DBE1B /* Tonemapper.hpp */,
|
428EFED4145AFAB4001DBE1B /* Tonemapper.hpp */,
|
||||||
|
@ -151,9 +153,15 @@
|
||||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
HEADER_SEARCH_PATHS = /usr/local/include/;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
|
WARNING_CFLAGS = (
|
||||||
|
"-Weffc++",
|
||||||
|
"-Wextra",
|
||||||
|
"-Wall",
|
||||||
|
);
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
|
@ -171,8 +179,14 @@
|
||||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
HEADER_SEARCH_PATHS = /usr/local/include/;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
|
WARNING_CFLAGS = (
|
||||||
|
"-Weffc++",
|
||||||
|
"-Wextra",
|
||||||
|
"-Wall",
|
||||||
|
);
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#ifndef AwesomeAttractorND_Canvas_hpp
|
#ifndef AwesomeAttractorND_Canvas_hpp
|
||||||
#define AwesomeAttractorND_Canvas_hpp
|
#define AwesomeAttractorND_Canvas_hpp
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
#include "nd_array.hpp"
|
#include "nd_array.hpp"
|
||||||
|
|
||||||
class Canvas2D : public nd_array<unsigned int, 2>{
|
class Canvas2D : public nd_array<unsigned int, 2>{
|
||||||
|
@ -24,14 +25,45 @@ public:
|
||||||
const size_t width = get_size(0);
|
const size_t width = get_size(0);
|
||||||
const size_t height = get_size(1);
|
const size_t height = get_size(1);
|
||||||
|
|
||||||
const size_t x = position[0]*width + width*.5;
|
const size_t x = 0.5*position[0]*width + width*.5;
|
||||||
const size_t y = position[1]*width + height*.5;
|
const size_t y = 0.5*position[1]*width + height*.5;
|
||||||
|
|
||||||
|
if(x < width && y < height) {
|
||||||
|
(*this)[x][y]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Canvas2Db : public std::vector<std::vector<unsigned int> > {
|
||||||
|
typedef Canvas2Db self;
|
||||||
|
typedef std::vector<std::vector<unsigned int> > super;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Canvas2Db(size_t width, size_t height)
|
||||||
|
: super(width, super::value_type(height, 0))
|
||||||
|
{}
|
||||||
|
|
||||||
|
void plot(double const * const position){
|
||||||
|
const size_t width = get_size(0);
|
||||||
|
const size_t height = get_size(1);
|
||||||
|
|
||||||
|
const size_t x = 0.5*position[0]*width + width*.5;
|
||||||
|
const size_t y = 0.5*position[1]*width + height*.5;
|
||||||
|
|
||||||
if(x < width && y < height) {
|
if(x < width && y < height) {
|
||||||
(*this)[x][y]++;
|
(*this)[x][y]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t get_size(size_t n) const {
|
||||||
|
switch (n) {
|
||||||
|
case 0:
|
||||||
|
return size();
|
||||||
|
case 1:
|
||||||
|
return front().size();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
#include <tr1/memory>
|
#include <tr1/memory>
|
||||||
|
|
||||||
struct pixel {
|
struct pixel {
|
||||||
friend class Image;
|
|
||||||
|
|
||||||
pixel(double red, double green, double blue)
|
pixel(double red, double green, double blue)
|
||||||
: red(clamp(255*red))
|
: red(clamp(255*red))
|
||||||
, green(clamp(255*green))
|
, green(clamp(255*green))
|
||||||
|
@ -29,6 +27,10 @@ struct pixel {
|
||||||
, blue(clamp(blue))
|
, blue(clamp(blue))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
void swapRB(){
|
||||||
|
std::swap(red, blue);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t clamp(int n){
|
uint8_t clamp(int n){
|
||||||
return std::min(255, std::max(0, n));
|
return std::min(255, std::max(0, n));
|
||||||
|
@ -116,21 +118,29 @@ namespace ImageFormats {
|
||||||
: dib_header(width, height)
|
: dib_header(width, height)
|
||||||
, header(dib_header)
|
, header(dib_header)
|
||||||
, file(filename.c_str())
|
, file(filename.c_str())
|
||||||
|
, x(0)
|
||||||
|
, y(0)
|
||||||
{
|
{
|
||||||
|
if(!file)
|
||||||
|
throw std::runtime_error("bitmap file could not be opened.");
|
||||||
header.write(file);
|
header.write(file);
|
||||||
dib_header.write(file);
|
dib_header.write(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
bitmap_stream& operator<<(pixel const & p){
|
bitmap_stream& operator<<(pixel const & p){
|
||||||
file.write(&p, 3);
|
if (y >= dib_header.height){
|
||||||
|
throw std::out_of_range("Writing BMP image out of bounds.");
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel p2(p);
|
||||||
|
p2.swapRB();
|
||||||
|
file.write((char const *)&p2, 3);
|
||||||
++x;
|
++x;
|
||||||
if (x >= dib_header.width){
|
if (x >= dib_header.width){
|
||||||
x = 0;
|
x = 0;
|
||||||
++y;
|
++y;
|
||||||
}
|
}
|
||||||
if (y >= dib_header.height){
|
return *this;
|
||||||
throw std::out_of_range("Writing BMP image out of bounds.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
139
AwesomeAttractorND/Logging.hpp
Normal file
139
AwesomeAttractorND/Logging.hpp
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
//
|
||||||
|
// Logging.hpp
|
||||||
|
// AwesomeAttractorND
|
||||||
|
//
|
||||||
|
// Created by Joshua Moerman on 11/2/11.
|
||||||
|
// Copyright 2011 Vadovas. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef AwesomeAttractorND_Logging_hpp
|
||||||
|
#define AwesomeAttractorND_Logging_hpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define INFORMATION __FILE__ << ":" << __LINE__ << "(" << __FUNCTION__ << ")"
|
||||||
|
#define COUT std::cout << INFORMATION << "\n"
|
||||||
|
#define CERR std::cerr << INFORMATION << "\n"
|
||||||
|
|
||||||
|
#define VCOUT if(verbose) COUT
|
||||||
|
#define VCERR if(verbose) CERR
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <stack>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
|
|
||||||
|
/* Usage:
|
||||||
|
When timing anything:
|
||||||
|
Before starting the task: start("with a string");
|
||||||
|
When the task is done: stop();
|
||||||
|
|
||||||
|
The shorthand for that is
|
||||||
|
{
|
||||||
|
start("foo");
|
||||||
|
foo();
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
Note that a call to stop without parameters, stops the last started event. This works like a stack:
|
||||||
|
{
|
||||||
|
start("Task of several small tasks");
|
||||||
|
start("Small task 1");
|
||||||
|
small_task_1();
|
||||||
|
stop();
|
||||||
|
|
||||||
|
start("Small task 2");
|
||||||
|
small_task_2();
|
||||||
|
stop();
|
||||||
|
stop(); // Stops "Task of several small tasks"
|
||||||
|
}
|
||||||
|
The indenting is, of course, only to help you understand what's going on.
|
||||||
|
|
||||||
|
Questions/Suggestions mail nick@astrant.net
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct Logger {
|
||||||
|
Logger(std::ostream& logging_stream_, std::string prefix_ = std::string(""))
|
||||||
|
: logging_stream(&logging_stream_)
|
||||||
|
, prefix(prefix_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void log(std::string what){
|
||||||
|
*logging_stream << get_prefix() << "(" << what << ") took place at (" << boost::posix_time::microsec_clock::local_time() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start(std::string what){
|
||||||
|
Event e;
|
||||||
|
e.start = boost::posix_time::microsec_clock::local_time();
|
||||||
|
e.name = what;
|
||||||
|
|
||||||
|
EventMap::iterator it = event_map.find(what);
|
||||||
|
if(it != event_map.end()){
|
||||||
|
*logging_stream << get_prefix() << "WARNING: Overwriting event(" << e.name << "), did you forget to call stop()?";
|
||||||
|
} else {
|
||||||
|
event_name_stack.push(what);
|
||||||
|
}
|
||||||
|
|
||||||
|
event_map.insert(it, std::make_pair(what, e));
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop() {
|
||||||
|
assert(!event_name_stack.empty());
|
||||||
|
stop(event_name_stack.top());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void stop(std::string what){
|
||||||
|
EventMap::iterator it = event_map.find(what);
|
||||||
|
if(it == event_map.end()){
|
||||||
|
*logging_stream << get_prefix() << "WARNING: No such, or already stopped, event(" << what << "), did you forget to call start()?";
|
||||||
|
} else {
|
||||||
|
it->second.end = boost::posix_time::microsec_clock::local_time();
|
||||||
|
log_event(it->second);
|
||||||
|
event_map.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
event_name_stack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Event {
|
||||||
|
boost::posix_time::ptime start;
|
||||||
|
boost::posix_time::ptime end;
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A map containing strings -> Event, used by start() and stop()
|
||||||
|
typedef std::map<std::string, Event> EventMap;
|
||||||
|
EventMap event_map;
|
||||||
|
|
||||||
|
// A stack used by 0-parameter stop() to stop the last start()ed event.
|
||||||
|
std::stack<std::string> event_name_stack;
|
||||||
|
|
||||||
|
std::ostream* logging_stream;
|
||||||
|
|
||||||
|
std::string prefix;
|
||||||
|
|
||||||
|
void log_event(Event const& e){
|
||||||
|
*logging_stream << get_prefix() << "Event(" << e.name << ") started at (" << e.start << ") ended at (" << e.end << ") duration (" << e.end - e.start << " ms) " << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_prefix() const {
|
||||||
|
if(prefix == std::string("")){
|
||||||
|
return prefix;
|
||||||
|
} else {
|
||||||
|
return prefix + ": ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -10,15 +10,23 @@
|
||||||
#define AwesomeAttractorND_Tonemapper_hpp
|
#define AwesomeAttractorND_Tonemapper_hpp
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
namespace Tonemappers {
|
namespace Tonemappers {
|
||||||
|
|
||||||
class Normalizer2D {
|
struct Normalizer2D {
|
||||||
unsigned int max;
|
Normalizer2D()
|
||||||
|
: max(0)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename C>
|
template <typename C>
|
||||||
void analyse(C const & canvas){
|
void analyse(C const & canvas){
|
||||||
max = *std::max_element(canvas.cbegin(), canvas.cend());
|
//max = *std::max_element(canvas.cbegin(), canvas.cend());
|
||||||
|
for (size_t x = 0; x < canvas.get_size(0); ++x) {
|
||||||
|
for (size_t y = 0; y < canvas.get_size(1); ++y) {
|
||||||
|
max = std::max(max, (unsigned int)canvas[x][y]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename C, typename I>
|
template <typename C, typename I>
|
||||||
|
@ -26,10 +34,13 @@ namespace Tonemappers {
|
||||||
for (size_t x = 0; x < canvas.get_size(0); ++x) {
|
for (size_t x = 0; x < canvas.get_size(0); ++x) {
|
||||||
for (size_t y = 0; y < canvas.get_size(1); ++y) {
|
for (size_t y = 0; y < canvas.get_size(1); ++y) {
|
||||||
const double grayscale = (double) canvas[x][y] / (double) max;
|
const double grayscale = (double) canvas[x][y] / (double) max;
|
||||||
image << I::pixel(grayscale, grayscale, grayscale);
|
image << typename I::pixel(std::pow(grayscale, 0.2), std::pow(grayscale, 0.6), grayscale*1.5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned int max;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,91 +12,40 @@
|
||||||
#include "Canvas.hpp"
|
#include "Canvas.hpp"
|
||||||
#include "Tonemapper.hpp"
|
#include "Tonemapper.hpp"
|
||||||
#include "Image.hpp"
|
#include "Image.hpp"
|
||||||
|
#include "Logging.hpp"
|
||||||
|
|
||||||
const size_t width = 512;
|
typedef Canvas2D Canvas;
|
||||||
const size_t height = 64;
|
|
||||||
const size_t depth = 32;
|
|
||||||
|
|
||||||
typedef nd_array<double, 3> array;
|
void fill(Canvas & canvas){
|
||||||
|
const unsigned int it = 100000000/2;
|
||||||
|
|
||||||
double calculate1(array & c){
|
for (unsigned int i = 0; i < it; ++i){
|
||||||
double mean = 0.0;
|
double x = 2.0 * (rand() / (double) RAND_MAX - 0.5);
|
||||||
for (unsigned int x = 0; x < width; ++x) {
|
double y = 2.0 * (rand() / (double) RAND_MAX - 0.5);
|
||||||
for (unsigned int y = 0; y < height; ++y) {
|
double position[2] = {sin(x / (y*y - 1)), sin(y / (x*x - 1))};
|
||||||
for (unsigned int z = 0; z < depth; ++z) {
|
canvas.plot(position);
|
||||||
mean += 1.0/(width*height*depth) * c[x][y][z];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mean;
|
|
||||||
}
|
|
||||||
|
|
||||||
void calculate2(array & c, double mean){
|
|
||||||
for (unsigned int x = 0; x < width; ++x) {
|
|
||||||
for (unsigned int y = 0; y < height; ++y) {
|
|
||||||
for (unsigned int z = 0; z < depth; ++z) {
|
|
||||||
c[x][y][z] = c[x/3][y][z/2] * mean / 200.0 + mean - x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculate(array & c){
|
void output(Canvas const & canvas){
|
||||||
std::cout << "Calculating..." << std::endl;
|
ImageFormats::bmp::bitmap_stream<> image(canvas.get_size(0), canvas.get_size(1), "test.bmp");
|
||||||
|
Tonemappers::Normalizer2D tonemapper;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 1000; ++i) {
|
tonemapper.analyse(canvas);
|
||||||
double mean = calculate1(c);
|
tonemapper.process(canvas, image);
|
||||||
calculate2(c, mean);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill(array & c){
|
int main (int, const char * []){
|
||||||
std::cout << "Filling..." << std::endl;
|
Logger l(std::cout);
|
||||||
|
l.start("all");
|
||||||
|
|
||||||
for (unsigned int x = 0; x < width; ++x) {
|
l.log("creating canvas");
|
||||||
for (unsigned int y = 0; y < height; ++y) {
|
Canvas canvas(2048, 2048);
|
||||||
for (unsigned int z = 0; z < depth; ++z) {
|
l.log("filling canvas");
|
||||||
c[x][y][z] = x + z;
|
fill(canvas);
|
||||||
if (y == 5) {
|
l.log("outputting canvas");
|
||||||
c[x][y][z] = 5;
|
output(canvas);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void output(array & c){
|
|
||||||
std::cout << "Outputting..." << std::endl;
|
|
||||||
|
|
||||||
for (unsigned int y = 0; y < 10; ++y) {
|
|
||||||
for (unsigned int x = 0; x < 10; ++x) {
|
|
||||||
std::cout << c[x][y][2] << '\t';
|
|
||||||
}
|
|
||||||
std::cout << '\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "Outputting addresses..." << std::endl;
|
|
||||||
|
|
||||||
for (unsigned int z = 20; z < 30; ++z) {
|
|
||||||
double & n = c[32][64][z];
|
|
||||||
std::cout << &n << '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main (int argc, const char * argv[]){
|
|
||||||
|
|
||||||
std::cout << "Creating..." << std::endl;
|
|
||||||
|
|
||||||
array c(width, height, depth);
|
|
||||||
|
|
||||||
fill(c);
|
|
||||||
|
|
||||||
calculate(c);
|
|
||||||
|
|
||||||
output(c);
|
|
||||||
|
|
||||||
std::cout << "Done" << std::endl;
|
|
||||||
|
|
||||||
|
l.stop();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ public:
|
||||||
|
|
||||||
const_proxy<N-1> operator[](size_t y) const {
|
const_proxy<N-1> operator[](size_t y) const {
|
||||||
if (N == 0) throw std::logic_error("called operator[] on a value");
|
if (N == 0) throw std::logic_error("called operator[] on a value");
|
||||||
return proxy<N-1>(data, data->sizes[dimension - N]*offset + y);
|
return const_proxy<N-1>(data, data->sizes[dimension - N]*offset + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
operator const_reference() const {
|
operator const_reference() const {
|
||||||
|
@ -115,7 +115,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type size() const {
|
size_type size() const {
|
||||||
return std::accumulate(sizes.begin(), sizes.end(), 0, std::multiplies<size_type>());
|
return std::accumulate(sizes.begin(), sizes.end(), 1, std::multiplies<size_type>());
|
||||||
}
|
}
|
||||||
|
|
||||||
proxy<dimension-1> operator[](size_t x){
|
proxy<dimension-1> operator[](size_t x){
|
||||||
|
@ -123,7 +123,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
const_proxy<dimension-1> operator[](size_t x) const {
|
const_proxy<dimension-1> operator[](size_t x) const {
|
||||||
return proxy<dimension-1>(this, x);
|
return const_proxy<dimension-1>(this, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator begin(){
|
iterator begin(){
|
||||||
|
|
Reference in a new issue