<commit_before>// Copyright (c) 2013, Matthew Harvey. All rights reserved.

/** \file main.cpp
 *
 * \brief Contains main function, and possibly some small amount
 * of other code, relating to Phatbooks application.
 *
 * \author Matthew Harvey
 * \date 04 July 2012.
 *
 * Copyright (c) 2012, Matthew Harvey. All rights reserved.
 */

// TODO HIGH PRIORITY Tooltips aren't showing on Windows.

// TODO It must be easy for the user to send in an error report.
// One way is to implement "proper core dumping" on crash. An easy
// way is to have a logging statement at the beginning of, like,
// every function, that logs the source filepath and the line number,
// writing these to a logging stream (which need only be flushed at
// intervals). There could be runtime switch that turns logging on or
// off, which the user could switch on or off via a config file or in
// preferences in the GUI (though the config file might be necessary in
// the case the application is crashing on startup and the user can't even
// access the preferences). There could also be a preprocessor switch to
// disable this logging completely to avoid even having to check the switch.
// We could turn off the preprocessor switch on some future release
// if it ever became a performance problem. A nice side effect of this
// approach is that it would also assist me in everyday debugging. (But
// can this ever be better than just using GDB? Yes - because GDB so
// often gives poor information because, for example, some library
// is missing or etc.. If I have manual logging, then I KNOW it will
// print to log, and also it means I can enable or disable

// TODO Make the installer create an association on the user's system
// between the Phatbooks file extension and the Phatbooks application.
// See CMake book, page. 162.

// TODO (For GUI). Users will probably expect
// right-clicking to cause a context-dependent menu to pop up.

// TODO The application should automatically create a zipped backup
// file so that the session can be recovered if something goes wrong.

// TODO The database file should perhaps have a checksum to guard
// against its contents changing other than via the application.

// TODO Facilitate automatic checking for updates from user's
// machine, as well as easy process for providing updates
// via NSIS. It appears that the default configuration of CPack/NSIS is
// such that updates will not overwrite existing files. Some manual NSIS
// scripting may be required to enable this. Also take into account that
// the user may have to restart their computer in the event that they have
// files open while the installer (or "updater") is running (although I
// \e think that the default configuration under CPack does this
// automatically).

// TODO Write the licence.

// TODO Ensure that option for the user to lauch directly from the
// installer, works correctly.

// TODO Create a decent icon for the application. We want this
// in both .ico form (for Windows executable icon) and .xpm
// form (for icon for Frame). Note, when I exported my
// "token icon" using GIMP to .ico format, and later used this
// to create a double-clickable icon in Windows, only the text
// on the icon appeared, and the background image became
// transparent for some reason. Furthermore, when set as the
// large in-windows icon in the CPack/NSIS installer, the icon
// wasn't showing at all.

// TODO On Fedora, recompile and install wxWidgets with an additional
// configure flag, viz. --with-gnomeprint (sp?).

// TODO Set the version number in a single location and find a way
// to ensure this is reflected consistently everywhere it appears
// (website, installer, licence text etc.).

// TODO We need a proper solution to the potential for integer overflow.
// Mostly we use jewel::Decimal arithmetic - which will throw if unsafe -
// but we're not actually handling these exceptions for the user. The
// program would just crash.

// TODO HIGH PRIORITY Make the GUI display acceptably on smaller screen
// i.e. laptop.

#include "application.hpp"
#include "string_conv.hpp"
#include "graphical_session.hpp"
#include <boost/scoped_ptr.hpp>
#include <jewel/assert.hpp>
#include <jewel/log.hpp>
#include <tclap/CmdLine.h>
#include <wx/log.h>
#include <wx/snglinst.h>
#include <wx/string.h>
#include <wx/utils.h>
#include <cassert>
#include <cstdlib>
#include <exception>
#include <fstream>
#include <ios>
#include <iostream>
#include <string>

using boost::scoped_ptr;
using jewel::Log;
using phatbooks::Application;
using phatbooks::gui::GraphicalSession;
using phatbooks::wx_to_std8;
using std::abort;
using std::cerr;
using std::clog;
using std::cout;
using std::endl;
using std::ofstream;
using std::string;
using std::set_terminate;
using TCLAP::ArgException;
using TCLAP::CmdLine;
using TCLAP::UnlabeledValueArg;

void flush_standard_output_streams()
{
	cerr.flush();
	clog.flush();
	cout.flush();
	return;
}

void my_terminate_handler()
{
	// TODO HIGH PRIORITY This seems like a good idea, but is there
	// a hidden catch? (Custom terminate handling should not be done
	// lightly...)
	// flush_standard_output_streams();
	abort();
}

void configure_logging()
{
	Log::set_threshold(Log::trace);
	string const log_name =
		"/tmp/" + wx_to_std8(Application::application_name()) + ".log";
	ofstream* f = new ofstream(log_name.c_str());
	Log::set_stream(f);  // Note Log will take care of the memory.
	return;
}

int main(int argc, char** argv)
{
	try
	{
		configure_logging();

		JEWEL_LOG_TRACE();

		std::set_terminate(my_terminate_handler);

		// Enable exceptions on standard output streams....
		// On second thought, let's not do this. What if some distant
		// library function writes to std::cerr for example in its
		// destructor, for some reason, relying on this action being
		// exception-safe? Let's keep the standard behaviour
		// (i.e. let's comment out the below).
		// cout.exceptions(std::ios::badbit | std::ios::failbit);
		// clog.exceptions(std::ios::badbit | std::ios::failbit);
		// cerr.exceptions(std::ios::badbit | std::ios::failbit);

		// Prevent multiple instances run by the same user
		bool another_is_running = false;
		wxString const app_name = Application::application_name();
		wxString const instance_identifier =
			app_name +
			wxString::Format("-%s", wxGetUserId().c_str());
		scoped_ptr<wxSingleInstanceChecker> const m_checker
		(	new wxSingleInstanceChecker(instance_identifier)
		);
		if (m_checker->IsAnotherRunning())
		{
			another_is_running = true;
			// to which we will respond below
		}

		// Process command line arguments
		CmdLine cmd(wx_to_std8(Application::application_name()));
		UnlabeledValueArg<string> filepath_arg
		(	"FILE",
			"File to open or create",
			false,
			"",
			"string"
		);
		cmd.add(filepath_arg);
		cmd.parse(argc, argv);
		string const filepath_str = filepath_arg.getValue();
		GraphicalSession graphical_session;
		if (another_is_running)
		{
			// We tell the GraphicalSession of an existing instance
			// so that it can this session with a graphical
			// message box, which it can only do after wxWidgets'
			// initialization code has run.
			graphical_session.notify_existing_application_instance();
		}
		// Note phatbooks::Session currently requires a std::string to
		// be passed here.
		// TODO This may require a wstring or wxString if we want to
		// support non-ASCII filenames on Windows. We would need to
		// change the interface with phatbooks::Session.
		if (filepath_str.empty())
		{
			return graphical_session.run();
		}
		assert (!filepath_str.empty());
		return graphical_session.run(filepath_str);
	}
	catch (ArgException& e)
	{
		cerr << "error: " << e.error() << " for arg " << e.argId() << endl;
		flush_standard_output_streams();
		return 1;
	}
	// This seems pointless but is necessary to guarantee the stack is fully
	// unwound if an exception is thrown (not JUST to flush the standard
	// output streams).
	catch (...)
	{
		flush_standard_output_streams();
		throw;
	}
}

<commit_msg>Updated for new interface with jewel::Log.<commit_after>// Copyright (c) 2013, Matthew Harvey. All rights reserved.

/** \file main.cpp
 *
 * \brief Contains main function, and possibly some small amount
 * of other code, relating to Phatbooks application.
 *
 * \author Matthew Harvey
 * \date 04 July 2012.
 *
 * Copyright (c) 2012, Matthew Harvey. All rights reserved.
 */

// TODO HIGH PRIORITY Tooltips aren't showing on Windows.

// TODO It must be easy for the user to send in an error report.
// One way is to implement "proper core dumping" on crash. An easy
// way is to have a logging statement at the beginning of, like,
// every function, that logs the source filepath and the line number,
// writing these to a logging stream (which need only be flushed at
// intervals). There could be runtime switch that turns logging on or
// off, which the user could switch on or off via a config file or in
// preferences in the GUI (though the config file might be necessary in
// the case the application is crashing on startup and the user can't even
// access the preferences). There could also be a preprocessor switch to
// disable this logging completely to avoid even having to check the switch.
// We could turn off the preprocessor switch on some future release
// if it ever became a performance problem. A nice side effect of this
// approach is that it would also assist me in everyday debugging. (But
// can this ever be better than just using GDB? Yes - because GDB so
// often gives poor information because, for example, some library
// is missing or etc.. If I have manual logging, then I KNOW it will
// print to log, and also it means I can enable or disable

// TODO Make the installer create an association on the user's system
// between the Phatbooks file extension and the Phatbooks application.
// See CMake book, page. 162.

// TODO (For GUI). Users will probably expect
// right-clicking to cause a context-dependent menu to pop up.

// TODO The application should automatically create a zipped backup
// file so that the session can be recovered if something goes wrong.

// TODO The database file should perhaps have a checksum to guard
// against its contents changing other than via the application.

// TODO Facilitate automatic checking for updates from user's
// machine, as well as easy process for providing updates
// via NSIS. It appears that the default configuration of CPack/NSIS is
// such that updates will not overwrite existing files. Some manual NSIS
// scripting may be required to enable this. Also take into account that
// the user may have to restart their computer in the event that they have
// files open while the installer (or "updater") is running (although I
// \e think that the default configuration under CPack does this
// automatically).

// TODO Write the licence.

// TODO Ensure that option for the user to lauch directly from the
// installer, works correctly.

// TODO Create a decent icon for the application. We want this
// in both .ico form (for Windows executable icon) and .xpm
// form (for icon for Frame). Note, when I exported my
// "token icon" using GIMP to .ico format, and later used this
// to create a double-clickable icon in Windows, only the text
// on the icon appeared, and the background image became
// transparent for some reason. Furthermore, when set as the
// large in-windows icon in the CPack/NSIS installer, the icon
// wasn't showing at all.

// TODO On Fedora, recompile and install wxWidgets with an additional
// configure flag, viz. --with-gnomeprint (sp?).

// TODO Set the version number in a single location and find a way
// to ensure this is reflected consistently everywhere it appears
// (website, installer, licence text etc.).

// TODO We need a proper solution to the potential for integer overflow.
// Mostly we use jewel::Decimal arithmetic - which will throw if unsafe -
// but we're not actually handling these exceptions for the user. The
// program would just crash.

// TODO HIGH PRIORITY Make the GUI display acceptably on smaller screen
// i.e. laptop.

#include "application.hpp"
#include "string_conv.hpp"
#include "graphical_session.hpp"
#include <boost/scoped_ptr.hpp>
#include <jewel/assert.hpp>
#include <jewel/log.hpp>
#include <tclap/CmdLine.h>
#include <wx/log.h>
#include <wx/snglinst.h>
#include <wx/string.h>
#include <wx/utils.h>
#include <cassert>
#include <cstdlib>
#include <exception>
#include <fstream>
#include <ios>
#include <iostream>
#include <string>

using boost::scoped_ptr;
using jewel::Log;
using phatbooks::Application;
using phatbooks::gui::GraphicalSession;
using phatbooks::wx_to_std8;
using std::abort;
using std::cerr;
using std::clog;
using std::cout;
using std::endl;
using std::ofstream;
using std::string;
using std::set_terminate;
using TCLAP::ArgException;
using TCLAP::CmdLine;
using TCLAP::UnlabeledValueArg;

void flush_standard_output_streams()
{
	cerr.flush();
	clog.flush();
	cout.flush();
	return;
}

void my_terminate_handler()
{
	// TODO HIGH PRIORITY This seems like a good idea, but is there
	// a hidden catch? (Custom terminate handling should not be done
	// lightly...)
	// flush_standard_output_streams();
	abort();
}

void configure_logging()
{
	Log::set_threshold(Log::trace);
	string const log_name =
		"/tmp/" + wx_to_std8(Application::application_name()) + ".log";
	Log::set_filepath(log_name);
	return;
}

int main(int argc, char** argv)
{
	try
	{
		configure_logging();

		JEWEL_LOG_TRACE();

		std::set_terminate(my_terminate_handler);

		// Enable exceptions on standard output streams....
		// On second thought, let's not do this. What if some distant
		// library function writes to std::cerr for example in its
		// destructor, for some reason, relying on this action being
		// exception-safe? Let's keep the standard behaviour
		// (i.e. let's comment out the below).
		// cout.exceptions(std::ios::badbit | std::ios::failbit);
		// clog.exceptions(std::ios::badbit | std::ios::failbit);
		// cerr.exceptions(std::ios::badbit | std::ios::failbit);

		// Prevent multiple instances run by the same user
		bool another_is_running = false;
		wxString const app_name = Application::application_name();
		wxString const instance_identifier =
			app_name +
			wxString::Format("-%s", wxGetUserId().c_str());
		scoped_ptr<wxSingleInstanceChecker> const m_checker
		(	new wxSingleInstanceChecker(instance_identifier)
		);
		if (m_checker->IsAnotherRunning())
		{
			another_is_running = true;
			// to which we will respond below
		}

		// Process command line arguments
		CmdLine cmd(wx_to_std8(Application::application_name()));
		UnlabeledValueArg<string> filepath_arg
		(	"FILE",
			"File to open or create",
			false,
			"",
			"string"
		);
		cmd.add(filepath_arg);
		cmd.parse(argc, argv);
		string const filepath_str = filepath_arg.getValue();
		GraphicalSession graphical_session;
		if (another_is_running)
		{
			// We tell the GraphicalSession of an existing instance
			// so that it can this session with a graphical
			// message box, which it can only do after wxWidgets'
			// initialization code has run.
			graphical_session.notify_existing_application_instance();
		}
		// Note phatbooks::Session currently requires a std::string to
		// be passed here.
		// TODO This may require a wstring or wxString if we want to
		// support non-ASCII filenames on Windows. We would need to
		// change the interface with phatbooks::Session.
		if (filepath_str.empty())
		{
			return graphical_session.run();
		}
		assert (!filepath_str.empty());
		return graphical_session.run(filepath_str);
	}
	catch (ArgException& e)
	{
		cerr << "error: " << e.error() << " for arg " << e.argId() << endl;
		flush_standard_output_streams();
		return 1;
	}
	// This seems pointless but is necessary to guarantee the stack is fully
	// unwound if an exception is thrown (not JUST to flush the standard
	// output streams).
	catch (...)
	{
		flush_standard_output_streams();
		throw;
	}
}

<|endoftext|>


<commit_before>/**
Copyright 2013 PotcFdk

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
**/

#include <aes.hpp>

using namespace std;

int main()
{
    AES * aes = new AES();

    uint8_t in [] = {0, 0, 0, 0,
                     0, 0, 0, 0,
                     0, 0, 0, 0,
                     0, 0, 0, 0
                    };

    uint8_t key [] = {0xde, 0xca, 0xde, 0xca,
                      0xad, 0xfe, 0xad, 0xfe,
                      0xbe, 0xba, 0xbe, 0xba,
                      0xef, 0xbe, 0xef, 0xbe
                     };

    aes->setData(in);
    aes->setKey(key);

    //aes->encrypt(); // Shows ciphertext only.
    aes->verboseEncrypt(); // Shows all encryption steps.

    return 0;
}
<commit_msg>Removed unnecessary line.<commit_after>/**
Copyright 2013 PotcFdk

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
**/

#include <aes.hpp>

int main()
{
    AES * aes = new AES();

    uint8_t in [] = {0, 0, 0, 0,
                     0, 0, 0, 0,
                     0, 0, 0, 0,
                     0, 0, 0, 0
                    };

    uint8_t key [] = {0xde, 0xca, 0xde, 0xca,
                      0xad, 0xfe, 0xad, 0xfe,
                      0xbe, 0xba, 0xbe, 0xba,
                      0xef, 0xbe, 0xef, 0xbe
                     };

    aes->setData(in);
    aes->setKey(key);

    //aes->encrypt(); // Shows ciphertext only.
    aes->verboseEncrypt(); // Shows all encryption steps.

    return 0;
}
<|endoftext|>


<commit_before>1f4046dc-2748-11e6-ad6e-e0f84713e7b8<commit_msg>No longer crashes if X<commit_after>1f4b08f3-2748-11e6-ac3d-e0f84713e7b8<|endoftext|>


<commit_before>#include <iostream>
#include "Maze.h"
#include "MazeDefinitions.h"
#include "PathFinder.h"

/**
 * Demo of a PathFinder implementation.
 *
 * Do not use a left/right wall following algorithm, as most
 * Micromouse mazes are designed for such algorithms to fail.
 */
class LeftWallFollower : public PathFinder {
    // Helps us determine that we should go forward if we have just turned left.
    bool shouldGoForward = false;

    // Helps us determine if we've made a loop around the maze without finding the center.
    bool visitedStart = false;

    bool isAtCenter(unsigned x, unsigned y) const {
        unsigned midpoint = MazeDefinitions::MAZE_LEN / 2;

        if(MazeDefinitions::MAZE_LEN % 2 != 0) {
            return x == midpoint && y == midpoint;
        }

        return  (x == midpoint     && y == midpoint    ) ||
                (x == midpoint - 1 && y == midpoint    ) ||
                (x == midpoint     && y == midpoint - 1) ||
                (x == midpoint - 1 && y == midpoint - 1);
    }

    MouseMovement nextMovement(unsigned x, unsigned y, const Maze &maze) {
        const bool frontWall = maze.wallInFront();
        const bool leftWall  = maze.wallOnLeft();

        std::cout << maze.draw() << std::endl << std::endl;

        // If we somehow miraculously hit the center
        // of the maze, just terminate and celebrate!
        if(isAtCenter(x, y)) {
            return Finish;
        }

        // If we hit the start of the maze a second time, then
        // we couldn't find the center and never will...
        if(x == 0 && y == 0) {
            if(visitedStart) {
                return Finish;
            } else {
                visitedStart = true;
            }
        }

        // If we have just turned left, we should take that path!
        if(!frontWall && shouldGoForward) {
            shouldGoForward = false;
            return MoveForward;
        }

        // As long as nothing is in front and we have
        // a wall to our left, keep going forward!
        if(!frontWall && leftWall) {
            shouldGoForward = false;
            return MoveForward;
        }

        // If our forward and left paths are blocked
        // we should try going to the right!
        if(frontWall && leftWall) {
            shouldGoForward = false;
            return TurnClockwise;
        }

        // Lastly, if there is no left wall we should take that path!
        if(!leftWall) {
            shouldGoForward = true;
            return TurnCounterClockwise;
        }

        // If we get stuck somehow, just terminate.
        return Finish;
    }
};

int main(int argc, const char * argv[]) {
    LeftWallFollower leftWallFollower;
    Maze maze(MazeDefinitions::MAZE_CAMM_2012, &leftWallFollower);
    std::cout << maze.draw() << std::endl << std::endl;

    maze.start();
    std::cout << maze.draw() << std::endl << std::endl;
}
<commit_msg>Add some command line options for testing outside of an IDE<commit_after>#include <iostream>
#include <unistd.h> // getopt

#include "Maze.h"
#include "MazeDefinitions.h"
#include "PathFinder.h"

/**
 * Demo of a PathFinder implementation.
 *
 * Do not use a left/right wall following algorithm, as most
 * Micromouse mazes are designed for such algorithms to fail.
 */
class LeftWallFollower : public PathFinder {
public:
    LeftWallFollower(bool shouldPause = false) : pause(shouldPause) {}

    MouseMovement nextMovement(unsigned x, unsigned y, const Maze &maze) {
        const bool frontWall = maze.wallInFront();
        const bool leftWall  = maze.wallOnLeft();

        // Pause at each cell if the user requests it.
        // It allows for better viewing on command line.
        if(pause) {
            std::cout << "Hit enter to continue..." << std::endl;
            std::cin.ignore(10000, '\n');
            std::cin.clear();
        }

        std::cout << maze.draw() << std::endl << std::endl;

        // If we somehow miraculously hit the center
        // of the maze, just terminate and celebrate!
        if(isAtCenter(x, y)) {
            return Finish;
        }

        // If we hit the start of the maze a second time, then
        // we couldn't find the center and never will...
        if(x == 0 && y == 0) {
            if(visitedStart) {
                return Finish;
            } else {
                visitedStart = true;
            }
        }

        // If we have just turned left, we should take that path!
        if(!frontWall && shouldGoForward) {
            shouldGoForward = false;
            return MoveForward;
        }

        // As long as nothing is in front and we have
        // a wall to our left, keep going forward!
        if(!frontWall && leftWall) {
            shouldGoForward = false;
            return MoveForward;
        }

        // If our forward and left paths are blocked
        // we should try going to the right!
        if(frontWall && leftWall) {
            shouldGoForward = false;
            return TurnClockwise;
        }

        // Lastly, if there is no left wall we should take that path!
        if(!leftWall) {
            shouldGoForward = true;
            return TurnCounterClockwise;
        }

        // If we get stuck somehow, just terminate.
        return Finish;
    }

protected:
    // Helps us determine that we should go forward if we have just turned left.
    bool shouldGoForward = false;

    // Helps us determine if we've made a loop around the maze without finding the center.
    bool visitedStart = false;

    // Indicates we should pause before moving to next cell.
    // Useful for command line usage.
    bool pause = false;

    bool isAtCenter(unsigned x, unsigned y) const {
        unsigned midpoint = MazeDefinitions::MAZE_LEN / 2;

        if(MazeDefinitions::MAZE_LEN % 2 != 0) {
            return x == midpoint && y == midpoint;
        }

        return  (x == midpoint     && y == midpoint    ) ||
        (x == midpoint - 1 && y == midpoint    ) ||
        (x == midpoint     && y == midpoint - 1) ||
        (x == midpoint - 1 && y == midpoint - 1);
    }
};

int main(int argc, char * argv[]) {
    MazeDefinitions::MazeEncodingName mazeName = MazeDefinitions::MAZE_CAMM_2012;
    bool pause = false;

    int opt;
    opterr = 0;

    while((opt = getopt(argc, argv, "m:ph")) != -1) {
        switch(opt) {
            case 'm': {
                int mazeOption = atoi(optarg);
                if(mazeOption < MazeDefinitions::MAZE_NAME_MAX && mazeOption > 0) {
                    mazeName = (MazeDefinitions::MazeEncodingName)mazeOption;
                }
                break;
            }

            case 'p':
                pause = true;
                break;

            case 'h':
            default:
                std::cout << "Usage: " << argv[0] << " [-m N] [-p]" << std::endl;
                std::cout << "\t-m N will load the maze corresponding to N, or 0 if invalid N or missing option" << std::endl;
                std::cout << "\t-p will wait for a newline in between cell traversals" << std::endl;
                return -1;
        }
    }

    LeftWallFollower leftWallFollower(pause);
    Maze maze(mazeName, &leftWallFollower);
    std::cout << maze.draw() << std::endl << std::endl;

    maze.start();
    std::cout << maze.draw() << std::endl << std::endl;
}
<|endoftext|>


<commit_before>b57ed035-2747-11e6-90f3-e0f84713e7b8<commit_msg>I'm done<commit_after>b58e1ec5-2747-11e6-9cad-e0f84713e7b8<|endoftext|>


<commit_before>// small-radiosity by Magnus Burenius
#include <algorithm>
#include <functional>
#include <numeric>
#include <random>
#include <valarray>
#include <fstream>
#include <iostream>
#include <sstream>
using namespace std;
// Fast settings:
const auto S            = 20;		    // Number of patches per rect is S*S.			// SCENE
const auto PHOTONS      = 10000;	    // 300000;//30000;	// Number of particles used for each color component	// COMPUTE RADIOSITY
const auto DRAW_SAMPLES = 20;		    // Number of gaussian samples used for drawing.	// RENDERING
const auto WIDTH        = 250.0;		// Width of image		// RENDERING
const auto HEIGHT       = 250.0;		// Height of image		// RENDERING
// Slow settings:
//const auto S            = 64;//30;    // Number of patches per rect is S*S.
//const auto PHOTONS      = 100000000;  // Number of particles used for each color component
//const auto DRAW_SAMPLES = 100;        // Number of gaussian samples used for drawing.
//const auto WIDTH        = 4096.0;     // Width of image
//const auto HEIGHT       = 4096.0;     // Height of image
auto g = bind(      normal_distribution<double>(), mt19937());
auto u = bind(uniform_real_distribution<double>(), mt19937());
// Definition of vector type:
using vec = valarray<double>;
double dot(vec a, vec b)
{
    return (a * b).sum();
}
vec normalized(vec v)
{
    return v / sqrt(dot(v, v));
}
vec crossProduct(vec x, vec y)
{
    return vec{x[1]*y[2]-x[2]*y[1], x[2]*y[0]-x[0]*y[2], x[0]*y[1]-x[1]*y[0]};
}
// Used to describe the geometrical properties of a rectangular surface:
struct Rect
{
    vec p;      // A corner in the rectangle.
    vec x;      // Vector going from p to the right nearby corner.
    vec y;      // Vector going from p to the top nearby corner.
    vec n;      // Normal of the plane. The cross product of x and y.
    vec xn;     // normalized(x).
    vec yn;     // normalized(y).
    vec nn;     // normalized(n).
    double a;   // Area of rectangle. Given by length of x cross y.
    Rect(vec P, vec X, vec Y) : p{P}, x{X}, y{Y}, n{crossProduct(x, y)},
        xn{normalized(x)}, yn{normalized(y)}, nn{normalized(n)}, a{sqrt(dot(n, n))} {}
};
const auto L = 555.0; // Length of Cornell Box side.
struct Scene // Define the Cornell box:
{
    static const auto NUM_RECTANGLES = 15;
    static const auto NUM_PATCHES = NUM_RECTANGLES * S * S;

    Rect rectangles[NUM_RECTANGLES] = {
        Rect{ vec{ 0, 0, 0 }, vec{  0, 0, L }, vec{ L, 0, 0 } },    // Floor
        Rect{ vec{ 0, L, 0 }, vec{  L, 0, 0 }, vec{ 0, 0, L } },    // Ceiling
        Rect{ vec{ L, 0, L }, vec{ -L, 0, 0 }, vec{ 0, L, 0 } },	    // Back wall
        Rect{ vec{ 0, 0, 0 }, vec{  0, L, 0 }, vec{ 0, 0, L } },    // Right wall
        Rect{ vec{ L, 0, 0 }, vec{  0, 0, L }, vec{ 0, L, 0 } },    // Left wall
        // Tall block:
        Rect{ vec{ 314, 330, 454 }, vec{  158, 0,  -49 }, vec{ -49,   0, -158 } },
        Rect{ vec{ 314,   0, 454 }, vec{  158, 0,  -49 }, vec{   0, 330,    0 } },
        Rect{ vec{ 423,   0, 247 }, vec{ -158, 0,   49 }, vec{   0, 330,    0 } },
        Rect{ vec{ 265,   0, 296 }, vec{   49, 0,  158 }, vec{   0, 330,    0 } },
        Rect{ vec{ 472,   0, 405 }, vec{  -49, 0, -158 }, vec{   0, 330,    0 } },
        // Short block:
        Rect{ vec{  81, 165, 223 }, vec{  158, 0,   49 }, vec{  49,   0, -158 } },
        Rect{ vec{  81,   0, 223 }, vec{  158, 0,   49 }, vec{   0, 165,    0 } },
        Rect{ vec{ 288,   0, 114 }, vec{ -158, 0,  -49 }, vec{   0, 165,    0 } },
        Rect{ vec{ 130,   0,  65 }, vec{  -49, 0,  158 }, vec{   0, 165,    0 } },
        Rect{ vec{ 239,   0, 272 }, vec{   49, 0, -158 }, vec{   0, 165,    0 } } };

    // The color quantities for each patch:
    // TODO: rename?
    valarray<vec> R{ .75 * vec{ 1, 1, 1 }, NUM_PATCHES }; // Reflectance for each patch
    valarray<vec> B{       vec{ 0, 0, 0 }, NUM_PATCHES }; // Radiosity for each patch

    vec lightPos   =    L * vec{ .5, .8, .5 };
    vec lightPower = 1e11 * vec{  1,  1,  1 };

    Scene()
    {
        fill(&R[3 * S * S], &R[4 * S * S], vec{ .25, .75, .25 }); // Color right wall
        fill(&R[4 * S * S], &R[5 * S * S], vec{ .75, .25, .25 }); // Color left wall
    }
};
// Information about an intersection between a ray and a Rect:
struct Intersection
{
    double distance;
    double u; // 0-1 coordinate of the intersection within the rectangle.
    double v; // 0-1 coordinate of the intersection within the rectangle.
    vec position;
    int rectangleIndex;
    Intersection() : distance{numeric_limits<double>::max()} {}
    operator bool() const { return distance < numeric_limits<double>::max(); }
};
// Compute the first intersection along a ray:
Intersection ComputeIntersection(const Scene& scene, vec start, vec dir)
{
    const auto e = 0.0001;
    start += e * dir;
    dir = normalized(dir);
    auto firstIntersection = Intersection();
    for (auto r = 0; r < Scene::NUM_RECTANGLES; ++r)
    {
        const auto& rectangle = scene.rectangles[r];
        auto i = Intersection();
        i.distance = dot(rectangle.p - start, rectangle.nn) / dot(dir, rectangle.nn);
        if (i.distance < 0 || firstIntersection.distance < i.distance)
            continue;
        i.rectangleIndex = r;
        i.position = start + i.distance * dir;
        const auto p = i.position - rectangle.p;
        i.u = dot(p, rectangle.x) / dot(rectangle.x, rectangle.x);
        i.v = dot(p, rectangle.y) / dot(rectangle.y, rectangle.y);
        if (0 - e < i.u && i.u < 1 + e && 0 - e < i.v && i.v < 1 + e)
            firstIntersection = i;
    }
    return firstIntersection;
}
int RectToPatch(int rect_index, int rect_patch_u, int rect_path_v)
{
    return rect_patch_u + rect_path_v * S + rect_index * S * S;
}
// Get patch index of an intersection, with an optional u and v offset:
int Patch(const Intersection& i, double du = 0, double dv = 0)
{
    const auto rect_path_u = max(min(int((i.u + du) * S), S - 1), 0);
    const auto rect_path_v = max(min(int((i.v + dv) * S), S - 1), 0);
    return RectToPatch(i.rectangleIndex, rect_path_u, rect_path_v);
}
// Get an "interpolated" value for the radiosity using gaussian samples:
vec Radiosity(const Scene& scene, const Intersection& i)
{
    auto r = vec{0, 0, 0};
    if (!i)
        return r;
    //return B[Patch(i)]; // No interpolation
    // Gaussian filter:
    const auto DRAW_STD = 0.5 / S; // STD of gaussian filter.
    for (auto s = 0; s < DRAW_SAMPLES; ++s)
        r += scene.B[Patch(i, DRAW_STD * g(), DRAW_STD * g())];
    return r / double(DRAW_SAMPLES);
}
vec RandomDiffuseReflectionDirection(vec tangent1, vec tangent2, vec normal)
{
    const auto a = u();
    const auto dir = sqrt(a) * normalized(vec{g(), g(), 0}) + vec{0, 0, sqrt(1 - a)};
    return tangent1 * dir[0] + tangent2 * dir[1] + normal * dir[2];
}
vec RandomDirection()
{
    return normalized(vec{ g(), g(), g() });
}
bool PhotonIsAbsorbed(double reflectance)
{
    return u() > reflectance;
}
const auto NUM_COLOR_CHANNELS = 3;
// Compute the radiosity of the scene by bouncing around photons.
void ComputeRadiosity(Scene& scene)
{
    for (auto c = 0; c < NUM_COLOR_CHANNELS; ++c)
    {
        for (auto p = 0; p < PHOTONS; ++p)
        {
            auto ray_dir = RandomDirection();
            auto ray_start = scene.lightPos;
            auto i = ComputeIntersection(scene, ray_start, ray_dir);
            while (i && !PhotonIsAbsorbed(scene.R[Patch(i)][c]))
            {
                const auto& r = scene.rectangles[i.rectangleIndex];
                scene.B[Patch(i)][c] += scene.lightPower[c] / PHOTONS * S * S / r.a;
                ray_dir = RandomDiffuseReflectionDirection(r.xn, r.yn, r.nn);
                ray_start = i.position;
                i = ComputeIntersection(scene, ray_start, ray_dir);
            }
        }
    }
}
// Do gamma correction and truncation of color:
int ScreenColor(double c)
{
    return min(int(pow(c, 1 / 2.2)), 255);
}
// Render the image to a ppm-file:
void Render(const Scene& scene, vec cameraPos, double focalLength, const char* filename)
{
    ofstream file(filename);
    file << "P3\n" << int(WIDTH) << " " << int(HEIGHT) << "\n255\n";
    for (auto y = 0.0; y < HEIGHT; ++y)
    {
        for (auto x = 0.0; x < WIDTH; ++x)
        {
            const auto rayDir = vec{WIDTH / 2 - x, HEIGHT / 2 - y, focalLength};
            const auto color = Radiosity(scene, ComputeIntersection(scene, cameraPos, rayDir));
            for (auto c = 0; c < NUM_COLOR_CHANNELS; ++c)
                file << ScreenColor(color[c]) << " ";
        }
    }
}
void SaveLightmaps(const Scene& scene, const char* fileNameStart)
{
    for (auto r = 0; r < Scene::NUM_RECTANGLES; ++r)
    {
        auto ss = stringstream();
        ss << fileNameStart << r << ".ppm";
        auto file = ofstream(ss.str());
        file << "P3" << endl << S << " " << S << endl << 255 << endl;
        for (auto y = 0; y < S; ++y)
        {
            for (auto x = 0; x < S; ++x)
            {
                const auto color = scene.B[RectToPatch(r, x, y)];
                for (auto c = 0; c < NUM_COLOR_CHANNELS; ++c)
                    file << ScreenColor(color[c]) << " ";
            }
        }
    }
}
// Here we go:
int main()
{
    auto scene = Scene();
    cout << "Computing radiosity." << endl;
    ComputeRadiosity(scene);
    cout << "Saving lightmaps to files." << endl;
    SaveLightmaps(scene, "lightmap");
    cout << "Rendering image to file." << endl;
    const auto focalLength = 1.4 * WIDTH;
    const auto cameraPos = L * vec{.5, .5, -1.4};
    Render(scene, cameraPos, focalLength, "image.ppm");
}

//void LoadLightmaps()
//{
//	for(size_t q=0; q<Q;++q)
//	{
//		stringstream ss;
//		ss << "lightmaps30/lightmap" << q << ".ppm";
//		ifstream f( ss.str() );
//		string temp;
//		size_t w,h,color;
//		f >> temp >> w >> h >> color;
//		for( size_t y=0; y<S; ++y )
//		{
//			for( size_t x=0; x<S; ++x )
//			{
//				vec color = vec{0,0,0);
//				for( int c=0; c<3; ++c )
//					f >> color[c];
//				B[QuadToPatch(q,x,y)] = 700.*color; // N.B. truncated over 255
//			}
//		}
//	}
//}

//void LoadLightmaps()
//{
//	for(size_t q=0; q<Q;++q)
//	{
//		stringstream ss;
//		ss << "lightmap" << q << ".ppm";
//		ifstream f( ss.str() );
//		string temp;
//		size_t w,h,color;
//		f >> temp >> w >> h >> color;
//		for( size_t y=0; y<S; ++y )
//		{
//			for( size_t x=0; x<S; ++x )
//			{
//				vec color = vec{0,0,0);
//				for( int c=0; c<3; ++c )
//					f >> color[c];
//				radiosity[QuadToPatch(q,x,y)] = color; // N.B. truncated over 255
//			}
//		}
//	}
//}
<commit_msg>Make C++ more readable.<commit_after>// small-radiosity by Magnus Burenius
#include <algorithm>
#include <functional>
#include <numeric>
#include <random>
#include <valarray>
#include <fstream>
#include <iostream>
#include <sstream>
using namespace std;
// Fast settings:
const auto S            = 20;		    // Number of patches per rect is S*S.			// SCENE
const auto PHOTONS      = 10000;	    // 300000;//30000;	// Number of particles used for each color component	// COMPUTE RADIOSITY
const auto DRAW_SAMPLES = 20;		    // Number of gaussian samples used for drawing.	// RENDERING
const auto WIDTH        = 250.0;		// Width of image		// RENDERING
const auto HEIGHT       = 250.0;		// Height of image		// RENDERING
// Slow settings:
//const auto S            = 64;//30;    // Number of patches per rect is S*S.
//const auto PHOTONS      = 100000000;  // Number of particles used for each color component
//const auto DRAW_SAMPLES = 100;        // Number of gaussian samples used for drawing.
//const auto WIDTH        = 4096.0;     // Width of image
//const auto HEIGHT       = 4096.0;     // Height of image
auto g = bind(      normal_distribution<double>(), mt19937());
auto u = bind(uniform_real_distribution<double>(), mt19937());
// Definition of vector type:
using vec = valarray<double>;
double dot(vec a, vec b)
{
    return (a * b).sum();
}
double norm(vec a)
{
    return sqrt(dot(a, a));
}
vec normalized(vec a)
{
    return a / norm(a);
}
vec crossProduct(vec a, vec b)
{
    return vec{a[1]*b[2]-a[2]*b[1], a[2]*b[0]-a[0]*b[2], a[0]*b[1]-a[1]*b[0]};
}
// Used to describe the geometrical properties of a rectangular surface:
struct Rect
{
    vec p;      // A corner in the rectangle.
    vec x;      // Vector going from p to the right nearby corner.
    vec y;      // Vector going from p to the top nearby corner.
    vec n;      // Normal of the plane. The cross product of x and y.
    vec xn;     // normalized(x).
    vec yn;     // normalized(y).
    vec nn;     // normalized(n).
    double a;   // Area of rectangle. Given by length of x cross y.
    Rect(vec P, vec X, vec Y) : p{P}, x{X}, y{Y}, n{crossProduct(x, y)},
        xn{normalized(x)}, yn{normalized(y)}, nn{normalized(n)}, a{ norm(n)} {}
};
const auto L = 555.0; // Length of Cornell Box side.
const auto BLACK = vec{ 0, 0, 0 };
const auto WHITE = vec{ .75, .75, .75 };
const auto RED   = vec{ .75, .25, .25 };
const auto GREEN = vec{ .25, .75, .25 };
struct Scene // Define the Cornell box:
{
    static const auto NUM_RECTANGLES = 15;
    static const auto NUM_PATCHES = NUM_RECTANGLES * S * S;

    static int rectToPatch(int rect_index, int rect_patch_u, int rect_path_v)
    {
        return rect_patch_u + rect_path_v * S + rect_index * S * S;
    }

    Rect rectangles[NUM_RECTANGLES] = {
        Rect{ vec{ 0, 0, 0 }, vec{  0, 0, L }, vec{ L, 0, 0 } },    // Floor
        Rect{ vec{ 0, L, 0 }, vec{  L, 0, 0 }, vec{ 0, 0, L } },    // Ceiling
        Rect{ vec{ L, 0, L }, vec{ -L, 0, 0 }, vec{ 0, L, 0 } },	// Back wall
        Rect{ vec{ 0, 0, 0 }, vec{  0, L, 0 }, vec{ 0, 0, L } },    // Right wall
        Rect{ vec{ L, 0, 0 }, vec{  0, 0, L }, vec{ 0, L, 0 } },    // Left wall
        // Tall block:
        Rect{ vec{ 314, 330, 454 }, vec{  158, 0,  -49 }, vec{ -49,   0, -158 } },
        Rect{ vec{ 314,   0, 454 }, vec{  158, 0,  -49 }, vec{   0, 330,    0 } },
        Rect{ vec{ 423,   0, 247 }, vec{ -158, 0,   49 }, vec{   0, 330,    0 } },
        Rect{ vec{ 265,   0, 296 }, vec{   49, 0,  158 }, vec{   0, 330,    0 } },
        Rect{ vec{ 472,   0, 405 }, vec{  -49, 0, -158 }, vec{   0, 330,    0 } },
        // Short block:
        Rect{ vec{  81, 165, 223 }, vec{  158, 0,   49 }, vec{  49,   0, -158 } },
        Rect{ vec{  81,   0, 223 }, vec{  158, 0,   49 }, vec{   0, 165,    0 } },
        Rect{ vec{ 288,   0, 114 }, vec{ -158, 0,  -49 }, vec{   0, 165,    0 } },
        Rect{ vec{ 130,   0,  65 }, vec{  -49, 0,  158 }, vec{   0, 165,    0 } },
        Rect{ vec{ 239,   0, 272 }, vec{   49, 0, -158 }, vec{   0, 165,    0 } } };

    // The color quantities for each patch:
    valarray<vec> reflectance{ WHITE, NUM_PATCHES }; // Reflectance for each patch
    valarray<vec>   radiosity{ BLACK, NUM_PATCHES }; // Radiosity for each patch

    Scene()
    {
        fill(&reflectance[rectToPatch(3, 0, 0)], &reflectance[rectToPatch(4, 0, 0)], GREEN); // Color right wall
        fill(&reflectance[rectToPatch(4, 0, 0)], &reflectance[rectToPatch(5, 0, 0)], RED); // Color left wall
    }
};
struct Light
{
    vec position = L * vec{ .5, .8, .5 };
    vec power = 1e11 * vec{ 1,  1,  1 };
};
struct Camera
{
    vec position = L * vec{ .5, .5, -1.4 };
    double focalLength = 1.4 * WIDTH;
};
// Information about an intersection between a ray and a Rect:
struct Intersection
{
    double distance;
    double u; // 0-1 coordinate of the intersection within the rectangle.
    double v; // 0-1 coordinate of the intersection within the rectangle.
    vec position;
    int rectangleIndex;
    Intersection() : distance{numeric_limits<double>::max()} {}
    operator bool() const { return distance < numeric_limits<double>::max(); }
};
// Compute the first intersection along a ray:
Intersection findIntersection(const Scene& scene, vec start, vec dir)
{
    const auto e = 0.0001;
    start += e * dir;
    dir = normalized(dir);
    auto firstIntersection = Intersection();
    for (auto r = 0; r < Scene::NUM_RECTANGLES; ++r)
    {
        const auto& rectangle = scene.rectangles[r];
        auto i = Intersection();
        i.distance = dot(rectangle.p - start, rectangle.nn) / dot(dir, rectangle.nn);
        if (i.distance < 0 || firstIntersection.distance < i.distance)
            continue;
        i.rectangleIndex = r;
        i.position = start + i.distance * dir;
        const auto p = i.position - rectangle.p;
        i.u = dot(p, rectangle.x) / dot(rectangle.x, rectangle.x);
        i.v = dot(p, rectangle.y) / dot(rectangle.y, rectangle.y);
        if (0 - e < i.u && i.u < 1 + e && 0 - e < i.v && i.v < 1 + e)
            firstIntersection = i;
    }
    return firstIntersection;
}
// Get patch index of an intersection, with an optional u and v offset:
int patchIndex(const Intersection& i, double du = 0, double dv = 0)
{
    const auto rect_path_u = max(min(int((i.u + du) * S), S - 1), 0);
    const auto rect_path_v = max(min(int((i.v + dv) * S), S - 1), 0);
    return Scene::rectToPatch(i.rectangleIndex, rect_path_u, rect_path_v);
}
// Get an "interpolated" value for the radiosity using gaussian samples:
vec sampleRadiosity(const Scene& scene, const Intersection& i)
{
    auto r = BLACK;
    if (!i)
        return r;
    //return B[patchIndex(i)]; // No interpolation
    // Gaussian filter:
    const auto DRAW_STD = 0.5 / S; // STD of gaussian filter.
    for (auto s = 0; s < DRAW_SAMPLES; ++s)
        r += scene.radiosity[patchIndex(i, DRAW_STD * g(), DRAW_STD * g())];
    return r / double(DRAW_SAMPLES);
}
vec randomDirection()
{
    return normalized(vec{ g(), g(), g() });
}
vec randomDiffuseReflectionDirection(vec tangent1, vec tangent2, vec normal)
{
    const auto a = u();
    const auto dir = sqrt(a) * normalized(vec{g(), g(), 0}) + vec{0, 0, sqrt(1 - a)};
    return tangent1 * dir[0] + tangent2 * dir[1] + normal * dir[2];
}
bool isPhotonAbsorbed(double reflectance)
{
    return u() > reflectance;
}
const auto NUM_COLOR_CHANNELS = 3;
// Compute the radiosity of the scene by bouncing around photons.
void illuminateScene(Scene& scene, const Light& light)
{
    for (auto c = 0; c < NUM_COLOR_CHANNELS; ++c)
    {
        for (auto p = 0; p < PHOTONS; ++p)
        {
            auto ray_dir = randomDirection();
            auto ray_start = light.position;
            auto i = findIntersection(scene, ray_start, ray_dir);
            while (i && !isPhotonAbsorbed(scene.reflectance[patchIndex(i)][c]))
            {
                const auto& r = scene.rectangles[i.rectangleIndex];
                scene.radiosity[patchIndex(i)][c] += light.power[c] / PHOTONS * S * S / r.a;
                ray_dir = randomDiffuseReflectionDirection(r.xn, r.yn, r.nn);
                ray_start = i.position;
                i = findIntersection(scene, ray_start, ray_dir);
            }
        }
    }
}
// Do gamma correction and truncation of color:
int screenColor(double c)
{
    return min(int(pow(c, 1 / 2.2)), 255);
}
// Render the image to a ppm-file:
void renderCameraImage(const Scene& scene, const Camera& camera, const char* filename)
{
    ofstream file(filename);
    file << "P3" << endl << int(WIDTH) << " " << int(HEIGHT) << endl << "255" << endl;
    for (auto y = 0.0; y < HEIGHT; ++y)
    {
        for (auto x = 0.0; x < WIDTH; ++x)
        {
            const auto rayDir = vec{WIDTH / 2 - x, HEIGHT / 2 - y, camera.focalLength};
            const auto intersection = findIntersection(scene, camera.position, rayDir);
            const auto radiosity = sampleRadiosity(scene, intersection);
            for (auto c = 0; c < NUM_COLOR_CHANNELS; ++c)
                file << screenColor(radiosity[c]) << " ";
        }
    }
}
void saveLightmaps(const Scene& scene)
{
    for (auto r = 0; r < Scene::NUM_RECTANGLES; ++r)
    {
        const auto filename = "lightmap" + std::to_string(r) +  ".ppm";
        auto file = ofstream(filename);
        file << "P3" << endl << S << " " << S << endl << 255 << endl;
        for (auto y = 0; y < S; ++y)
        {
            for (auto x = 0; x < S; ++x)
            {
                const auto radiosity = scene.radiosity[scene.rectToPatch(r, x, y)];
                for (auto c = 0; c < NUM_COLOR_CHANNELS; ++c)
                    file << screenColor(radiosity[c]) << " ";
            }
        }
    }
}
int main()
{
    auto scene = Scene{};
    auto light = Light{};
    auto camera = Camera{};
    cout << "Illuminating the scene." << endl;
    illuminateScene(scene, light);
    cout << "Saving lightmaps to files." << endl;
    saveLightmaps(scene);
    cout << "Rendering camera image to file." << endl;
    renderCameraImage(scene, camera, "cameraImage.ppm");
}

//void LoadLightmaps()
//{
//	for(size_t q=0; q<Q;++q)
//	{
//		stringstream ss;
//		ss << "lightmaps30/lightmap" << q << ".ppm";
//		ifstream f( ss.str() );
//		string temp;
//		size_t w,h,color;
//		f >> temp >> w >> h >> color;
//		for( size_t y=0; y<S; ++y )
//		{
//			for( size_t x=0; x<S; ++x )
//			{
//				vec color = vec{0,0,0);
//				for( int c=0; c<3; ++c )
//					f >> color[c];
//				B[QuadToPatch(q,x,y)] = 700.*color; // N.B. truncated over 255
//			}
//		}
//	}
//}

//void LoadLightmaps()
//{
//	for(size_t q=0; q<Q;++q)
//	{
//		stringstream ss;
//		ss << "lightmap" << q << ".ppm";
//		ifstream f( ss.str() );
//		string temp;
//		size_t w,h,color;
//		f >> temp >> w >> h >> color;
//		for( size_t y=0; y<S; ++y )
//		{
//			for( size_t x=0; x<S; ++x )
//			{
//				vec color = vec{0,0,0);
//				for( int c=0; c<3; ++c )
//					f >> color[c];
//				radiosity[QuadToPatch(q,x,y)] = color; // N.B. truncated over 255
//			}
//		}
//	}
//}
<|endoftext|>


<commit_before>81915633-2749-11e6-b074-e0f84713e7b8<commit_msg>That didn't fix it<commit_after>81a5fb5c-2749-11e6-a79f-e0f84713e7b8<|endoftext|>


<commit_before>#include <iostream>
#include <bitset>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include "hckt_tree.hpp"

constexpr size_t window_width  { 512 };
constexpr size_t window_height { 512 };

int render(sf::RenderWindow & window, const hckt_tree<int> & m)
{
    for(size_t a=0; a<4; ++a) {
        for(size_t b=0; b<4; ++b) {
            for(size_t c=0; c<4; ++c) {
                if(m.empty()) {
                    continue;
                }

                auto pos = hckt_tree<int>::get_position_2d(a, b, c);
                auto value = m.get_value(pos);
                auto x = hckt_tree<int>::get_x_2d(a, b, c);
                auto y = hckt_tree<int>::get_y_2d(a, b, c);
                sf::Uint8 col = value * 20;

                sf::RectangleShape square { sf::Vector2f { 64, 64 } };
                square.setFillColor(sf::Color { col, col, col, 255 } );
                square.setPosition(64*x, 64*y);
                window.draw(square);

                for(size_t a2=0; a2<4; ++a2) {
                    for(size_t b2=0; b2<4; ++b2) {
                        for(size_t c2=0; c2<4; ++c2) {
                            if(m.leaf(pos)->empty()) {
                                continue;
                            }
                            auto subpos = hckt_tree<int>::get_position_2d(a2, b2, c2);
                            auto subvalue = m.leaf(pos)->get_value(subpos);
                            auto subx = hckt_tree<int>::get_x_2d(a2, b2, c2);
                            auto suby = hckt_tree<int>::get_y_2d(a2, b2, c2);
                            sf::Uint8 col = subvalue * 20;

                            sf::RectangleShape square { sf::Vector2f { 8, 8 } };
                            square.setFillColor(sf::Color { col, col, col, 255 } );
                            square.setPosition((64 * x) + (8 * subx), (64 * y) + (8 * suby));
                            window.draw(square);

                            for(size_t a3=0; a3<4; ++a3) {
                                for(size_t b3=0; b3<4; ++b3) {
                                    for(size_t c3=0; c3<4; ++c3) {
                                        if(m.leaf(pos)->leaf(subpos)->empty()) {
                                            continue;
                                        }
                                        auto subsubpos = hckt_tree<int>::get_position_2d(a3, b3, c3);
                                        auto subsubvalue = m.leaf(pos)->leaf(subpos)->get_value(subsubpos);

                                        auto subsubx = hckt_tree<int>::get_x_2d(a3, b3, c3);
                                        auto subsuby = hckt_tree<int>::get_y_2d(a3, b3, c3);
                                        sf::Uint8 col = subsubvalue * 20;

                                        sf::RectangleShape square { sf::Vector2f { 1, 1 } };
                                        square.setFillColor(sf::Color { col, col, col, 255 } );
                                        square.setPosition((64 * x) + (8 * subx) + (1 * subsubx), (64 * y) + (8 * suby) + (1 * subsuby));
                                        window.draw(square);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    while(1) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) {
                window.close();
                return 0;
            }
        }

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Escape)) {
            return 0;
        }

        window.display();
    }

    return 0;
}

void populate(hckt_tree<int> & m)
{
    for(size_t a=0; a<4; ++a) {
        for(size_t b=0; b<4; ++b) {
            for(size_t c=0; c<4; ++c) {
                auto pos = hckt_tree<int>::get_position_2d(a, b, c);
                m.insert(pos, a+b+c);

                if(pos % 6 == 0) {
                    for(size_t a2=0; a2<4; ++a2) {
                        for(size_t b2=0; b2<4; ++b2) {
                            for(size_t c2=0; c2<4; ++c2) {
                                auto subpos = hckt_tree<int>::get_position_2d(a2, b2, c2);
                                m.leaf(pos)->insert(subpos, a2+b2+c2);

                                if(subpos % 6 == 0) {
                                    for(size_t a3=0; a3<4; ++a3) {
                                        for(size_t b3=0; b3<4; ++b3) {
                                            for(size_t c3=0; c3<4; ++c3) {
                                                auto subsubpos = hckt_tree<int>::get_position_2d(a3, b3, c3);
                                                m.leaf(pos)->leaf(subpos)->insert(subsubpos, a3+b3+c3);

                                                if(subsubpos % 6 == 0) {
                                                    for(size_t a4=0; a4<4; ++a4) {
                                                        for(size_t b4=0; b4<4; ++b4) {
                                                            for(size_t c4=0; c4<4; ++c4) {
                                                                auto subsubsubpos = hckt_tree<int>::get_position_2d(a4, b4, c4);
                                                                m.leaf(pos)->leaf(subpos)->leaf(subsubpos)->insert(subsubsubpos, a4+b4+c4);

                                                                if(subsubsubpos % 6 == 0) {
                                                                    for(size_t a5=0; a5<4; ++a5) {
                                                                        for(size_t b5=0; b5<4; ++b5) {
                                                                            for(size_t c5=0; c5<4; ++c5) {
                                                                                auto subsubsubsubpos = hckt_tree<int>::get_position_2d(a5, b5, c5);
                                                                                m.leaf(pos)->leaf(subpos)->leaf(subsubpos)->leaf(subsubsubpos)->insert(subsubsubsubpos, a5+b5+c5);
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

int main(int argc, char ** argv)
{
    hckt_tree<int> m;
    populate(m);
    std::cout << m.calculate_memory_size() << std::endl;

    sf::RenderWindow window{{window_width, window_height}, "hckt-tree"};
    window.clear(sf::Color { 255, 255, 255, 255 } );

    return render(window, m);
}
<commit_msg>make pop & render generic<commit_after>#include <iostream>
#include <bitset>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include "hckt_tree.hpp"

constexpr size_t window_width  { 512 };
constexpr size_t window_height { 512 };

template <typename Tree>
int render(sf::RenderWindow & window, const Tree & m)
{
    for(size_t a=0; a<4; ++a) {
        for(size_t b=0; b<4; ++b) {
            for(size_t c=0; c<4; ++c) {
                if(m.empty()) {
                    continue;
                }

                auto pos = Tree::get_position_2d(a, b, c);
                auto value = m.get_value(pos);
                auto x = Tree::get_x_2d(a, b, c);
                auto y = Tree::get_y_2d(a, b, c);
                sf::Uint8 col = value * 20;

                sf::RectangleShape square { sf::Vector2f { 64, 64 } };
                square.setFillColor(sf::Color { col, col, col, 255 } );
                square.setPosition(64*x, 64*y);
                window.draw(square);

                for(size_t a2=0; a2<4; ++a2) {
                    for(size_t b2=0; b2<4; ++b2) {
                        for(size_t c2=0; c2<4; ++c2) {
                            if(m.leaf(pos)->empty()) {
                                continue;
                            }
                            auto subpos = Tree::get_position_2d(a2, b2, c2);
                            auto subvalue = m.leaf(pos)->get_value(subpos);
                            auto subx = Tree::get_x_2d(a2, b2, c2);
                            auto suby = Tree::get_y_2d(a2, b2, c2);
                            sf::Uint8 col = subvalue * 20;

                            sf::RectangleShape square { sf::Vector2f { 8, 8 } };
                            square.setFillColor(sf::Color { col, col, col, 100 } );
                            square.setPosition((64 * x) + (8 * subx), (64 * y) + (8 * suby));
                            window.draw(square);

                            for(size_t a3=0; a3<4; ++a3) {
                                for(size_t b3=0; b3<4; ++b3) {
                                    for(size_t c3=0; c3<4; ++c3) {
                                        if(m.leaf(pos)->leaf(subpos)->empty()) {
                                            continue;
                                        }
                                        auto subsubpos = Tree::get_position_2d(a3, b3, c3);
                                        auto subsubvalue = m.leaf(pos)->leaf(subpos)->get_value(subsubpos);

                                        auto subsubx = Tree::get_x_2d(a3, b3, c3);
                                        auto subsuby = Tree::get_y_2d(a3, b3, c3);
                                        sf::Uint8 col = subsubvalue * 20;

                                        sf::RectangleShape square { sf::Vector2f { 1, 1 } };
                                        square.setFillColor(sf::Color { col, col, col, 100 } );
                                        square.setPosition((64 * x) + (8 * subx) + (1 * subsubx), (64 * y) + (8 * suby) + (1 * subsuby));
                                        window.draw(square);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    while(1) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) {
                window.close();
                return 0;
            }
        }

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Escape)) {
            return 0;
        }

        window.display();
    }

    return 0;
}

template <typename Tree>
void populate(Tree & m)
{
    for(size_t a=0; a<4; ++a) {
        for(size_t b=0; b<4; ++b) {
            for(size_t c=0; c<4; ++c) {
                auto pos = Tree::get_position_2d(a, b, c);
                m.insert(pos, a+b+c);

                if(pos % 6 == 0) {
                    for(size_t a2=0; a2<4; ++a2) {
                        for(size_t b2=0; b2<4; ++b2) {
                            for(size_t c2=0; c2<4; ++c2) {
                                auto subpos = Tree::get_position_2d(a2, b2, c2);
                                m.leaf(pos)->insert(subpos, a2+b2+c2);

                                if(subpos % 6 == 0) {
                                    for(size_t a3=0; a3<4; ++a3) {
                                        for(size_t b3=0; b3<4; ++b3) {
                                            for(size_t c3=0; c3<4; ++c3) {
                                                auto subsubpos = Tree::get_position_2d(a3, b3, c3);
                                                m.leaf(pos)->leaf(subpos)->insert(subsubpos, a3+b3+c3);

                                                if(subsubpos % 6 == 0) {
                                                    for(size_t a4=0; a4<4; ++a4) {
                                                        for(size_t b4=0; b4<4; ++b4) {
                                                            for(size_t c4=0; c4<4; ++c4) {
                                                                auto subsubsubpos = Tree::get_position_2d(a4, b4, c4);
                                                                m.leaf(pos)->leaf(subpos)->leaf(subsubpos)->insert(subsubsubpos, a4+b4+c4);

                                                                if(subsubsubpos % 6 == 0) {
                                                                    for(size_t a5=0; a5<4; ++a5) {
                                                                        for(size_t b5=0; b5<4; ++b5) {
                                                                            for(size_t c5=0; c5<4; ++c5) {
                                                                                auto subsubsubsubpos = Tree::get_position_2d(a5, b5, c5);
                                                                                m.leaf(pos)->leaf(subpos)->leaf(subsubpos)->leaf(subsubsubpos)->insert(subsubsubsubpos, a5+b5+c5);
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

int main(int argc, char ** argv)
{
    hckt_tree<int> m;
    populate(m);
    std::cout << m.calculate_memory_size() << std::endl;

    sf::RenderWindow window{{window_width, window_height}, "hckt-tree"};
    window.clear(sf::Color { 255, 255, 255, 255 } );

    return render(window, m);
}
<|endoftext|>


<commit_before>85103dc7-4b02-11e5-ab04-28cfe9171a43<commit_msg>Hey we can now do a thing<commit_after>851ee933-4b02-11e5-bb0a-28cfe9171a43<|endoftext|>


<commit_before>8cc2bf9e-4b02-11e5-85a7-28cfe9171a43<commit_msg>( ͡° ͜ʖ ͡°)<commit_after>8cd07182-4b02-11e5-a22a-28cfe9171a43<|endoftext|>


<commit_before>
/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2016 Burak Arslan
 *
 * 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.
 */

#include<behold.h>

struct Loggable {
    int a;
    int b;
    MAKE_LOGGABLE(a, b)
};

struct NotLoggable {
    const char *b;
};

int main(int, char **) {
    std::vector<int> vi = {1, 2, 3, 4};
    std::vector<std::string> vs = {"a", "b", "c"};
    Loggable l;
    //NotLoggable nl;

#ifdef HAVE_MSGPACK
    std::string some_string = "some string";
    msgpack::v1::type::raw_ref raw;
    raw.ptr = some_string.c_str();
    raw.size = some_string.size();

#else
    std::string raw = "no msgpack";

#endif

    Behold() << "A std::vector<int>:" << vi;
    Behold() << "A std::vector<std::string>:" << vs;
    Behold() << "A loggable class:" << l;
    Behold() << "A string:" << raw;
    Behold() << "Some numbers with no spaces:"
        << 5 << LogManip::NO_SPACE
        << 6 << LogManip::NO_SPACE
        << 7 << LogManip::NO_SPACE
        << 8 << LogManip::NO_SPACE;

    return 0;
}
<commit_msg>switch to latest api<commit_after>
/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2016 Burak Arslan
 *
 * 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.
 */

#include<behold.h>

static const char *LC = "MAIN";

struct Loggable {
    int a;
    int b;
    MAKE_LOGGABLE(a, b)
};

struct NotLoggable {
    const char *b;
};

int main(int, char **) {
    std::vector<int> vi = {1, 2, 3, 4};
    std::vector<std::string> vs = {"a", "b", "c"};
    Loggable l;
    //NotLoggable nl;

#ifdef HAVE_MSGPACK
    std::string some_string = "some string";
    msgpack::v1::type::raw_ref raw;
    raw.ptr = some_string.c_str();
    raw.size = some_string.size();

#else
    std::string raw = "no msgpack";

#endif

    Behold::info(LC) << "A std::vector<int>:" << vi;
    Behold::debug(LC) << "A std::vector<std::string>:" << vs;
    Behold::error(LC) << "A loggable class:" << l;
    Behold::critical(LC) << "A string:" << raw;
    Behold::devel(LC) << "Some numbers with no spaces:"
        << 5 << LogManip::NO_SPACE
        << 6 << LogManip::NO_SPACE
        << 7 << LogManip::NO_SPACE
        << 8 << LogManip::NO_SPACE;

    return 0;
}
<|endoftext|>


<commit_before>54080adc-ad58-11e7-97c7-ac87a332f658<commit_msg>this is my first commit?<commit_after>5485dff3-ad58-11e7-a4a1-ac87a332f658<|endoftext|>


<commit_before>/* **** **** **** **** **** **** **** **** *
 *
 *         _/        _/        _/
 *        _/_/_/    _/_/_/    _/_/_/
 *       _/    _/  _/    _/  _/    _/
 *      _/    _/  _/    _/  _/    _/
 *     _/_/_/    _/_/_/    _/_/_/
 *
 * bit by bit
 * main.cpp
 *
 * author: ISHII 2bit
 * mail:   2bit@backspace.tokyo
 *
 * **** **** **** **** **** **** **** **** */

#include "bit_by_bit.hpp"
#include "simple_test.hpp"

bbb_test_declaretion(test);
void reusable_array_test();
void byte_array_test();
void multithread_test(size_t num);
void range_test();
bbb_test_declaretion(iterator_delegation);

int main(int argc, char *argv[]) {
    bbb_test(test);
    reusable_array_test();
    byte_array_test();
    multithread_test(4);
    range_test();
    bbb_test(iterator_delegation);
}

bbb_test_begin_definition(test)
bbb_assert(true);
bbb_test_end_definition(test)

#pragma mark reusable_array_test

#include <cassert>
#include <iostream>

struct particle {
    int life_time;
    int age;
    int name;

    particle() {}
    particle(int life_time, int name)
        : life_time(life_time)
        , name(name)
        , age(0) {}

    void init(int life_time, int name) {
        this->life_time = life_time;
        this->name = name;
        this->age = 0;
    }

    bool update() {
        return ++age < life_time;
    }

    void print() const {
        std::cout << name << ", " << (life_time - age) << std::endl;
    }
};

constexpr int loop_num(1);
constexpr int elem_num(10);

void reusable_array_test() {
    bbb::random::set_seed_mt(0);
    auto a = bbb::random::mt();
    bbb::random::set_seed_mt(0);
    auto b = bbb::random::mt();
    bbb::random::set_seed_mt(1);
    auto c = bbb::random::mt();
    assert(a == b);
    assert(a != c);

    bbb::stop_watch watch;
    watch.start();

    {
        bbb::random::set_seed_mt(0);
        bbb::reusable_array<particle, elem_num> f;
        watch.rap();

        for(int k = 0; k++ < loop_num;) {
            do f.init(bbb::random::mt() % 100, f.current_size()); while(f.has_space());
            while(f.current_size()) {
                f.update();
            }
        }

        watch.rap();
        std::cout << "time: " << watch.getLastRapNanoseconds() << std::endl;
    }

    {
        bbb::random::set_seed_mt(0);
        bbb::shared_vector<particle> f;
        watch.rap();

        for(int k = 0; k++ < loop_num;) {
            for(; f.size() < elem_num; f.push_back(std::shared_ptr<particle>(new particle(rand() % 100, f.size()))));
            auto wrapper = bbb::make_reverse(f);
            while(f.size()) for(auto e : wrapper) if(!e->update()) {
                e = f.back();
                f.pop_back();
            }
        }

        watch.rap();
        std::cout << "time: " << watch.getLastRapNanoseconds() << std::endl;
    }
}

void byte_array_test() {
    bbb::byte_array<int> barr{0x7FFFFFFF};
    for(auto i = 0; i < barr.size(); i++) {
        std::cout << (int)barr[i] << std::endl;
    }
    for(auto &b : barr) {
        std::cout << (int)b << std::endl;
    }
};

void multithread_test(size_t num) {
    size_t sum = 0;
    bool is_run = true;
    bbb::stop_watch watch;
    watch.start();
    bbb::multithread::manager manager(num, [&sum, &is_run](size_t index, std::mutex &mutex) {
        while(is_run) {
            if(mutex.try_lock()) {
                sum++;
                mutex.unlock();
            }
            bbb::sleep_nanoseconds(50);
        }
    });

    while(is_run) {
        bbb::sleep_milliseconds(10);
        auto lock(manager.lock_guard());
        if(100000 < sum) {
            is_run = false;
            manager.join();
        }
    }
    watch.rap();
    std::cout << "time: " << watch.getLastRapMilliseconds() << std::endl;
}

void range_test() {
    {
        std::vector<int> vec;
        bbb::for_each(bbb::range(10, 2), [&vec](int x) { vec.push_back(x); });
        bbb::for_each(vec, [](int &x) { x *= 2; });

        for(auto v : bbb::enumerate(vec)) {
            std::cout << v.index << ", " << v.value << std::endl;
            v.value *= 2;
        }
        for(auto v : bbb::enumerate(vec)) {
            std::cout << v.index << ", " << v.value << std::endl;
        }
    }

    {
        const std::vector<int> cvec{1, 2, 3};
        for(auto v : bbb::enumerate(cvec)) {
            std::cout << v.index << ", " << v.value << std::endl;
        }
    }
    std::cout << std::endl;

    std::vector<std::string> svec{"a", "hoge", "foo"};
    for(auto &v : bbb::enumerate(svec)) {
        std::cout << v.index << ", " << v.value << std::endl;
    }
    for(const auto &v : bbb::enumerate(svec)) {
        std::cout << v.index << ", " << v.value << std::endl;
    }
}

#include <iostream>
#include <vector>
#include <deque>
#include <queue>
#include <list>
#include <map>
#include <string>

bbb_test_begin_prepare(iterator_delegation)
struct vectroid
    : bbb::iterator_delegation<std::vector<int>> {
    std::vector<int> body;

    vectroid() : delegation(body) { };
};

struct mappoid : bbb::iterator_delegation<std::map<int, int>> {
    std::map<int, int> body;

    mappoid() : delegation(body) { };
};

struct introid : bbb::iterator_delegation<int> {
    int body;

    introid() : delegation(body) { };
};
bbb_test_end_prepare(iterator_delegation)

bbb_test_begin_definition(iterator_delegation)

bbb_assert(bbb::iteratable_class_traits<std::vector<int>>::has_iterator);
bbb_assert(bbb::iteratable_class_traits<std::vector<int>>::has_reverse_iterator);
bbb_assert(bbb::iteratable_class_traits<std::map<int, int>>::has_iterator);
bbb_assert(bbb::iteratable_class_traits<std::string>::has_iterator);
bbb_assert(!bbb::iteratable_class_traits<int>::has_iterator);
bbb_assert(bbb::iteratable_class_traits<bbb::iterator_delegation<std::vector<int>>>::has_iterator);

bbb_assert(bbb::iteratable_class_traits<std::vector<int>>::has_insert);
bbb_assert(bbb::iteratable_class_traits<std::vector<int>>::has_push_back);
bbb_assert(!bbb::iteratable_class_traits<std::vector<int>>::has_push_front);

bbb_assert(bbb::iteratable_class_traits<std::deque<int>>::has_insert);
bbb_assert(bbb::iteratable_class_traits<std::deque<int>>::has_push_back);
bbb_assert(bbb::iteratable_class_traits<std::deque<int>>::has_push_front);

bbb_assert(bbb::iteratable_class_traits<std::list<int>>::has_insert);
bbb_assert(bbb::iteratable_class_traits<std::list<int>>::has_push_back);
bbb_assert(bbb::iteratable_class_traits<std::list<int>>::has_push_front);

bbb_assert(!bbb::iteratable_class_traits<std::queue<int>>::has_insert);
bbb_assert(!bbb::iteratable_class_traits<std::queue<int>>::has_push_back);
bbb_assert(!bbb::iteratable_class_traits<std::queue<int>>::has_push_front);

bbb_assert(!bbb::iteratable_class_traits<int>::has_insert);
bbb_assert(!bbb::iteratable_class_traits<int>::has_push_back);
bbb_assert(!bbb::iteratable_class_traits<int>::has_push_front);

vectroid v;
v.body.push_back(-1);
v.body.push_back(-2);
v.body.push_back(-3);
std::vector<int> src{1, 2, 3, 4};
std::copy(src.begin(), src.end(), std::back_inserter(v));
std::copy(src.begin(), src.end(), std::inserter(v, v.begin()));
for (const auto &i : v) {
    std::cout << i << std::endl;
}

mappoid m;
m.body.insert(std::make_pair(2, 3));
m.body.insert(std::make_pair(6, 7));
m.body.insert(std::make_pair(4, 5));
m.body.insert(std::make_pair(8, 9));
for (const auto &p : m) {
    std::cout << p.first << ", " << p.second << std::endl;
}
introid i;
//	for(auto &it : i) {} // Error: delegated type doesn't provide iterator

bbb_test_end_definition(iterator_delegation)<commit_msg>update test<commit_after>/* **** **** **** **** **** **** **** **** *
 *
 *         _/        _/        _/
 *        _/_/_/    _/_/_/    _/_/_/
 *       _/    _/  _/    _/  _/    _/
 *      _/    _/  _/    _/  _/    _/
 *     _/_/_/    _/_/_/    _/_/_/
 *
 * bit by bit
 * main.cpp
 *
 * author: ISHII 2bit
 * mail:   2bit@backspace.tokyo
 *
 * **** **** **** **** **** **** **** **** */

#include "bit_by_bit.hpp"
#include "simple_test.hpp"

bbb_test_declaretion(test);
void reusable_array_test();
void byte_array_test();
void multithread_test(size_t num);
void range_test();
bbb_test_declaretion(iterator_delegation);

int main(int argc, char *argv[]) {
    bbb_test(test);
    reusable_array_test();
    byte_array_test();
    multithread_test(4);
    range_test();
    bbb_test(iterator_delegation);
}

bbb_test_begin_definition(test)
bbb_assert(true);
bbb_test_end_definition(test)

#pragma mark reusable_array_test

#include <cassert>
#include <iostream>

struct particle {
    int life_time;
    int age;
    int name;

    particle() {}
    particle(int life_time, int name)
        : life_time(life_time)
        , name(name)
        , age(0) {}

    void init(int life_time, int name) {
        this->life_time = life_time;
        this->name = name;
        this->age = 0;
    }

    bool update() {
        return ++age < life_time;
    }

    void print() const {
        std::cout << name << ", " << (life_time - age) << std::endl;
    }
};

constexpr int loop_num(1);
constexpr int elem_num(10);

void reusable_array_test() {
    bbb::random::set_seed_mt(0);
    auto a = bbb::random::mt();
    bbb::random::set_seed_mt(0);
    auto b = bbb::random::mt();
    bbb::random::set_seed_mt(1);
    auto c = bbb::random::mt();
    assert(a == b);
    assert(a != c);

    bbb::stop_watch watch;
    watch.start();

    {
        bbb::random::set_seed_mt(0);
        bbb::reusable_array<particle, elem_num> f;
        watch.rap();

        for(int k = 0; k++ < loop_num;) {
            do f.init(bbb::random::mt() % 100, f.current_size()); while(f.has_space());
            while(f.current_size()) {
                f.update();
            }
        }

        watch.rap();
        std::cout << "time: " << watch.getLastRapNanoseconds() << std::endl;
    }

    {
        bbb::random::set_seed_mt(0);
        bbb::shared_vector<particle> f;
        watch.rap();

        for(int k = 0; k++ < loop_num;) {
            for(; f.size() < elem_num; f.push_back(std::shared_ptr<particle>(new particle(rand() % 100, f.size()))));
            auto wrapper = bbb::make_reverse(f);
            while(f.size()) for(auto e : wrapper) if(!e->update()) {
                e = f.back();
                f.pop_back();
            }
        }

        watch.rap();
        std::cout << "time: " << watch.getLastRapNanoseconds() << std::endl;
    }
}

void byte_array_test() {
    bbb::byte_array<int> barr{0x7FFFFFFF};
    for(auto i = 0; i < barr.size(); i++) {
        std::cout << (int)barr[i] << std::endl;
    }
    for(auto &b : barr) {
        std::cout << (int)b << std::endl;
    }
};

void multithread_test(size_t num) {
    size_t sum = 0;
    bool is_run = true;
    bbb::stop_watch watch;
    watch.start();
    bbb::multithread::manager manager(num, [&sum, &is_run](size_t index, std::mutex &mutex) {
        while(is_run) {
            if(mutex.try_lock()) {
                sum++;
                mutex.unlock();
            }
            bbb::sleep_nanoseconds(50);
        }
    });

    while(is_run) {
        bbb::sleep_milliseconds(10);
        auto lock(manager.lock_guard());
        if(100000 < sum) {
            is_run = false;
            manager.join();
        }
    }
    watch.rap();
    std::cout << "time: " << watch.getLastRapMilliseconds() << std::endl;
}

void range_test() {
    {
        std::vector<int> vec;
        bbb::for_each(bbb::range(10, 2), [&vec](int x) { vec.push_back(x); });
        bbb::for_each(vec, [](int &x) { x *= 2; });

        for(auto v : bbb::enumerate(vec)) {
            std::cout << v.index << ", " << v.value << std::endl;
            v.value *= 2;
        }
        for(auto v : bbb::enumerate(vec)) {
            std::cout << v.index << ", " << v.value << std::endl;
        }
    }

    {
        const std::vector<int> cvec{1, 2, 3};
        for(auto v : bbb::enumerate(cvec)) {
            std::cout << v.index << ", " << v.value << std::endl;
        }
    }
    std::cout << std::endl;

    std::vector<std::string> svec{"a", "hoge", "foo"};
    for(auto &v : bbb::enumerate(svec)) {
        std::cout << v.index << ", " << v.value << std::endl;
    }
    for(const auto &v : bbb::enumerate(svec)) {
        std::cout << v.index << ", " << v.value << std::endl;
    }
}

#include <iostream>
#include <vector>
#include <deque>
#include <queue>
#include <list>
#include <map>
#include <string>

bbb_test_begin_prepare(iterator_delegation)
struct vectroid
    : bbb::iterator_delegation<std::vector<int>> {
    std::vector<int> body;

    vectroid() : delegation(body) { };
};

struct mappoid : bbb::iterator_delegation<std::map<int, int>> {
    std::map<int, int> body;

    mappoid() : delegation(body) { };
};

struct introid : bbb::iterator_delegation<int> {
    int body;

    introid() : delegation(body) { };
};
bbb_test_end_prepare(iterator_delegation)

bbb_test_begin_definition(iterator_delegation)

bbb_assert(bbb::iteratable_class_traits<std::vector<int>>::has_iterator);
bbb_assert(bbb::iteratable_class_traits<std::vector<int>>::has_reverse_iterator);
bbb_assert(bbb::iteratable_class_traits<std::map<int, int>>::has_iterator);
bbb_assert(bbb::iteratable_class_traits<std::string>::has_iterator);
bbb_assert(!bbb::iteratable_class_traits<int>::has_iterator);
bbb_assert(bbb::iteratable_class_traits<bbb::iterator_delegation<std::vector<int>>>::has_iterator);

bbb_assert(bbb::iteratable_class_traits<std::vector<int>>::has_insert);
bbb_assert(bbb::iteratable_class_traits<std::vector<int>>::has_push_back);
bbb_assert(!bbb::iteratable_class_traits<std::vector<int>>::has_push_front);

bbb_assert(bbb::iteratable_class_traits<std::deque<int>>::has_insert);
bbb_assert(bbb::iteratable_class_traits<std::deque<int>>::has_push_back);
bbb_assert(bbb::iteratable_class_traits<std::deque<int>>::has_push_front);

bbb_assert(bbb::iteratable_class_traits<std::list<int>>::has_insert);
bbb_assert(bbb::iteratable_class_traits<std::list<int>>::has_push_back);
bbb_assert(bbb::iteratable_class_traits<std::list<int>>::has_push_front);

bbb_assert(!bbb::iteratable_class_traits<std::queue<int>>::has_insert);
bbb_assert(!bbb::iteratable_class_traits<std::queue<int>>::has_push_back);
bbb_assert(!bbb::iteratable_class_traits<std::queue<int>>::has_push_front);

bbb_assert(!bbb::iteratable_class_traits<int>::has_insert);
bbb_assert(!bbb::iteratable_class_traits<int>::has_push_back);
bbb_assert(!bbb::iteratable_class_traits<int>::has_push_front);

vectroid v;
v.body.push_back(-1);
v.body.push_back(-2);
v.body.push_back(-3);

std::vector<int> src{1, 2, 3, 4};
std::copy(src.begin(), src.end(), std::back_inserter(v));
std::copy(src.begin(), src.end(), std::inserter(v, v.begin()));

{
    auto it = std::begin(v);
    bbb_assert(*it++ == 1);
    bbb_assert(*it++ == 2);
    bbb_assert(*it++ == 3);
    bbb_assert(*it++ == 4);
    bbb_assert(*it++ == -1);
    bbb_assert(*it++ == -2);
    bbb_assert(*it++ == -3);
    bbb_assert(*it++ == 1);
    bbb_assert(*it++ == 2);
    bbb_assert(*it++ == 3);
    bbb_assert(*it++ == 4);
}
mappoid m;
m.body.insert(std::make_pair(2, 3));
m.body.insert(std::make_pair(6, 7));
m.body.insert(std::make_pair(4, 5));
m.body.insert(std::make_pair(8, 9));
{
    auto it = std::begin(m);
    bbb_assert(it->first == 2 && (it++)->second == 3);
    bbb_assert(it->first == 4 && (it++)->second == 5);
    bbb_assert(it->first == 6 && (it++)->second == 7);
    bbb_assert(it->first == 8 && (it++)->second == 9);
}
introid i;
//	for(auto &it : i) {} // Error: delegated type doesn't provide iterator

bbb_test_end_definition(iterator_delegation)<|endoftext|>


<commit_before>#include <tools/common/log.h>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>

void tools::Logger::enableTimestamp(const std::shared_ptr <spdlog::logger> &other_log) {
    if (other_log != nullptr) {
        other_log->set_pattern("[%Y-%m-%d %H:%M:%S][%n]%^[%=8l]%$ %v");
        other_log->trace("Enabled timestamp");
    }
}

void tools::Logger::disableTimestamp(const std::shared_ptr<spdlog::logger> &other_log){
    if(other_log != nullptr){
        other_log->set_pattern("[%n]%^[%=8l]%$ %v");
        other_log->trace("Disabled timestamp");
    }
}

template<typename levelType>
void tools::Logger::setLogLevel(const std::shared_ptr<spdlog::logger> &other_log, levelType levelZeroToFive) {
    if constexpr(std::is_same_v<levelType, spdlog::level::level_enum>)
        other_log->set_level(levelZeroToFive);
    else if constexpr(std::is_integral_v<levelType>) {
        if(levelZeroToFive > 5) { throw std::runtime_error("Expected verbosity level integer in [0-5]. Got: " + std::to_string(levelZeroToFive)); }
        return tools::Logger::setLogLevel(other_log,static_cast<spdlog::level::level_enum>(levelZeroToFive));
    }else if constexpr(std::is_same_v<levelType, std::optional<size_t>>) {
        if(levelZeroToFive)
            return setLogLevel(other_log,levelZeroToFive.value());
        else
            return;
    }else if constexpr(std::is_same_v<levelType, std::optional<spdlog::level::level_enum>>){
        if(levelZeroToFive) return setLogLevel(other_log,levelZeroToFive.value());
        else return;
    } else {
        throw std::runtime_error("Given wrong type for spdlog verbosity level");
    }
//    other_log->info("Log verbosity level: {}   | trace:0 | debug:1 | info:2 | warn:3 | error:4 | critical:5 |", static_cast<int>(other_log->level()));
//    other_log->debug("Log verbosity level: {}", static_cast<int>(other_log->level()));
}

template void tools::Logger::setLogLevel(const std::shared_ptr<spdlog::logger> &other_log, size_t levelZeroToFive);
template void tools::Logger::setLogLevel(const std::shared_ptr<spdlog::logger> &other_log, std::optional<size_t> levelZeroToFive);
template void tools::Logger::setLogLevel(const std::shared_ptr<spdlog::logger> &other_log, std::optional<spdlog::level::level_enum> levelZeroToFive);

size_t tools::Logger::getLogLevel(const std::shared_ptr<spdlog::logger> &other_log) {
    if(other_log != nullptr)
        return static_cast<size_t>(other_log->level());
    else
        return 2;
}

void tools::Logger::setLogger(std::shared_ptr<spdlog::logger> &other_log, const std::string &name, std::optional<size_t> levelZeroToFive , std::optional<bool> timestamp) {
    if(spdlog::get(name) == nullptr)
        other_log = spdlog::stdout_color_mt(name);
    else
        other_log = spdlog::get(name);
    other_log->set_pattern("[%n]%^[%=8l]%$ %v"); // Disabled timestamp is the default
    setLogLevel(other_log,levelZeroToFive);
    if(timestamp and timestamp.value())
        enableTimestamp(other_log);
}

std::shared_ptr<spdlog::logger> tools::Logger::setLogger(const std::string &name, std::optional<size_t> levelZeroToFive, std::optional<bool> timestamp) {
    std::shared_ptr<spdlog::logger> other_log;
    if(spdlog::get(name) == nullptr) {
        other_log = spdlog::stdout_color_mt(name);
    } else {
        other_log = spdlog::get(name);
    }
    tools::Logger::setLogLevel(other_log,levelZeroToFive);
    if(not timestamp or (timestamp and timestamp.value()))
        tools::Logger::enableTimestamp(other_log);
    else if(timestamp and not timestamp.value())
        tools::Logger::disableTimestamp(other_log);
    return other_log;
}

std::shared_ptr<spdlog::logger> tools::Logger::getLogger( const std::string & name ){
    if(spdlog::get(name) == nullptr)
        throw std::runtime_error(fmt::format("Logger with name [{}] does not exist",name));
    else
        return spdlog::get(name);
}
<commit_msg>Tweaked log type and coloring (doesn't seem to make a difference yet)<commit_after>#include <tools/common/log.h>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>

void tools::Logger::enableTimestamp(const std::shared_ptr <spdlog::logger> &other_log) {
    if (other_log != nullptr) {
        other_log->set_pattern("[%Y-%m-%d %H:%M:%S][%n]%^[%=8l]%$ %v");
        other_log->trace("Enabled timestamp");
    }
}

void tools::Logger::disableTimestamp(const std::shared_ptr<spdlog::logger> &other_log){
    if(other_log != nullptr){
        other_log->set_pattern("[%n]%^[%=8l]%$ %v");
        other_log->trace("Disabled timestamp");
    }
}

template<typename levelType>
void tools::Logger::setLogLevel(const std::shared_ptr<spdlog::logger> &other_log, levelType levelZeroToFive) {
    if constexpr(std::is_same_v<levelType, spdlog::level::level_enum>)
        other_log->set_level(levelZeroToFive);
    else if constexpr(std::is_integral_v<levelType>) {
        if(levelZeroToFive > 5) { throw std::runtime_error("Expected verbosity level integer in [0-5]. Got: " + std::to_string(levelZeroToFive)); }
        return tools::Logger::setLogLevel(other_log,static_cast<spdlog::level::level_enum>(levelZeroToFive));
    }else if constexpr(std::is_same_v<levelType, std::optional<size_t>>) {
        if(levelZeroToFive)
            return setLogLevel(other_log,levelZeroToFive.value());
        else
            return;
    }else if constexpr(std::is_same_v<levelType, std::optional<spdlog::level::level_enum>>){
        if(levelZeroToFive) return setLogLevel(other_log,levelZeroToFive.value());
        else return;
    } else {
        throw std::runtime_error("Given wrong type for spdlog verbosity level");
    }
//    other_log->info("Log verbosity level: {}   | trace:0 | debug:1 | info:2 | warn:3 | error:4 | critical:5 |", static_cast<int>(other_log->level()));
//    other_log->debug("Log verbosity level: {}", static_cast<int>(other_log->level()));
}

template void tools::Logger::setLogLevel(const std::shared_ptr<spdlog::logger> &other_log, size_t levelZeroToFive);
template void tools::Logger::setLogLevel(const std::shared_ptr<spdlog::logger> &other_log, std::optional<size_t> levelZeroToFive);
template void tools::Logger::setLogLevel(const std::shared_ptr<spdlog::logger> &other_log, std::optional<spdlog::level::level_enum> levelZeroToFive);

size_t tools::Logger::getLogLevel(const std::shared_ptr<spdlog::logger> &other_log) {
    if(other_log != nullptr)
        return static_cast<size_t>(other_log->level());
    else
        return 2;
}

void tools::Logger::setLogger(std::shared_ptr<spdlog::logger> &other_log, const std::string &name, std::optional<size_t> levelZeroToFive , std::optional<bool> timestamp) {
    if(spdlog::get(name) == nullptr)
        other_log = spdlog::stdout_color_st(name,spdlog::color_mode::always);
    else
        other_log = spdlog::get(name);
    other_log->set_pattern("[%n]%^[%=8l]%$ %v"); // Disabled timestamp is the default
    setLogLevel(other_log,levelZeroToFive);
    if(timestamp and timestamp.value())
        enableTimestamp(other_log);
}

std::shared_ptr<spdlog::logger> tools::Logger::setLogger(const std::string &name, std::optional<size_t> levelZeroToFive, std::optional<bool> timestamp) {
    std::shared_ptr<spdlog::logger> other_log;
    if(spdlog::get(name) == nullptr) {
        other_log = spdlog::stdout_color_mt(name);
    } else {
        other_log = spdlog::get(name);
    }
    tools::Logger::setLogLevel(other_log,levelZeroToFive);
    if(not timestamp or (timestamp and timestamp.value()))
        tools::Logger::enableTimestamp(other_log);
    else if(timestamp and not timestamp.value())
        tools::Logger::disableTimestamp(other_log);
    return other_log;
}

std::shared_ptr<spdlog::logger> tools::Logger::getLogger( const std::string & name ){
    if(spdlog::get(name) == nullptr)
        throw std::runtime_error(fmt::format("Logger with name [{}] does not exist",name));
    else
        return spdlog::get(name);
}
<|endoftext|>


<commit_before>b68932ae-4b02-11e5-912d-28cfe9171a43<commit_msg>more bug fix<commit_after>b696e3f3-4b02-11e5-90a7-28cfe9171a43<|endoftext|>


<commit_before>#include <algorithm>
#include <bitset>
#include <iostream>
#include <map>
#include <string>
#include "logic/lexer.h"
#include "logic/parser.h"
#include "logic/dependency_visitor.h"
#include "logic/subset_visitor.h"

using namespace std;

const short MAX_VARIABLES = 31;

int main() {
    string s;
    getline(cin, s);

    auto tokens = logic::Lexer(s.c_str(), s.length()).Tokenize();
    auto expr = logic::Parser(tokens.data()).Parse(s.c_str());

    logic::DependencyVisitor dVisitor;
    expr->Traverse(&dVisitor);
    auto dependencySet = dVisitor.GetResult();
    if (dependencySet.size() > MAX_VARIABLES) {
        cerr << "Too many variables!\n";
        return 1;
    }
    vector<string> deps(dependencySet.rbegin(), dependencySet.rend());

    logic::SubsetVisitor sVisitor;
    expr->Traverse(&sVisitor);
    auto subsets = sVisitor.GetResult();
    subsets.erase(remove_if(begin(subsets), end(subsets),
        [ ](const logic::Expression* e) {
            return !dynamic_cast<const logic::Operator*>(e);
        }
    ), end(subsets));

    cout << endl;
    for (size_t i = 0; i < subsets.size(); i++) {
        cout << 'F' << i + 1 << " = ";
        subsets[i]->ToString(cout);
        cout << endl;
    }
    cout << endl;

    //Generating table with Gray code.
    vector<vector<bool>> table(
        1LL << deps.size(),
        vector<bool>(deps.size() + subsets.size())
    );
    map<string, bool> context;
    for (const string& var: deps)
        context.emplace(var, 0);
    size_t j = deps.size();
    for (auto e: subsets)
        table[0x0][j++] = e->Evaluate(context);
    bitset<MAX_VARIABLES> mask;
    for (size_t i = 0x1; i < 1LL << deps.size(); i++) {
        size_t x = i, pos = 0;
        while (!(x & 0x1)) {
            x >>= 1;
            pos++;
        }
        mask.flip(pos);
        context.find(deps[pos])->second ^= true;
        pos = mask.to_ulong();
        for (j = 0; j < deps.size(); j++)
            table[pos][j] = mask[deps.size() - j - 1];
        for (auto e: subsets)
            table[pos][j++] = e->Evaluate(context);
    }

    for_each(deps.rbegin(), deps.rend(),
        [ ](const string& var) { cout << var << '\t'; }
    );
    for (j = 1; j <= subsets.size(); j++)
        cout << 'F' << j << '\t';
    cout << endl;
    for (const auto& row: table) {
        for (auto b: row)
            cout << b << '\t';
        cout << endl;
    }
}
<commit_msg>Updated main.cpp<commit_after>#include <algorithm>
#include <bitset>
#include <iostream>
#include <map>
#include <string>
#include "logic/lexer.h"
#include "logic/parser.h"
#include "logic/dependency_visitor.h"
#include "logic/subset_visitor.h"

using namespace std;

const short MAX_VARIABLES = 31;

class OpCountVisitor: public logic::Visitor {
public:
    void Visit(const logic::Expression* e) {
        if (dynamic_cast<const logic::Operator*>(e))
            _count++;
    }

    size_t GetCount() const { return _count; }

private:
    size_t _count = 0;
};

int main() {
    string s;
    getline(cin, s);

    unique_ptr<logic::Expression> expr;
    try {
        auto tokens = logic::Lexer(s.c_str(), s.length()).Tokenize();
        expr = logic::Parser(tokens.data()).Parse(s.c_str());
    }
    catch (logic::LexicalError&) {
        cerr << "Lexical error\n";
        return 1;
    }
    catch (logic::SyntaxError&) {
        cerr << "Syntax error\n";
        return 1;
    }

    logic::DependencyVisitor dVisitor;
    expr->Traverse(&dVisitor);
    auto dependencySet = dVisitor.GetResult();
    if (dependencySet.size() > MAX_VARIABLES) {
        cerr << "Too many variables!\n";
        return 1;
    }
    vector<string> deps(dependencySet.rbegin(), dependencySet.rend());

    logic::SubsetVisitor sVisitor;
    expr->Traverse(&sVisitor);
    auto subsets = sVisitor.GetResult();
    subsets.erase(remove_if(begin(subsets), end(subsets),
        [ ](const logic::Expression* e) {
            return !dynamic_cast<const logic::Operator*>(e);
        }
    ), end(subsets));

    OpCountVisitor cVisitor;
    expr->Traverse(&cVisitor);
    cout << endl << cVisitor.GetCount() << " operations\n";

    for (size_t i = 0; i < subsets.size(); i++) {
        cout << 'F' << i + 1 << " = ";
        subsets[i]->ToString(cout);
        cout << endl;
    }
    cout << endl;

    //Generating table with Gray code.
    vector<vector<bool>> table(
        1LL << deps.size(),
        vector<bool>(deps.size() + subsets.size())
    );
    map<string, bool> context;
    for (const string& var: deps)
        context.emplace(var, 0);
    size_t j = deps.size();
    for (auto e: subsets)
        table[0x0][j++] = e->Evaluate(context);
    bitset<MAX_VARIABLES> mask;
    for (size_t i = 0x1; i < 1LL << deps.size(); i++) {
        size_t x = i, pos = 0;
        while (!(x & 0x1)) {
            x >>= 1;
            pos++;
        }
        mask.flip(pos);
        context.find(deps[pos])->second ^= true;
        pos = mask.to_ulong();
        for (j = 0; j < deps.size(); j++)
            table[pos][j] = mask[deps.size() - j - 1];
        for (auto e: subsets)
            table[pos][j++] = e->Evaluate(context);
    }

    for_each(deps.rbegin(), deps.rend(),
        [ ](const string& var) { cout << var << '\t'; }
    );
    for (j = 1; j <= subsets.size(); j++)
        cout << 'F' << j << '\t';
    cout << endl;
    for (const auto& row: table) {
        for (auto b: row)
            cout << b << '\t';
        cout << endl;
    }
}
<|endoftext|>