<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <string>
#include <iostream>

#include "Options.hpp"
#include "Compiler.hpp"
#include "Utils.hpp"
#include "Platform.hpp"

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE EddicTestSuites
#include <boost/test/unit_test.hpp>
#include <boost/test/detail/unit_test_parameters.hpp>

/*
 * \def TEST_SAMPLE(file)
 * Generate a test case that verify that the sample compiles in both 32 and 64 bits mode.
 */
#define TEST_SAMPLE(file)\
BOOST_AUTO_TEST_CASE( samples_##file ){\
    assertCompiles("samples/" #file ".eddi", "--32");\
    assertCompiles("samples/" #file ".eddi", "--64");\
}

/* Config Fixture  */

struct ConfigFixture {
    ConfigFixture(){
        //TODO Configure the show progress parameter
    }

    ~ConfigFixture(){
        /* Nothing to teard down */
    }
};

/* Fixture to delete the a.out file after the compilation */

struct DeleteOutFixture {
    DeleteOutFixture(){
        /* Nothing to setup  */
    }

    ~DeleteOutFixture(){
        BOOST_TEST_MESSAGE( "Delete the a.out file" );
        remove("a.out");
    }
};

inline void parse_options(const std::string& file, const std::string& param){
    const char* argv[4];
    argv[0] = "./bin/test";
    argv[1] = param.c_str();
    argv[2] = "--quiet";
    argv[3] = file.c_str();

    BOOST_REQUIRE (eddic::parseOptions(4, argv));
}

void assertCompiles(const std::string& file, const std::string& param){
    parse_options(file, param);

    eddic::Compiler compiler;
    int code = compiler.compile(file);

    BOOST_REQUIRE_EQUAL (code, 0);
}

void assert_compilation_error(const std::string& file, const std::string& param){
    parse_options("test/cases/" + file, param);

    eddic::Compiler compiler;
    int code = compiler.compile("test/cases/" + file);

    BOOST_REQUIRE_EQUAL (code, 1);
}

void assertOutputEquals(const std::string& file, const std::string& output, const std::string& param){
    assertCompiles("test/cases/" + file, param);

    std::string out = eddic::execCommand("./a.out");

    BOOST_CHECK_EQUAL (output, out);
}

void assert_output_32(const std::string& file, const std::string& output){
    assertOutputEquals(file, output, "--32");
}

void assert_output_64(const std::string& file, const std::string& output){
    assertOutputEquals(file, output, "--64");
}

void assert_output(const std::string& file, const std::string& output){
    assert_output_32(file, output);
    assert_output_64(file, output);
}

/* Configure a global fixture for the configuration */

BOOST_GLOBAL_FIXTURE ( ConfigFixture  )

/* Compiles all the samples */

BOOST_FIXTURE_TEST_SUITE( SamplesSuite, DeleteOutFixture )

TEST_SAMPLE(arrays)
TEST_SAMPLE(asm)
TEST_SAMPLE(assembly)
TEST_SAMPLE(bool)
TEST_SAMPLE(compound)
TEST_SAMPLE(concat)
TEST_SAMPLE(const)
TEST_SAMPLE(functions)
TEST_SAMPLE(float)
TEST_SAMPLE(little_float)
TEST_SAMPLE(casts)
TEST_SAMPLE(inc)
TEST_SAMPLE(includes)
TEST_SAMPLE(optimize)
TEST_SAMPLE(problem)
TEST_SAMPLE(sort)
TEST_SAMPLE(identifiers)
TEST_SAMPLE(structures)

BOOST_AUTO_TEST_SUITE_END()

/* Specific tests */

BOOST_FIXTURE_TEST_SUITE(SpecificSuite, DeleteOutFixture)

BOOST_AUTO_TEST_CASE( array_foreach_local ){
    assert_output("array_foreach_local.eddi", "43210");
}

BOOST_AUTO_TEST_CASE( array_foreach_global ){
    assert_output("array_foreach_global.eddi", "43210");
}

BOOST_AUTO_TEST_CASE( array_foreach_param_local ){
    assert_output("array_foreach_param_local.eddi", "43210");
}

BOOST_AUTO_TEST_CASE( array_foreach_param_global ){
    assert_output("array_foreach_param_global.eddi", "43210");
}

BOOST_AUTO_TEST_CASE( array_foreach_param_param ){
    assert_output("array_foreach_param_param.eddi", "43210");
}

BOOST_AUTO_TEST_CASE( casts ){
    assert_output_32("casts.eddi", "5.0|5|4|333|5.0|8.3299|");
    assert_output_64("casts.eddi", "5.0|5|4|333|5.0|8.3300|");
}

BOOST_AUTO_TEST_CASE( compound ){
    assert_output("compound.eddi", "6|9|6|18|6|0|");
}

BOOST_AUTO_TEST_CASE( if_ ){
    assert_output("if.eddi", "Cool");
}

BOOST_AUTO_TEST_CASE( includes ){
    assert_output("includes.eddi", "45");
}

BOOST_AUTO_TEST_CASE( int_arrays ){
    assert_output("int_arrays.eddi", "1|1|1|0|0|0|0|0|2|2|0|0|0|0|0|4|9|4|1|9|9|0|0|0|4|9|4|2|9|9|0|0|0|");
}

BOOST_AUTO_TEST_CASE( string_arrays ){
    assert_output("string_arrays.eddi", "5|6|7|7|5|6|7|7||||a|a|a|a|a||||||2|2|2|7|7||||4|9|4|a|9|9||||4|9|4|2|9|9||||");
}

BOOST_AUTO_TEST_CASE( int_pointers ){
    assert_output_32("int_pointers.eddi", "44|44|55|55|66|66|66|");
    assert_output_64("int_pointers.eddi", "44|44|55|55|66|66|66|");
}

BOOST_AUTO_TEST_CASE( while_ ){
    assert_output("while.eddi", "01234");
}

BOOST_AUTO_TEST_CASE( do_while_ ){
    assert_output("do_while.eddi", "01234");
}

BOOST_AUTO_TEST_CASE( float_ ){
    //TODO Could be better to split this test
    assert_output_32("float.eddi", "5.4990|100.0|-100.0|100.0|2.0889|4.1999|3.3299|1.5000|3.0|5.0|4.5000|5.7500|1.5000|-2.0|7.5000|2.2699|7.5590|14.4927|3.0|8.0|3.0910|2.0934|5.1844|1|1|11111|8.0|13.7500|2.5000|5.5000|2.5000|5.5000|2.5000|5.5000|2.5000|5.5000|3.3299|");
    assert_output_64("float.eddi", "5.4989|100.0|-100.0|100.0|2.0889|4.2000|3.3300|1.5000|3.0|5.0|4.5000|5.7500|1.5000|-2.0|7.5000|2.2700|7.5590|14.4927|3.0|8.0|3.0910|2.0934|5.1844|1|1|11111|8.0|13.7500|2.5000|5.5000|2.5000|5.5000|2.5000|5.5000|2.5000|5.5000|3.3300|");
}

BOOST_AUTO_TEST_CASE( for_ ){
    assert_output("for.eddi", "01234");
}

BOOST_AUTO_TEST_CASE( foreach_ ){
    assert_output("foreach.eddi", "012345");
}

BOOST_AUTO_TEST_CASE( globals_ ){
    assert_output("globals.eddi", "1000a2000aa");
}

BOOST_AUTO_TEST_CASE( inc ){
    assert_output("inc.eddi", "0|1|2|1|0|1|2|");
}

BOOST_AUTO_TEST_CASE( void_functions ){
    assert_output("void.eddi", "4445");
}

BOOST_AUTO_TEST_CASE( string_functions ){
    assert_output("return_string.eddi", "abcdef");
}

BOOST_AUTO_TEST_CASE( int_functions ){
    assert_output("return_int.eddi", "484");
}

BOOST_AUTO_TEST_CASE( recursive_functions ){
    assert_output("recursive.eddi", "362880");
}

BOOST_AUTO_TEST_CASE( math ){
    assert_output("math.eddi", "333|111|-111|0|24642|2|-2|-1|1|2|0|-111|");
}

BOOST_AUTO_TEST_CASE( builtin ){
    assert_output("builtin.eddi", "10|11|12|13|12|13|10|11|4|8|13|8|0|3|");
}

BOOST_AUTO_TEST_CASE( assign_value ){
    assert_output("assign_value.eddi", "66779921");
}

BOOST_AUTO_TEST_CASE( concat ){
    assert_output("concat.eddi", "asdf1234|1234asdf|asdfasdf|12341234|");
}

BOOST_AUTO_TEST_CASE( prints ){
    assert_output_32("prints.eddi", "111|0|-111|0|1|999.9899|1.0089|0.0|-1.0089|-999.9899||-0|asdf|1234asdf|");
    assert_output_64("prints.eddi", "111|0|-111|0|1|999.9900|1.0089|0.0|-1.0089|-999.9900||-0|asdf|1234asdf|");
}

BOOST_AUTO_TEST_CASE( structures ){
    assert_output_32("structures.eddi", "222|666|3.2300|0|asdf|333|888|4.3299|1|ertz|333|888|4.3299|1|ertz|");
    assert_output_64("structures.eddi", "222|666|3.2300|0|asdf|333|888|4.3300|1|ertz|333|888|4.3300|1|ertz|");
}

BOOST_AUTO_TEST_CASE( nested ){
    assert_output_32("nested.eddi", "222|555|333|444|2222|5555|3333|4444||222|555|333|444|2222|5555|3333|4444|");
    assert_output_64("nested.eddi", "222|555|333|444|2222|5555|3333|4444||222|555|333|444|2222|5555|3333|4444|");
}

BOOST_AUTO_TEST_CASE( args ){
    assertCompiles("test/cases/args.eddi", "--32");

    std::string out = eddic::execCommand("./a.out");
    BOOST_CHECK_EQUAL ("./a.out|", out);

    out = eddic::execCommand("./a.out arg1 arg2 arg3");
    BOOST_CHECK_EQUAL ("./a.out|arg1|arg2|arg3|", out);

    assertCompiles("test/cases/args.eddi", "--64");

    out = eddic::execCommand("./a.out");
    BOOST_CHECK_EQUAL ("./a.out|", out);

    out = eddic::execCommand("./a.out arg1 arg2 arg3");
    BOOST_CHECK_EQUAL ("./a.out|arg1|arg2|arg3|", out);
}

BOOST_AUTO_TEST_SUITE_END()

/* Verify that the compilation fails for invalid statements */

BOOST_FIXTURE_TEST_SUITE(CompilationErrorsSuite, DeleteOutFixture)

BOOST_AUTO_TEST_CASE( params_assign ){
    assert_compilation_error("params_assign.eddi", "--32");
    assert_compilation_error("params_assign.eddi", "--64");
}

BOOST_AUTO_TEST_SUITE_END()

/* Standard library test suite  */

BOOST_FIXTURE_TEST_SUITE(StandardLibSuite, DeleteOutFixture)

BOOST_AUTO_TEST_CASE( std_lib_arrays_sum ){
    assert_output("stdlib_array_sum.eddi", "100");
}

BOOST_AUTO_TEST_CASE( std_lib_math_min ){
    assert_output("stdlib_math_min.eddi", "999|0|0|-1|0|-1");
}

BOOST_AUTO_TEST_CASE( std_lib_math_max ){
    assert_output("stdlib_math_max.eddi", "1000|1|1|0|0|0");
}

BOOST_AUTO_TEST_CASE( std_lib_math_factorial ){
    assert_output("stdlib_math_factorial.eddi", "1|1|2|362880");
}

BOOST_AUTO_TEST_CASE( std_lib_math_pow ){
    assert_output("stdlib_math_pow.eddi", "0|1|10|100|1024|1");
}

BOOST_AUTO_TEST_SUITE_END()

/* Unit test for bug fixes regression */

BOOST_FIXTURE_TEST_SUITE(BugFixesSuite, DeleteOutFixture)

BOOST_AUTO_TEST_CASE( while_bug ){
    assert_output("while_bug.eddi", "W1W2W3W4W5");
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Add the string pointers test case to the integration tests<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <string>
#include <iostream>

#include "Options.hpp"
#include "Compiler.hpp"
#include "Utils.hpp"
#include "Platform.hpp"

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE EddicTestSuites
#include <boost/test/unit_test.hpp>
#include <boost/test/detail/unit_test_parameters.hpp>

/*
 * \def TEST_SAMPLE(file)
 * Generate a test case that verify that the sample compiles in both 32 and 64 bits mode.
 */
#define TEST_SAMPLE(file)\
BOOST_AUTO_TEST_CASE( samples_##file ){\
    assertCompiles("samples/" #file ".eddi", "--32");\
    assertCompiles("samples/" #file ".eddi", "--64");\
}

/* Config Fixture  */

struct ConfigFixture {
    ConfigFixture(){
        //TODO Configure the show progress parameter
    }

    ~ConfigFixture(){
        /* Nothing to teard down */
    }
};

/* Fixture to delete the a.out file after the compilation */

struct DeleteOutFixture {
    DeleteOutFixture(){
        /* Nothing to setup  */
    }

    ~DeleteOutFixture(){
        BOOST_TEST_MESSAGE( "Delete the a.out file" );
        remove("a.out");
    }
};

inline void parse_options(const std::string& file, const std::string& param){
    const char* argv[4];
    argv[0] = "./bin/test";
    argv[1] = param.c_str();
    argv[2] = "--quiet";
    argv[3] = file.c_str();

    BOOST_REQUIRE (eddic::parseOptions(4, argv));
}

void assertCompiles(const std::string& file, const std::string& param){
    parse_options(file, param);

    eddic::Compiler compiler;
    int code = compiler.compile(file);

    BOOST_REQUIRE_EQUAL (code, 0);
}

void assert_compilation_error(const std::string& file, const std::string& param){
    parse_options("test/cases/" + file, param);

    eddic::Compiler compiler;
    int code = compiler.compile("test/cases/" + file);

    BOOST_REQUIRE_EQUAL (code, 1);
}

void assertOutputEquals(const std::string& file, const std::string& output, const std::string& param){
    assertCompiles("test/cases/" + file, param);

    std::string out = eddic::execCommand("./a.out");

    BOOST_CHECK_EQUAL (output, out);
}

void assert_output_32(const std::string& file, const std::string& output){
    assertOutputEquals(file, output, "--32");
}

void assert_output_64(const std::string& file, const std::string& output){
    assertOutputEquals(file, output, "--64");
}

void assert_output(const std::string& file, const std::string& output){
    assert_output_32(file, output);
    assert_output_64(file, output);
}

/* Configure a global fixture for the configuration */

BOOST_GLOBAL_FIXTURE ( ConfigFixture  )

/* Compiles all the samples */

BOOST_FIXTURE_TEST_SUITE( SamplesSuite, DeleteOutFixture )

TEST_SAMPLE(arrays)
TEST_SAMPLE(asm)
TEST_SAMPLE(assembly)
TEST_SAMPLE(bool)
TEST_SAMPLE(compound)
TEST_SAMPLE(concat)
TEST_SAMPLE(const)
TEST_SAMPLE(functions)
TEST_SAMPLE(float)
TEST_SAMPLE(little_float)
TEST_SAMPLE(casts)
TEST_SAMPLE(inc)
TEST_SAMPLE(includes)
TEST_SAMPLE(optimize)
TEST_SAMPLE(problem)
TEST_SAMPLE(sort)
TEST_SAMPLE(identifiers)
TEST_SAMPLE(structures)

BOOST_AUTO_TEST_SUITE_END()

/* Specific tests */

BOOST_FIXTURE_TEST_SUITE(SpecificSuite, DeleteOutFixture)

BOOST_AUTO_TEST_CASE( array_foreach_local ){
    assert_output("array_foreach_local.eddi", "43210");
}

BOOST_AUTO_TEST_CASE( array_foreach_global ){
    assert_output("array_foreach_global.eddi", "43210");
}

BOOST_AUTO_TEST_CASE( array_foreach_param_local ){
    assert_output("array_foreach_param_local.eddi", "43210");
}

BOOST_AUTO_TEST_CASE( array_foreach_param_global ){
    assert_output("array_foreach_param_global.eddi", "43210");
}

BOOST_AUTO_TEST_CASE( array_foreach_param_param ){
    assert_output("array_foreach_param_param.eddi", "43210");
}

BOOST_AUTO_TEST_CASE( casts ){
    assert_output_32("casts.eddi", "5.0|5|4|333|5.0|8.3299|");
    assert_output_64("casts.eddi", "5.0|5|4|333|5.0|8.3300|");
}

BOOST_AUTO_TEST_CASE( compound ){
    assert_output("compound.eddi", "6|9|6|18|6|0|");
}

BOOST_AUTO_TEST_CASE( if_ ){
    assert_output("if.eddi", "Cool");
}

BOOST_AUTO_TEST_CASE( includes ){
    assert_output("includes.eddi", "45");
}

BOOST_AUTO_TEST_CASE( int_arrays ){
    assert_output("int_arrays.eddi", "1|1|1|0|0|0|0|0|2|2|0|0|0|0|0|4|9|4|1|9|9|0|0|0|4|9|4|2|9|9|0|0|0|");
}

BOOST_AUTO_TEST_CASE( string_arrays ){
    assert_output("string_arrays.eddi", "5|6|7|7|5|6|7|7||||a|a|a|a|a||||||2|2|2|7|7||||4|9|4|a|9|9||||4|9|4|2|9|9||||");
}

BOOST_AUTO_TEST_CASE( int_pointers ){
    assert_output_32("int_pointers.eddi", "44|44|55|55|66|66|66|");
    assert_output_64("int_pointers.eddi", "44|44|55|55|66|66|66|");
}

BOOST_AUTO_TEST_CASE( string_pointers ){
    assert_output_32("string_pointers.eddi", "a|a|b|b|c|c|c|");
    assert_output_64("string_pointers.eddi", "a|a|b|b|c|c|c|");
}

BOOST_AUTO_TEST_CASE( while_ ){
    assert_output("while.eddi", "01234");
}

BOOST_AUTO_TEST_CASE( do_while_ ){
    assert_output("do_while.eddi", "01234");
}

BOOST_AUTO_TEST_CASE( float_ ){
    //TODO Could be better to split this test
    assert_output_32("float.eddi", "5.4990|100.0|-100.0|100.0|2.0889|4.1999|3.3299|1.5000|3.0|5.0|4.5000|5.7500|1.5000|-2.0|7.5000|2.2699|7.5590|14.4927|3.0|8.0|3.0910|2.0934|5.1844|1|1|11111|8.0|13.7500|2.5000|5.5000|2.5000|5.5000|2.5000|5.5000|2.5000|5.5000|3.3299|");
    assert_output_64("float.eddi", "5.4989|100.0|-100.0|100.0|2.0889|4.2000|3.3300|1.5000|3.0|5.0|4.5000|5.7500|1.5000|-2.0|7.5000|2.2700|7.5590|14.4927|3.0|8.0|3.0910|2.0934|5.1844|1|1|11111|8.0|13.7500|2.5000|5.5000|2.5000|5.5000|2.5000|5.5000|2.5000|5.5000|3.3300|");
}

BOOST_AUTO_TEST_CASE( for_ ){
    assert_output("for.eddi", "01234");
}

BOOST_AUTO_TEST_CASE( foreach_ ){
    assert_output("foreach.eddi", "012345");
}

BOOST_AUTO_TEST_CASE( globals_ ){
    assert_output("globals.eddi", "1000a2000aa");
}

BOOST_AUTO_TEST_CASE( inc ){
    assert_output("inc.eddi", "0|1|2|1|0|1|2|");
}

BOOST_AUTO_TEST_CASE( void_functions ){
    assert_output("void.eddi", "4445");
}

BOOST_AUTO_TEST_CASE( string_functions ){
    assert_output("return_string.eddi", "abcdef");
}

BOOST_AUTO_TEST_CASE( int_functions ){
    assert_output("return_int.eddi", "484");
}

BOOST_AUTO_TEST_CASE( recursive_functions ){
    assert_output("recursive.eddi", "362880");
}

BOOST_AUTO_TEST_CASE( math ){
    assert_output("math.eddi", "333|111|-111|0|24642|2|-2|-1|1|2|0|-111|");
}

BOOST_AUTO_TEST_CASE( builtin ){
    assert_output("builtin.eddi", "10|11|12|13|12|13|10|11|4|8|13|8|0|3|");
}

BOOST_AUTO_TEST_CASE( assign_value ){
    assert_output("assign_value.eddi", "66779921");
}

BOOST_AUTO_TEST_CASE( concat ){
    assert_output("concat.eddi", "asdf1234|1234asdf|asdfasdf|12341234|");
}

BOOST_AUTO_TEST_CASE( prints ){
    assert_output_32("prints.eddi", "111|0|-111|0|1|999.9899|1.0089|0.0|-1.0089|-999.9899||-0|asdf|1234asdf|");
    assert_output_64("prints.eddi", "111|0|-111|0|1|999.9900|1.0089|0.0|-1.0089|-999.9900||-0|asdf|1234asdf|");
}

BOOST_AUTO_TEST_CASE( structures ){
    assert_output_32("structures.eddi", "222|666|3.2300|0|asdf|333|888|4.3299|1|ertz|333|888|4.3299|1|ertz|");
    assert_output_64("structures.eddi", "222|666|3.2300|0|asdf|333|888|4.3300|1|ertz|333|888|4.3300|1|ertz|");
}

BOOST_AUTO_TEST_CASE( nested ){
    assert_output_32("nested.eddi", "222|555|333|444|2222|5555|3333|4444||222|555|333|444|2222|5555|3333|4444|");
    assert_output_64("nested.eddi", "222|555|333|444|2222|5555|3333|4444||222|555|333|444|2222|5555|3333|4444|");
}

BOOST_AUTO_TEST_CASE( args ){
    assertCompiles("test/cases/args.eddi", "--32");

    std::string out = eddic::execCommand("./a.out");
    BOOST_CHECK_EQUAL ("./a.out|", out);

    out = eddic::execCommand("./a.out arg1 arg2 arg3");
    BOOST_CHECK_EQUAL ("./a.out|arg1|arg2|arg3|", out);

    assertCompiles("test/cases/args.eddi", "--64");

    out = eddic::execCommand("./a.out");
    BOOST_CHECK_EQUAL ("./a.out|", out);

    out = eddic::execCommand("./a.out arg1 arg2 arg3");
    BOOST_CHECK_EQUAL ("./a.out|arg1|arg2|arg3|", out);
}

BOOST_AUTO_TEST_SUITE_END()

/* Verify that the compilation fails for invalid statements */

BOOST_FIXTURE_TEST_SUITE(CompilationErrorsSuite, DeleteOutFixture)

BOOST_AUTO_TEST_CASE( params_assign ){
    assert_compilation_error("params_assign.eddi", "--32");
    assert_compilation_error("params_assign.eddi", "--64");
}

BOOST_AUTO_TEST_SUITE_END()

/* Standard library test suite  */

BOOST_FIXTURE_TEST_SUITE(StandardLibSuite, DeleteOutFixture)

BOOST_AUTO_TEST_CASE( std_lib_arrays_sum ){
    assert_output("stdlib_array_sum.eddi", "100");
}

BOOST_AUTO_TEST_CASE( std_lib_math_min ){
    assert_output("stdlib_math_min.eddi", "999|0|0|-1|0|-1");
}

BOOST_AUTO_TEST_CASE( std_lib_math_max ){
    assert_output("stdlib_math_max.eddi", "1000|1|1|0|0|0");
}

BOOST_AUTO_TEST_CASE( std_lib_math_factorial ){
    assert_output("stdlib_math_factorial.eddi", "1|1|2|362880");
}

BOOST_AUTO_TEST_CASE( std_lib_math_pow ){
    assert_output("stdlib_math_pow.eddi", "0|1|10|100|1024|1");
}

BOOST_AUTO_TEST_SUITE_END()

/* Unit test for bug fixes regression */

BOOST_FIXTURE_TEST_SUITE(BugFixesSuite, DeleteOutFixture)

BOOST_AUTO_TEST_CASE( while_bug ){
    assert_output("while_bug.eddi", "W1W2W3W4W5");
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>/*
	Convert to binary representation - conversion procedures

	Author  : Wojciech Muła, Larry Bank
	Date    : 2014-09-11, 2015-04-18
	License : BSD
*/

#include <cstdio>
#include <cstdint>
#include <cstring>

#define SIMD_ALIGN __attribute__((aligned(16)))
#define packed_byte(x)   {x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x}

// constants for SIMD version
uint8_t bit_mask[16] SIMD_ALIGN = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
uint8_t ascii[16]    SIMD_ALIGN = packed_byte('0');

namespace convert_to_bin {

// --- naive --------------------------------------------------------------

uint64_t naive(uint8_t v) {

	union {
		uint64_t qword;
		uint8_t  bytes[8];
	} result;

	for (int i=7; i >= 0; i--) {

		const uint8_t bit = (1 << i);

		result.bytes[i] = (v & bit) ? '1' : '0';
	}

	return result.qword;
}

// --- lookup -------------------------------------------------------------

static uint64_t lookup_table[256];

uint64_t lookup(uint8_t v) {
	return lookup_table[v];
}

void prepare_lookup() {
    for (int i=0; i < 256; i++) {
        lookup_table[i] = naive(i);
    }
}

// --- SWAR version -------------------------------------------------------

uint64_t swar(uint8_t v) {

	const uint64_t r1 =  v * 0x0101010101010101;
	const uint64_t r2 = r1 & 0x8040201008040201;
	const uint64_t r3 = r2 + 0x00406070787c7e7f;
	const uint64_t r4 = (r3 >> 7) & 0x0101010101010101;

	return 0x3030303030303030 + r4;  // ord('0') == 0x30
}

// --- SWAR version 2 -----------------------------------------------------

uint64_t swar2(uint8_t v) {

    const uint32_t mul = 1 + (1 << (8 - 1)) + (1 << (16 - 2)) + (1 << (24 - 3));
    const uint32_t r1 = (v & 0xf) * mul;
    const uint32_t r2 = (v >> 4) * mul;

    const uint64_t r3 = r1 | (uint64_t(r2) << 32);
    const uint64_t r4 = r3 & 0x0101010101010101;

    return 0x3030303030303030 + r4;
}

// --- SWAR version 3 -----------------------------------------------------
// author: Larry Bank

uint64_t swar3(uint8_t v) {

    // convert lowest 7 bits
    const uint64_t mul = 0x02040810204081;
    const uint64_t r1  = (v & 0x7f) * mul;
    const uint64_t r2  = r1 & 0x0101010101010101;

    // move the most significant bit to 56th bit
#if 0
    const uint64_t r3  = uint64_t(v & 0x80) << (56 - 7);
#else
    const uint64_t r3  = uint64_t(int64_t(int8_t(v))) & 0x0100000000000000;
#endif
    const uint64_t r4  = r2 | r3;

    return 0x3030303030303030 + r4;
}

// --- SIMD version -------------------------------------------------------

#ifdef ARCH_64BIT
uint64_t simd(uint8_t v) {

    uint64_t result;

	__asm__ __volatile__ (
		// 1. populate byte
		"movd       %1,  %%xmm0    \n"
		"punpcklbw  %%xmm0, %%xmm0    \n"

		// 2. mask bits
		"pand       %2, %%xmm0  \n"
		"pcmpeqb    %2, %%xmm0  \n"

		// 3. convert to ASCII
		"movdqa     %3, %%xmm1     \n"
		"psubb      %%xmm0, %%xmm1    \n"

		// save result
		"movq       %%xmm1, %0   \n"

		: "=r" (result)

		: "r" (0x01010101 * v)
        , "m" (bit_mask)
        , "m" (ascii)

        : "memory"
	);

	return result;
}
#else
uint64_t simd(uint8_t v) {

    uint64_t result;

	__asm__ __volatile__ (
		// 1. populate byte
		"movd       %0,  %%xmm0    \n"
		"punpcklbw  %%xmm0, %%xmm0    \n"

		// 2. mask bits
		"pand       %1, %%xmm0  \n"
		"pcmpeqb    %1, %%xmm0  \n"

		// 3. convert to ASCII
		"movdqa     %2, %%xmm1     \n"
		"psubb      %%xmm0, %%xmm1    \n"

		// save result
		"movq       %%xmm1, (%3)   \n"

		: /* no output */

		: "r" (0x01010101 * v)
        , "m" (bit_mask)
        , "m" (ascii)
        , "r" (&result)

        : "memory"
	);

	return result;
}
#endif

// --- PDEP version -------------------------------------------------------

namespace CPU {

#ifdef HAVE_PDEP_INSTRUCTION
uint64_t pdep(uint64_t src1, uint64_t src2) {
    uint64_t result;

    __asm__ __volatile__(
        "pdep %1, %2, %0"
        : "=r" (result)
        : "r" (src1)
        , "r" (src2)
    );

    return result;
}
#else
uint64_t pdep(uint64_t src1, uint64_t src2) {
    uint64_t result = 0;

    int k = 0;
    for (int i=0; i < 64; i++) {
        const uint64_t mask = (1llu << i);

        if (src1 & mask) {
            if (src2 & (1llu << k)) {
                result |= mask;
            }
            k += 1;
        }
    }

    return result;
}
#endif

uint64_t bswap(uint64_t qword) {
    union {
        uint64_t qword;
        uint8_t  bytes[8];
    } result;

    result.qword = qword;

    for (int i=0; i < 4; i++) {
        const uint8_t t = result.bytes[i];

        result.bytes[i] = result.bytes[7 - i];
        result.bytes[7 - i] = t;
    }

    return result.qword;
}

} // namespace CPU

uint64_t pdep(uint8_t v) {

    const uint64_t expanded = CPU::pdep(0x0101010101010101, v);

	return 0x3030303030303030 + expanded;
}

} // namespace conv_to_bin

<commit_msg>conv_to_bin: link to Larry's profile<commit_after>/*
	Convert to binary representation - conversion procedures

	Author  : Wojciech Muła, Larry Bank (https://github.com/bitbank2)
	Date    : 2014-09-11, 2015-04-18
	License : BSD
*/

#include <cstdio>
#include <cstdint>
#include <cstring>

#define SIMD_ALIGN __attribute__((aligned(16)))
#define packed_byte(x)   {x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x}

// constants for SIMD version
uint8_t bit_mask[16] SIMD_ALIGN = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
uint8_t ascii[16]    SIMD_ALIGN = packed_byte('0');

namespace convert_to_bin {

// --- naive --------------------------------------------------------------

uint64_t naive(uint8_t v) {

	union {
		uint64_t qword;
		uint8_t  bytes[8];
	} result;

	for (int i=7; i >= 0; i--) {

		const uint8_t bit = (1 << i);

		result.bytes[i] = (v & bit) ? '1' : '0';
	}

	return result.qword;
}

// --- lookup -------------------------------------------------------------

static uint64_t lookup_table[256];

uint64_t lookup(uint8_t v) {
	return lookup_table[v];
}

void prepare_lookup() {
    for (int i=0; i < 256; i++) {
        lookup_table[i] = naive(i);
    }
}

// --- SWAR version -------------------------------------------------------

uint64_t swar(uint8_t v) {

	const uint64_t r1 =  v * 0x0101010101010101;
	const uint64_t r2 = r1 & 0x8040201008040201;
	const uint64_t r3 = r2 + 0x00406070787c7e7f;
	const uint64_t r4 = (r3 >> 7) & 0x0101010101010101;

	return 0x3030303030303030 + r4;  // ord('0') == 0x30
}

// --- SWAR version 2 -----------------------------------------------------

uint64_t swar2(uint8_t v) {

    const uint32_t mul = 1 + (1 << (8 - 1)) + (1 << (16 - 2)) + (1 << (24 - 3));
    const uint32_t r1 = (v & 0xf) * mul;
    const uint32_t r2 = (v >> 4) * mul;

    const uint64_t r3 = r1 | (uint64_t(r2) << 32);
    const uint64_t r4 = r3 & 0x0101010101010101;

    return 0x3030303030303030 + r4;
}

// --- SWAR version 3 -----------------------------------------------------
// author: Larry Bank

uint64_t swar3(uint8_t v) {

    // convert lowest 7 bits
    const uint64_t mul = 0x02040810204081;
    const uint64_t r1  = (v & 0x7f) * mul;
    const uint64_t r2  = r1 & 0x0101010101010101;

    // move the most significant bit to 56th bit
#if 0
    const uint64_t r3  = uint64_t(v & 0x80) << (56 - 7);
#else
    const uint64_t r3  = uint64_t(int64_t(int8_t(v))) & 0x0100000000000000;
#endif
    const uint64_t r4  = r2 | r3;

    return 0x3030303030303030 + r4;
}

// --- SIMD version -------------------------------------------------------

#ifdef ARCH_64BIT
uint64_t simd(uint8_t v) {

    uint64_t result;

	__asm__ __volatile__ (
		// 1. populate byte
		"movd       %1,  %%xmm0    \n"
		"punpcklbw  %%xmm0, %%xmm0    \n"

		// 2. mask bits
		"pand       %2, %%xmm0  \n"
		"pcmpeqb    %2, %%xmm0  \n"

		// 3. convert to ASCII
		"movdqa     %3, %%xmm1     \n"
		"psubb      %%xmm0, %%xmm1    \n"

		// save result
		"movq       %%xmm1, %0   \n"

		: "=r" (result)

		: "r" (0x01010101 * v)
        , "m" (bit_mask)
        , "m" (ascii)

        : "memory"
	);

	return result;
}
#else
uint64_t simd(uint8_t v) {

    uint64_t result;

	__asm__ __volatile__ (
		// 1. populate byte
		"movd       %0,  %%xmm0    \n"
		"punpcklbw  %%xmm0, %%xmm0    \n"

		// 2. mask bits
		"pand       %1, %%xmm0  \n"
		"pcmpeqb    %1, %%xmm0  \n"

		// 3. convert to ASCII
		"movdqa     %2, %%xmm1     \n"
		"psubb      %%xmm0, %%xmm1    \n"

		// save result
		"movq       %%xmm1, (%3)   \n"

		: /* no output */

		: "r" (0x01010101 * v)
        , "m" (bit_mask)
        , "m" (ascii)
        , "r" (&result)

        : "memory"
	);

	return result;
}
#endif

// --- PDEP version -------------------------------------------------------

namespace CPU {

#ifdef HAVE_PDEP_INSTRUCTION
uint64_t pdep(uint64_t src1, uint64_t src2) {
    uint64_t result;

    __asm__ __volatile__(
        "pdep %1, %2, %0"
        : "=r" (result)
        : "r" (src1)
        , "r" (src2)
    );

    return result;
}
#else
uint64_t pdep(uint64_t src1, uint64_t src2) {
    uint64_t result = 0;

    int k = 0;
    for (int i=0; i < 64; i++) {
        const uint64_t mask = (1llu << i);

        if (src1 & mask) {
            if (src2 & (1llu << k)) {
                result |= mask;
            }
            k += 1;
        }
    }

    return result;
}
#endif

uint64_t bswap(uint64_t qword) {
    union {
        uint64_t qword;
        uint8_t  bytes[8];
    } result;

    result.qword = qword;

    for (int i=0; i < 4; i++) {
        const uint8_t t = result.bytes[i];

        result.bytes[i] = result.bytes[7 - i];
        result.bytes[7 - i] = t;
    }

    return result.qword;
}

} // namespace CPU

uint64_t pdep(uint8_t v) {

    const uint64_t expanded = CPU::pdep(0x0101010101010101, v);

	return 0x3030303030303030 + expanded;
}

} // namespace conv_to_bin

<|endoftext|>


<commit_before>#include<iostream>
#include<algorithm>
#include<unordered_map>
#include<queue>
#include<sstream>
#include<cstdio>
#define MAXBITS 12
#define len(x) (int)(x).size()
using namespace std;

typedef unordered_map< bitset<MAXBITS>, vector< bitset<MAXBITS> > > State;

/**
 * Prints instructions for usage of programming to standard out.
 **/
void usage(){
    cout << "Usage:\n\tsim N K [LOG]\n";
    cout << "\tN - number to create a superset on in base 10 and greater than 0\n";
    cout << "\tK - maximum number of neighbours each element can have\n";
    cout << "\tLOG - optional, print the game to standard out, pass in 1 for yes, 0 for no\n";
}

/**
 * Determine if two bitsets a,b differ by at most one bit.
 **/
bool differ_by_one_bit(const bitset<MAXBITS>&a, const bitset<MAXBITS>&b){
    int cnt = 0;
    for(int i = 0;i < MAXBITS;i++){
        if(a[i] != b[i]){
            cnt++;
        }
    }
    return cnt == 1;
}

/**
 * Returns the first N bits from a bit in little-endian
 * */
string get_first_n_bits(const bitset<MAXBITS>&b, const int &N){
    string bin = b.to_string();
    return bin.substr(bin.size()-N, N);
}

/**
 * Prints out the adjacency list representation of the State object.
 **/
void print_state(const State &st, const int &N){
    for(auto it: st){
        bitset<MAXBITS>node = it.first;
        vector< bitset<MAXBITS> >edges = it.second;
        cout << "node " << get_first_n_bits(node, N) << "(" << node.to_ulong() << ")" << " adj:";
        for(auto &adj_node: edges){
            cout << get_first_n_bits(adj_node, N) << "(" << adj_node.to_ulong() << ")" << " ";
        }
        cout << "\n";
    }
    cout << "\n";
}

/**
 * Obtain the argument values N and K from arguments pass to the program,
 * then stores it in the respective variables. Returns a 0 on successful validation of
 * input, -1 otherwise.
 **/
int get_nk_log(int argc, char **argv, int *N, int *K, int *LOG){
    string arg_one(argv[1]);
    string arg_two(argv[2]);
    stringstream ss;

    ss << arg_one;
    ss >> *N;
    if(!ss){
        return -1;
    }
    ss.clear();

    ss << arg_two;
    ss >> *K;
    if(!ss){
        return -1;
    }
    ss.clear();

    if(argc == 4){// optinal command, LOG
        string arg_three(argv[3]);
        ss << arg_three;
        ss >> *LOG;
        if(!ss){
            return -1;
        } else if(*LOG != 0 && *LOG != 1){
            return -1;
        }
        ss.clear();
    }else{
        *LOG = 0;// default to 0

    }

    return 0;
}

/**
 * Creates a new graph by removing all nodes and edges connecting to nodes
 * which have the designed bit value in the given index.
 * */
State construct_new_graph(const State &st, int index, int designated_bit){
    State st_cpy = st;
    for(auto it: st){
        bitset<MAXBITS>node = it.first;
        if(node[index] == designated_bit){
            st_cpy.erase(node);
        }else{
            vector< bitset<MAXBITS> >edges = it.second;
            vector< bitset<MAXBITS> >new_adj;
            for(int i = 0;i < len(edges);i++){
                if(edges[i][index] != designated_bit){
                    new_adj.push_back(edges[i]);
                }
            }
            st_cpy.erase(node);
            st_cpy[node] = new_adj;
        }
    }
    return st_cpy;
}

bool has_at_least_one_edge(const State &st){
    for(auto it:st){
        vector< bitset<MAXBITS> >edges = it.second;
        if(len(edges) > 0){
            return true;
        }
    }
    return false;
}

/**
 * Determines if there exists an optimal strategy on this subgraph.
 */
bool optimal_strategy(const State &st, bitset<MAXBITS>&used_bits, int n){
    if(!has_at_least_one_edge(st)){
        return false;
    } else if(n != 1){
        bool pos = true;
        for(int i = 0;pos && i < MAXBITS;i++){
            if(!used_bits[i]){
                used_bits[i] = 1;
                // try finding an optimal strategy by removing ith bit to 1
                State graph_one_removed = construct_new_graph(st, i, 1);
                State graph_zero_removed = construct_new_graph(st, i, 0);
                bool result = false;
                result |= optimal_strategy(graph_one_removed, used_bits, n-1);
                if(result){ // skip ahead since strategy exists
                    used_bits[i]=0;
                    continue;
                }
                result |= optimal_strategy(graph_zero_removed, used_bits, n-1);
                used_bits[i] = 0;
                pos &= result;
            }
        }
        return pos;
    }else{
        return has_at_least_one_edge(st);
    }
}

void simulate(int N, int K, int LOG){
    bitset<MAXBITS>start, used_bits;
    State start_adj;
    queue< State >q;
    start_adj[start] = vector< bitset<MAXBITS> >();
    q.push(start_adj);
    while(!q.empty()){
        State st = q.front();
        q.pop();
        if(LOG){
            printf("current graph:\n");
            print_state(st, N);
        }
        if(optimal_strategy(st, used_bits, N)){
            printf("Subgraph found\n");
            print_state(st, N);
            return;
        }
        for(auto it: st){
            bitset<MAXBITS>node = it.first;
            vector< bitset<MAXBITS> >edges = it.second;
            // check if the flipped node is already in our
            for(int i = 0;i < N;i++){
                node[i] = ~node[i];
                if(st.find(node) == st.end()){
                    // determine all nodes which differ by one bit with
                    // new node we're going to add. And determine if once
                    // this node is added whether or not the graph is still
                    // maximal K
                    bool valid = true;
                    for(auto jt:st){
                        bitset<MAXBITS>adj_node= jt.first;
                        // adding this node breaks the maximal k property
                        if(differ_by_one_bit(node, adj_node) && len(st[adj_node])+1 > K){
                            valid = false;
                            break;
                        }
                    }
                    if(valid){
                        // now add edges for nodes which differ by one bit
                        // with the new node we're adding to the graph
                        State st_cpy = st;
                        for(auto jt:st_cpy){
                            bitset<MAXBITS>adj_node = jt.first;
                            if(differ_by_one_bit(node, adj_node)){
                                st_cpy[node].push_back(adj_node);
                                st_cpy[adj_node].push_back(node);
                            }
                        }
                        q.push(st_cpy);
                    }
                }
                node[i] = ~node[i];
            }
        }
    }
}

int main(int argc, char**argv) {
    if(argc <= 1 or argc > 4){
        usage();
        exit(1);
    }else{
        int N, K, LOG;
        int result = get_nk_log(argc, argv, &N, &K, &LOG);
        if(result < 0){
            usage();
            exit(1);
        }else{
            simulate(N, K, LOG);
        }
    }
    return 0;
}
<commit_msg>added commented out code for memoizing<commit_after>#include<iostream>
#include<algorithm>
#include<unordered_map>
#include<queue>
#include<sstream>
#include<cstdio>
#define MAXBITS 12
#define len(x) (int)(x).size()
using namespace std;

typedef unordered_map< bitset<MAXBITS>, vector< bitset<MAXBITS> > > State;

/**
 * Prints instructions for usage of programming to standard out.
 **/
void usage(){
    cout << "Usage:\n\tsim N K [LOG]\n";
    cout << "\tN - number to create a superset on in base 10 and greater than 0\n";
    cout << "\tK - maximum number of neighbours each element can have\n";
    cout << "\tLOG - optional, print the game to standard out, pass in 1 for yes, 0 for no\n";
}

/**
 * Determine if two bitsets a,b differ by at most one bit.
 **/
bool differ_by_one_bit(const bitset<MAXBITS>&a, const bitset<MAXBITS>&b){
    int cnt = 0;
    for(int i = 0;i < MAXBITS;i++){
        if(a[i] != b[i]){
            cnt++;
        }
    }
    return cnt == 1;
}

/**
 * Returns the first N bits from a bit in little-endian
 * */
string get_first_n_bits(const bitset<MAXBITS>&b, const int &N){
    string bin = b.to_string();
    return bin.substr(bin.size()-N, N);
}

/**
 * Prints out the adjacency list representation of the State object.
 **/
void print_state(const State &st, const int &N){
    for(auto it: st){
        bitset<MAXBITS>node = it.first;
        vector< bitset<MAXBITS> >edges = it.second;
        cout << "node " << get_first_n_bits(node, N) << "(" << node.to_ulong() << ")" << " adj:";
        for(auto &adj_node: edges){
            cout << get_first_n_bits(adj_node, N) << "(" << adj_node.to_ulong() << ")" << " ";
        }
        cout << "\n";
    }
    cout << "\n";
}

/**
 * Obtain the argument values N and K from arguments pass to the program,
 * then stores it in the respective variables. Returns a 0 on successful validation of
 * input, -1 otherwise.
 **/
int get_nk_log(int argc, char **argv, int *N, int *K, int *LOG){
    string arg_one(argv[1]);
    string arg_two(argv[2]);
    stringstream ss;

    ss << arg_one;
    ss >> *N;
    if(!ss){
        return -1;
    }
    ss.clear();

    ss << arg_two;
    ss >> *K;
    if(!ss){
        return -1;
    }
    ss.clear();

    if(argc == 4){// optinal command, LOG
        string arg_three(argv[3]);
        ss << arg_three;
        ss >> *LOG;
        if(!ss){
            return -1;
        } else if(*LOG != 0 && *LOG != 1){
            return -1;
        }
        ss.clear();
    }else{
        *LOG = 0;// default to 0

    }

    return 0;
}

/** Maps a Graph to 1-10000007, using the muliplication method.
 * */
unsigned long create_hash(const State &st){
    #define MOD (1000007)
    unsigned long ret = 1;
    for(auto it: st){
        ret *= it.first.to_ulong()+1;
        //ret = (ret%MOD * (it.first.to_ulong()+1)%MOD)%MOD;
    }
    #undef MOD
    return ret;
}

/**
 * Creates a new graph by removing all nodes and edges connecting to nodes
 * which have the designed bit value in the given index.
 * */
State construct_new_graph(const State &st, int index, int designated_bit){
    State st_cpy = st;
    for(auto it: st){
        bitset<MAXBITS>node = it.first;
        if(node[index] == designated_bit){
            st_cpy.erase(node);
        }else{
            vector< bitset<MAXBITS> >edges = it.second;
            vector< bitset<MAXBITS> >new_adj;
            for(int i = 0;i < len(edges);i++){
                if(edges[i][index] != designated_bit){
                    new_adj.push_back(edges[i]);
                }
            }
            st_cpy.erase(node);
            st_cpy[node] = new_adj;
        }
    }
    return st_cpy;
}

bool has_at_least_one_edge(const State &st){
    for(auto it:st){
        vector< bitset<MAXBITS> >edges = it.second;
        if(len(edges) > 0){
            return true;
        }
    }
    return false;
}

unordered_multimap<unsigned long, bool>computed_graphs;

/**
 * Determines if there exists an optimal strategy on this subgraph.
 */
bool optimal_strategy(const State &st, bitset<MAXBITS>&used_bits, int n){
    //unsigned long hash = create_hash(st);
    if(!has_at_least_one_edge(st)){
        //computed_graphs.insert(pair<int,bool>(hash, false));
        return false;
    }
    // else if(computed_graphs.find(hash) != computed_graphs.end()){
    //     cout << "computed!" << endl;
    //     for(auto it:st){
    //         cout << it.first.to_ulong() << " ";
    //     }
    //     cout << "\nhash: ";
    //     cout << create_hash(st) << endl;
    //     cout << endl;
    //     cout << computed_graphs.find(hash)->second << endl;
    //     return computed_graphs.find(hash)->second;
    // }
    else if(n != 1){
        bool pos = true;
        for(int i = 0;pos && i < MAXBITS;i++){
            if(!used_bits[i]){
                used_bits[i] = 1;
                // try finding an optimal strategy by removing ith bit to 1
                State graph_one_removed = construct_new_graph(st, i, 1);
                State graph_zero_removed = construct_new_graph(st, i, 0);
                bool result = false;
                result |= optimal_strategy(graph_one_removed, used_bits, n-1);
                if(result){ // skip ahead since strategy exists
                    used_bits[i]=0;
                    continue;
                }
                result |= optimal_strategy(graph_zero_removed, used_bits, n-1);
                used_bits[i] = 0;
                pos &= result;
            }
        }
        //computed_graphs.insert(pair<unsigned long,bool>(hash, pos));
        return pos;
    }else{
        return has_at_least_one_edge(st);
    }
}

void simulate(int N, int K, int LOG){
    bitset<MAXBITS>start, used_bits;
    State start_adj;
    queue< State >q;
    start_adj[start] = vector< bitset<MAXBITS> >();
    q.push(start_adj);
    while(!q.empty()){
        State st = q.front();
        q.pop();
        if(LOG){
            cout << "current graph: ";
            for(auto it:st){
                cout << it.first.to_ulong() << " ";
            }
            cout << "\nHash: ";
            cout << create_hash(st) << endl;
            cout << endl;
            print_state(st, N);
        }
        if(optimal_strategy(st, used_bits, N)){
            cout << "Subgraph found\n" << endl;
            print_state(st, N);
            exit(0);
        }
        for(auto it: st){
            bitset<MAXBITS>node = it.first;
            vector< bitset<MAXBITS> >edges = it.second;
            // check if the flipped node is already in our
            for(int i = 0;i < N;i++){
                node[i] = ~node[i];
                if(st.find(node) == st.end()){
                    // determine all nodes which differ by one bit with
                    // new node we're going to add. And determine if once
                    // this node is added whether or not the graph is still
                    // maximal K
                    bool valid = true;
                    for(auto jt:st){
                        bitset<MAXBITS>adj_node= jt.first;
                        // adding this node breaks the maximal k property
                        if(differ_by_one_bit(node, adj_node) && len(st[adj_node])+1 > K){
                            valid = false;
                            break;
                        }
                    }
                    if(valid){
                        // now add edges for nodes which differ by one bit
                        // with the new node we're adding to the graph
                        State st_cpy = st;
                        for(auto jt:st_cpy){
                            bitset<MAXBITS>adj_node = jt.first;
                            if(differ_by_one_bit(node, adj_node)){
                                st_cpy[node].push_back(adj_node);
                                st_cpy[adj_node].push_back(node);
                            }
                        }
                        q.push(st_cpy);
                    }
                }
                node[i] = ~node[i];
            }
        }
    }
}

int main(int argc, char**argv) {
    if(argc <= 1 or argc > 4){
        usage();
        exit(1);
    }else{
        int N, K, LOG;
        int result = get_nk_log(argc, argv, &N, &K, &LOG);
        if(result < 0){
            usage();
            exit(1);
        }else{
            simulate(N, K, LOG);
            cout << "No subgraph found" << endl;
        }
    }
    return 0;
}
<|endoftext|>


<commit_before>// @(#)root/base:$Id$
// Author: Andreas-Joachim Peters   20/9/2005

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TFileInfo                                                            //
//                                                                      //
// Class describing a generic file including meta information.          //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "Riostream.h"
#include "TFileInfo.h"
#include "TRegexp.h"
#include "TSystem.h"
#include "TClass.h"

ClassImp(TFileInfo)
ClassImp(TFileInfoMeta)

//______________________________________________________________________________
TFileInfo::TFileInfo(const char *url, Long64_t size, const char *uuid,
                     const char *md5, TObject *meta)
   : fCurrentUrl(0), fUrlList(0), fSize(size), fUUID(0), fMD5(0),
     fMetaDataList(0)
{
   // Constructor.

   if (uuid)
      fUUID = new TUUID(uuid);
   else
      fUUID = new TUUID;

   if (md5)
      fMD5 = new TMD5((const UChar_t*)md5);
   else
      fMD5 = new TMD5;

   // Set's the name from the UUID.
   SetName(fUUID->AsString());
   SetTitle("TFileInfo");

   if (url)
      AddUrl(url);

   if (meta)
      AddMetaData(meta);
}

//______________________________________________________________________________
TFileInfo::TFileInfo(const TFileInfo &fi) : TNamed(fi.GetName(), fi.GetTitle()),
                                            fCurrentUrl(0), fUrlList(0),
                                            fSize(fi.fSize), fUUID(0), fMD5(0),
                                            fMetaDataList(0)
{
   // Copy constructor

   if (fi.fUrlList) {
      fUrlList = new TList;
      fUrlList->SetOwner();
      TIter nxu(fi.fUrlList);
      TUrl *u = 0;
      while ((u = (TUrl *)nxu())) {
         fUrlList->Add(new TUrl(u->GetUrl(), kTRUE));
      }
      ResetUrl();
   }
   fSize = fi.fSize;

   if (fi.fUUID)
      fUUID = new TUUID(fi.fUUID->AsString());

   if (fi.fMD5)
      fMD5 = new TMD5(*(fi.fMD5));

   // Staged and corrupted bits
   ResetBit(TFileInfo::kStaged);
   ResetBit(TFileInfo::kCorrupted);
   if (fi.TestBit(TFileInfo::kStaged)) SetBit(TFileInfo::kStaged);
   if (fi.TestBit(TFileInfo::kCorrupted)) SetBit(TFileInfo::kCorrupted);

   if (fi.fMetaDataList) {
      fMetaDataList = new TList;
      fMetaDataList->SetOwner();
      TIter nxm(fi.fMetaDataList);
      TFileInfoMeta *fim = 0;
      while ((fim = (TFileInfoMeta *)nxm())) {
         fMetaDataList->Add(new TFileInfoMeta(*fim));
      }
   }
}

//______________________________________________________________________________
TFileInfo::~TFileInfo()
{
   // Destructor.

   SafeDelete(fMetaDataList);
   SafeDelete(fUUID);
   SafeDelete(fMD5);
   SafeDelete(fUrlList);
}

//______________________________________________________________________________
void TFileInfo::SetUUID(const char *uuid)
{
   // Set the UUID to the value associated to the string 'uuid'. This is
   // useful to set the UUID to the one of the ROOT file during verification.
   // NB: we do not change the name in here, because this would screw up lists
   //     of these objects hashed on the name. Those lists need to be rebuild.
   //     TFileCollection does that in RemoveDuplicates.

   if (uuid) {
      if (fUUID) delete fUUID;
      fUUID = new TUUID(uuid);
   }
}

//______________________________________________________________________________
TUrl *TFileInfo::GetCurrentUrl() const
{
   // Return the current url.

   if (!fCurrentUrl)
      const_cast<TFileInfo*>(this)->ResetUrl();
   return fCurrentUrl;
}

//______________________________________________________________________________
TUrl *TFileInfo::NextUrl()
{
   // Iterator function, start iteration by calling ResetUrl().
   // The first call to NextUrl() will return the 1st element,
   // the seconde the 2nd element etc. Returns 0 in case no more urls.

   if (!fUrlList)
      return 0;

   TUrl *returl = fCurrentUrl;

   if (fCurrentUrl)
      fCurrentUrl = (TUrl*)fUrlList->After(fCurrentUrl);

   return returl;
}

//______________________________________________________________________________
TUrl *TFileInfo::FindByUrl(const char *url, Bool_t withDeflt)
{
   // Find an element from a URL. Returns 0 if not found.

   TIter nextUrl(fUrlList);
   TUrl *urlelement;

   TRegexp rg(url);
   while  ((urlelement = (TUrl*) nextUrl())) {
      if (TString(urlelement->GetUrl(withDeflt)).Index(rg) != kNPOS) {
         return urlelement;
      }
   }
   return 0;
}

//______________________________________________________________________________
Bool_t TFileInfo::AddUrl(const char *url, Bool_t infront)
{
   // Add a new URL. If 'infront' is TRUE the new url is pushed at the beginning
   // of the list; otherwise is pushed back.
   // Returns kTRUE if successful, kFALSE otherwise.

   if (FindByUrl(url))
      return kFALSE;

   if (!fUrlList) {
      fUrlList = new TList;
      fUrlList->SetOwner();
   }

   TUrl *newurl = new TUrl(url, kTRUE);
   // We set the current Url to the first url added
   if (fUrlList->GetSize() == 0)
      fCurrentUrl = newurl;

   if (infront)
      fUrlList->AddFirst(newurl);
   else
      fUrlList->Add(newurl);
   return kTRUE;
}

//______________________________________________________________________________
Bool_t TFileInfo::RemoveUrl(const char *url)
{
   // Remove an URL. Returns kTRUE if successful, kFALSE otherwise.

   TUrl *lurl;
   if ((lurl = FindByUrl(url))) {
      fUrlList->Remove(lurl);
      if (lurl == fCurrentUrl)
         ResetUrl();
      delete lurl;
      return kTRUE;
   }
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TFileInfo::SetCurrentUrl(const char *url)
{
   // Set 'url' as current URL, if in the list
   // Return kFALSE if not in the list

   TUrl *lurl;
   if ((lurl = FindByUrl(url))) {
      fCurrentUrl = lurl;
      return kTRUE;
   }
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TFileInfo::SetCurrentUrl(TUrl *url)
{
   // Set 'url' as current URL, if in the list
   // Return kFALSE if not in the list

   if (url && fUrlList && fUrlList->FindObject(url)) {
      fCurrentUrl = url;
      return kTRUE;
   }
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TFileInfo::AddMetaData(TObject *meta)
{
   // Add's a meta data object to the file info object. The object will be
   // adopted by the TFileInfo and should not be deleted by the user.
   // Typically objects of class TFileInfoMeta or derivatives should be added,
   // but any class is accepted.
   // Returns kTRUE if successful, kFALSE otherwise.

   if (meta) {
      if (!fMetaDataList) {
         fMetaDataList = new TList;
         fMetaDataList->SetOwner();
      }
      fMetaDataList->Add(meta);
      return kTRUE;
   }
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TFileInfo::RemoveMetaData(const char *meta)
{
   // Remove the metadata obeject. If meta is 0 remove all meta data objects.
   // Returns kTRUE if successful, kFALSE otherwise.

   if (fMetaDataList) {
      if (!meta || strlen(meta) <= 0) {
         SafeDelete(fMetaDataList);
         return kTRUE;
      } else {
         TObject *o = fMetaDataList->FindObject(meta);
         if (o) {
            fMetaDataList->Remove(o);
            delete o;
            return kTRUE;
         }
      }
   }
   return kFALSE;
}

//______________________________________________________________________________
TFileInfoMeta *TFileInfo::GetMetaData(const char *meta) const
{
   // Get meta data object with specified name. If meta is 0
   // get first meta data object. Returns 0 in case no
   // suitable meta data object is found.

   if (fMetaDataList) {
      TFileInfoMeta *m;
      if (!meta || strlen(meta) <= 0)
         m = (TFileInfoMeta *) fMetaDataList->First();
      else
         m = (TFileInfoMeta *) fMetaDataList->FindObject(meta);
      if (m) {
         TClass *c = m->IsA();
         return (c && c->InheritsFrom("TFileInfoMeta")) ? m : 0;
      }
   }
   return 0;
}

//______________________________________________________________________________
Int_t TFileInfo::Compare(const TObject *obj) const
{
   // Compare TFileInfo object by their first urls.

   if (this == obj) return 0;
   if (TFileInfo::Class() != obj->IsA()) return -1;
   return (GetFirstUrl()->Compare(((TFileInfo*)obj)->GetFirstUrl()));
}

//______________________________________________________________________________
void TFileInfo::Print(Option_t * /* option */) const
{
   // Print information about this object.

   GetMD5()->Final();
   cout << "UUID: " << GetUUID()->AsString() << "\n"
        << "MD5:  " << GetMD5()->AsString() << "\n"
        << "Size: " << GetSize() << endl;

   TIter next(fUrlList);
   TUrl *u;
   cout << " === URLs ===" << endl;
   while ((u = (TUrl*)next()))
      cout << " URL: " << u->GetUrl() << endl;

   TIter nextm(fMetaDataList);
   TObject *m = 0;   // can be any TObject not only TFileInfoMeta
   while ((m = (TObject*) nextm())) {
      cout << " === Meta Data Object ===" << endl;
      m->Print();
   }
}

//______________________________________________________________________________
TFileInfoMeta::TFileInfoMeta(const char *objPath, const char *objClass,
                             Long64_t entries, Long64_t first, Long64_t last,
                             Long64_t totbytes, Long64_t zipbytes)
              : TNamed(objPath, objClass), fEntries(entries), fFirst(first),
                fLast(last), fTotBytes(totbytes), fZipBytes(zipbytes)
{
   // Create file meta data object.

   TString p = objPath;
   if (!p.BeginsWith("/")) {
      p.Prepend("/");
      SetName(p);
   }

   TClass *c = TClass::GetClass(objClass);
   fIsTree = (c && c->InheritsFrom("TTree")) ? kTRUE : kFALSE;
   ResetBit(TFileInfoMeta::kExternal);
}

//______________________________________________________________________________
TFileInfoMeta::TFileInfoMeta(const char *objPath, const char *objDir,
                             const char *objClass, Long64_t entries,
                             Long64_t first, Long64_t last,
                             Long64_t totbytes, Long64_t zipbytes)
              : TNamed(objPath, objClass), fEntries(entries), fFirst(first),
                fLast(last), fTotBytes(totbytes), fZipBytes(zipbytes)
{
   // Create file meta data object.

   TString sdir = objDir;
   if (!sdir.BeginsWith("/"))
      sdir.Prepend("/");
   if (!sdir.EndsWith("/"))
      sdir += "/";
   sdir += objPath;
   SetName(sdir);

   TClass *c = TClass::GetClass(objClass);
   fIsTree = (c && c->InheritsFrom("TTree")) ? kTRUE : kFALSE;
   ResetBit(TFileInfoMeta::kExternal);
}

//______________________________________________________________________________
TFileInfoMeta::TFileInfoMeta(const TFileInfoMeta &m)
              : TNamed(m.GetName(), m.GetTitle())
{
   // Copy constructor

   fEntries = m.fEntries;
   fFirst = m.fFirst;
   fLast = m.fLast;
   fIsTree = m.fIsTree;
   fTotBytes = m.fTotBytes;
   fZipBytes = m.fZipBytes;
   ResetBit(TFileInfoMeta::kExternal);
   if (m.TestBit(TFileInfoMeta::kExternal)) SetBit(TFileInfoMeta::kExternal);
}

//______________________________________________________________________________
const char *TFileInfoMeta::GetDirectory() const
{
   // Get the object's directory in the ROOT file.

   return gSystem->DirName(GetName());
}

//______________________________________________________________________________
const char *TFileInfoMeta::GetObject() const
{
   // Get the object name, with path stripped off. For full path
   // use GetName().

   return gSystem->BaseName(GetName());
}

//______________________________________________________________________________
void TFileInfoMeta::Print(Option_t * /* option */) const
{
   // Print information about this object.

   cout << " Name:    " << fName << "\n"
        << " Class:   " << fTitle << "\n"
        << " Entries: " << fEntries << "\n"
        << " First:   " << fFirst << "\n"
        << " Last:    " << fLast << endl;
}
<commit_msg>From Gerri: Use Printf(...) instead of cout.<commit_after>// @(#)root/base:$Id$
// Author: Andreas-Joachim Peters   20/9/2005

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TFileInfo                                                            //
//                                                                      //
// Class describing a generic file including meta information.          //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "Riostream.h"
#include "TFileInfo.h"
#include "TRegexp.h"
#include "TSystem.h"
#include "TClass.h"

ClassImp(TFileInfo)
ClassImp(TFileInfoMeta)

//______________________________________________________________________________
TFileInfo::TFileInfo(const char *url, Long64_t size, const char *uuid,
                     const char *md5, TObject *meta)
   : fCurrentUrl(0), fUrlList(0), fSize(size), fUUID(0), fMD5(0),
     fMetaDataList(0)
{
   // Constructor.

   if (uuid)
      fUUID = new TUUID(uuid);
   else
      fUUID = new TUUID;

   if (md5)
      fMD5 = new TMD5((const UChar_t*)md5);
   else
      fMD5 = new TMD5;

   // Set's the name from the UUID.
   SetName(fUUID->AsString());
   SetTitle("TFileInfo");

   if (url)
      AddUrl(url);

   if (meta)
      AddMetaData(meta);
}

//______________________________________________________________________________
TFileInfo::TFileInfo(const TFileInfo &fi) : TNamed(fi.GetName(), fi.GetTitle()),
                                            fCurrentUrl(0), fUrlList(0),
                                            fSize(fi.fSize), fUUID(0), fMD5(0),
                                            fMetaDataList(0)
{
   // Copy constructor

   if (fi.fUrlList) {
      fUrlList = new TList;
      fUrlList->SetOwner();
      TIter nxu(fi.fUrlList);
      TUrl *u = 0;
      while ((u = (TUrl *)nxu())) {
         fUrlList->Add(new TUrl(u->GetUrl(), kTRUE));
      }
      ResetUrl();
   }
   fSize = fi.fSize;

   if (fi.fUUID)
      fUUID = new TUUID(fi.fUUID->AsString());

   if (fi.fMD5)
      fMD5 = new TMD5(*(fi.fMD5));

   // Staged and corrupted bits
   ResetBit(TFileInfo::kStaged);
   ResetBit(TFileInfo::kCorrupted);
   if (fi.TestBit(TFileInfo::kStaged)) SetBit(TFileInfo::kStaged);
   if (fi.TestBit(TFileInfo::kCorrupted)) SetBit(TFileInfo::kCorrupted);

   if (fi.fMetaDataList) {
      fMetaDataList = new TList;
      fMetaDataList->SetOwner();
      TIter nxm(fi.fMetaDataList);
      TFileInfoMeta *fim = 0;
      while ((fim = (TFileInfoMeta *)nxm())) {
         fMetaDataList->Add(new TFileInfoMeta(*fim));
      }
   }
}

//______________________________________________________________________________
TFileInfo::~TFileInfo()
{
   // Destructor.

   SafeDelete(fMetaDataList);
   SafeDelete(fUUID);
   SafeDelete(fMD5);
   SafeDelete(fUrlList);
}

//______________________________________________________________________________
void TFileInfo::SetUUID(const char *uuid)
{
   // Set the UUID to the value associated to the string 'uuid'. This is
   // useful to set the UUID to the one of the ROOT file during verification.
   // NB: we do not change the name in here, because this would screw up lists
   //     of these objects hashed on the name. Those lists need to be rebuild.
   //     TFileCollection does that in RemoveDuplicates.

   if (uuid) {
      if (fUUID) delete fUUID;
      fUUID = new TUUID(uuid);
   }
}

//______________________________________________________________________________
TUrl *TFileInfo::GetCurrentUrl() const
{
   // Return the current url.

   if (!fCurrentUrl)
      const_cast<TFileInfo*>(this)->ResetUrl();
   return fCurrentUrl;
}

//______________________________________________________________________________
TUrl *TFileInfo::NextUrl()
{
   // Iterator function, start iteration by calling ResetUrl().
   // The first call to NextUrl() will return the 1st element,
   // the seconde the 2nd element etc. Returns 0 in case no more urls.

   if (!fUrlList)
      return 0;

   TUrl *returl = fCurrentUrl;

   if (fCurrentUrl)
      fCurrentUrl = (TUrl*)fUrlList->After(fCurrentUrl);

   return returl;
}

//______________________________________________________________________________
TUrl *TFileInfo::FindByUrl(const char *url, Bool_t withDeflt)
{
   // Find an element from a URL. Returns 0 if not found.

   TIter nextUrl(fUrlList);
   TUrl *urlelement;

   TRegexp rg(url);
   while  ((urlelement = (TUrl*) nextUrl())) {
      if (TString(urlelement->GetUrl(withDeflt)).Index(rg) != kNPOS) {
         return urlelement;
      }
   }
   return 0;
}

//______________________________________________________________________________
Bool_t TFileInfo::AddUrl(const char *url, Bool_t infront)
{
   // Add a new URL. If 'infront' is TRUE the new url is pushed at the beginning
   // of the list; otherwise is pushed back.
   // Returns kTRUE if successful, kFALSE otherwise.

   if (FindByUrl(url))
      return kFALSE;

   if (!fUrlList) {
      fUrlList = new TList;
      fUrlList->SetOwner();
   }

   TUrl *newurl = new TUrl(url, kTRUE);
   // We set the current Url to the first url added
   if (fUrlList->GetSize() == 0)
      fCurrentUrl = newurl;

   if (infront)
      fUrlList->AddFirst(newurl);
   else
      fUrlList->Add(newurl);
   return kTRUE;
}

//______________________________________________________________________________
Bool_t TFileInfo::RemoveUrl(const char *url)
{
   // Remove an URL. Returns kTRUE if successful, kFALSE otherwise.

   TUrl *lurl;
   if ((lurl = FindByUrl(url))) {
      fUrlList->Remove(lurl);
      if (lurl == fCurrentUrl)
         ResetUrl();
      delete lurl;
      return kTRUE;
   }
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TFileInfo::SetCurrentUrl(const char *url)
{
   // Set 'url' as current URL, if in the list
   // Return kFALSE if not in the list

   TUrl *lurl;
   if ((lurl = FindByUrl(url))) {
      fCurrentUrl = lurl;
      return kTRUE;
   }
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TFileInfo::SetCurrentUrl(TUrl *url)
{
   // Set 'url' as current URL, if in the list
   // Return kFALSE if not in the list

   if (url && fUrlList && fUrlList->FindObject(url)) {
      fCurrentUrl = url;
      return kTRUE;
   }
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TFileInfo::AddMetaData(TObject *meta)
{
   // Add's a meta data object to the file info object. The object will be
   // adopted by the TFileInfo and should not be deleted by the user.
   // Typically objects of class TFileInfoMeta or derivatives should be added,
   // but any class is accepted.
   // Returns kTRUE if successful, kFALSE otherwise.

   if (meta) {
      if (!fMetaDataList) {
         fMetaDataList = new TList;
         fMetaDataList->SetOwner();
      }
      fMetaDataList->Add(meta);
      return kTRUE;
   }
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TFileInfo::RemoveMetaData(const char *meta)
{
   // Remove the metadata obeject. If meta is 0 remove all meta data objects.
   // Returns kTRUE if successful, kFALSE otherwise.

   if (fMetaDataList) {
      if (!meta || strlen(meta) <= 0) {
         SafeDelete(fMetaDataList);
         return kTRUE;
      } else {
         TObject *o = fMetaDataList->FindObject(meta);
         if (o) {
            fMetaDataList->Remove(o);
            delete o;
            return kTRUE;
         }
      }
   }
   return kFALSE;
}

//______________________________________________________________________________
TFileInfoMeta *TFileInfo::GetMetaData(const char *meta) const
{
   // Get meta data object with specified name. If meta is 0
   // get first meta data object. Returns 0 in case no
   // suitable meta data object is found.

   if (fMetaDataList) {
      TFileInfoMeta *m;
      if (!meta || strlen(meta) <= 0)
         m = (TFileInfoMeta *) fMetaDataList->First();
      else
         m = (TFileInfoMeta *) fMetaDataList->FindObject(meta);
      if (m) {
         TClass *c = m->IsA();
         return (c && c->InheritsFrom("TFileInfoMeta")) ? m : 0;
      }
   }
   return 0;
}

//______________________________________________________________________________
Int_t TFileInfo::Compare(const TObject *obj) const
{
   // Compare TFileInfo object by their first urls.

   if (this == obj) return 0;
   if (TFileInfo::Class() != obj->IsA()) return -1;
   return (GetFirstUrl()->Compare(((TFileInfo*)obj)->GetFirstUrl()));
}

//______________________________________________________________________________
void TFileInfo::Print(Option_t * /* option */) const
{
   // Print information about this object.

   GetMD5()->Final();
   Printf("UUID: %s\nMD5:  %s\nSize: %lld", GetUUID()->AsString(), GetMD5()->AsString(), GetSize());

   TIter next(fUrlList);
   TUrl *u;
   Printf(" === URLs ===");
   while ((u = (TUrl*)next()))
     Printf(" URL:  %s", u->GetUrl());

   TIter nextm(fMetaDataList);
   TObject *m = 0;   // can be any TObject not only TFileInfoMeta
   while ((m = (TObject*) nextm())) {
      Printf(" === Meta Data Object ===");
      m->Print();
   }
}

//______________________________________________________________________________
TFileInfoMeta::TFileInfoMeta(const char *objPath, const char *objClass,
                             Long64_t entries, Long64_t first, Long64_t last,
                             Long64_t totbytes, Long64_t zipbytes)
              : TNamed(objPath, objClass), fEntries(entries), fFirst(first),
                fLast(last), fTotBytes(totbytes), fZipBytes(zipbytes)
{
   // Create file meta data object.

   TString p = objPath;
   if (!p.BeginsWith("/")) {
      p.Prepend("/");
      SetName(p);
   }

   TClass *c = TClass::GetClass(objClass);
   fIsTree = (c && c->InheritsFrom("TTree")) ? kTRUE : kFALSE;
   ResetBit(TFileInfoMeta::kExternal);
}

//______________________________________________________________________________
TFileInfoMeta::TFileInfoMeta(const char *objPath, const char *objDir,
                             const char *objClass, Long64_t entries,
                             Long64_t first, Long64_t last,
                             Long64_t totbytes, Long64_t zipbytes)
              : TNamed(objPath, objClass), fEntries(entries), fFirst(first),
                fLast(last), fTotBytes(totbytes), fZipBytes(zipbytes)
{
   // Create file meta data object.

   TString sdir = objDir;
   if (!sdir.BeginsWith("/"))
      sdir.Prepend("/");
   if (!sdir.EndsWith("/"))
      sdir += "/";
   sdir += objPath;
   SetName(sdir);

   TClass *c = TClass::GetClass(objClass);
   fIsTree = (c && c->InheritsFrom("TTree")) ? kTRUE : kFALSE;
   ResetBit(TFileInfoMeta::kExternal);
}

//______________________________________________________________________________
TFileInfoMeta::TFileInfoMeta(const TFileInfoMeta &m)
              : TNamed(m.GetName(), m.GetTitle())
{
   // Copy constructor

   fEntries = m.fEntries;
   fFirst = m.fFirst;
   fLast = m.fLast;
   fIsTree = m.fIsTree;
   fTotBytes = m.fTotBytes;
   fZipBytes = m.fZipBytes;
   ResetBit(TFileInfoMeta::kExternal);
   if (m.TestBit(TFileInfoMeta::kExternal)) SetBit(TFileInfoMeta::kExternal);
}

//______________________________________________________________________________
const char *TFileInfoMeta::GetDirectory() const
{
   // Get the object's directory in the ROOT file.

   return gSystem->DirName(GetName());
}

//______________________________________________________________________________
const char *TFileInfoMeta::GetObject() const
{
   // Get the object name, with path stripped off. For full path
   // use GetName().

   return gSystem->BaseName(GetName());
}

//______________________________________________________________________________
void TFileInfoMeta::Print(Option_t * /* option */) const
{
   // Print information about this object.

   Printf(" Name:    %s\n Class:   %s\n Entries: %lld\n"
          " First:   %lld\n Last:    %lld",
          fName.Data(), fTitle.Data(), fEntries, fFirst, fLast);
}
<|endoftext|>


<commit_before>// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
//
// 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 "CompressorRGBE.h"
#include "CompressionOptions.h"
#include "OutputOptions.h"

#include <nvimage/Image.h>
#include <nvimage/FloatImage.h>

#include <nvmath/Color.h>

#include <nvcore/Debug.h>

using namespace nv;
using namespace nvtt;

static Color32 toRgbe8(float r, float g, float b)
{
    Color32 c;
    float v = max(max(r, g), b);
    if (v < 1e-32) {
        c.r = c.g = c.b = c.a = 0;
    }
    else {
        int e;
        v = frexp(v, &e) * 256.0f / v;
        c.r = uint8(clamp(r * v, 0.0f, 255.0f));
        c.g = uint8(clamp(g * v, 0.0f, 255.0f));
        c.b = uint8(clamp(b * v, 0.0f, 255.0f));
        c.a = e + 128;
    }

    return c;
}

void CompressorRGBE::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
{
    nvDebugCheck (compressionOptions.format == nvtt::Format_RGBE);

    uint srcPitch = w;
    uint srcPlane = w * h;

    // Allocate output scanline.
	Color32 * dst = (Color32 *)mem::malloc(w);

	for (uint y = 0; y < h; y++)
	{
        const uint * src = (const uint *)data + y * srcPitch;
        const float * fsrc = (const float *)data + y * srcPitch;

		for (uint x = 0; x < w; x++)
		{
            float r, g, b;

            if (inputFormat == nvtt::InputFormat_BGRA_8UB) {
                Color32 c = Color32(src[x]);
                r = float(c.r) / 255.0f;
                g = float(c.g) / 255.0f;
                b = float(c.b) / 255.0f;
            }
            else {
                nvDebugCheck (inputFormat == nvtt::InputFormat_RGBA_32F);

#pragma message("Interleave color components")

			    // Color components not interleaved.
			    r = fsrc[x + 0 * srcPlane];
			    g = fsrc[x + 1 * srcPlane];
			    b = fsrc[x + 2 * srcPlane];
            }

            dst[x] = toRgbe8(r, g, b);
        }

		if (outputOptions.outputHandler != NULL)
		{
			outputOptions.outputHandler->writeData(dst, w * 4);
		}
    }

	mem::free(dst);
}
<commit_msg>fix comment.<commit_after>// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
//
// 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 "CompressorRGBE.h"
#include "CompressionOptions.h"
#include "OutputOptions.h"

#include <nvimage/Image.h>
#include <nvimage/FloatImage.h>

#include <nvmath/Color.h>

#include <nvcore/Debug.h>

using namespace nv;
using namespace nvtt;

static Color32 toRgbe8(float r, float g, float b)
{
    Color32 c;
    float v = max(max(r, g), b);
    if (v < 1e-32) {
        c.r = c.g = c.b = c.a = 0;
    }
    else {
        int e;
        v = frexp(v, &e) * 256.0f / v;
        c.r = uint8(clamp(r * v, 0.0f, 255.0f));
        c.g = uint8(clamp(g * v, 0.0f, 255.0f));
        c.b = uint8(clamp(b * v, 0.0f, 255.0f));
        c.a = e + 128;
    }

    return c;
}

void CompressorRGBE::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
{
    nvDebugCheck (compressionOptions.format == nvtt::Format_RGBE);

    uint srcPitch = w;
    uint srcPlane = w * h;

    // Allocate output scanline.
	Color32 * dst = (Color32 *)mem::malloc(w);

	for (uint y = 0; y < h; y++)
	{
        const uint * src = (const uint *)data + y * srcPitch;
        const float * fsrc = (const float *)data + y * srcPitch;

		for (uint x = 0; x < w; x++)
		{
            float r, g, b;

            if (inputFormat == nvtt::InputFormat_BGRA_8UB) {
                Color32 c = Color32(src[x]);
                r = float(c.r) / 255.0f;
                g = float(c.g) / 255.0f;
                b = float(c.b) / 255.0f;
            }
            else {
                nvDebugCheck (inputFormat == nvtt::InputFormat_RGBA_32F);

#pragma message(NV_FILE_LINE "TODO: Interleave color components")

			    // Color components not interleaved.
			    r = fsrc[x + 0 * srcPlane];
			    g = fsrc[x + 1 * srcPlane];
			    b = fsrc[x + 2 * srcPlane];
            }

            dst[x] = toRgbe8(r, g, b);
        }

		if (outputOptions.outputHandler != NULL)
		{
			outputOptions.outputHandler->writeData(dst, w * 4);
		}
    }

	mem::free(dst);
}
<|endoftext|>


<commit_before>//========- unittests/Support/SignalsTest.cpp - Signal handling test =========//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#if !defined(_WIN32)
#include <unistd.h>
#include <sysexits.h>
#endif // !defined(_WIN32)

#include "llvm/Support/Signals.h"

#include "gtest/gtest.h"

using namespace llvm;

#if !defined(_WIN32)
TEST(SignalTest, IgnoreMultipleSIGPIPEs) {
  // Ignore SIGPIPE.
  signal(SIGPIPE, SIG_IGN);

  // Disable exit-on-SIGPIPE.
  sys::SetPipeSignalFunction(nullptr);

  // Create unidirectional read/write pipes.
  int fds[2];
  int err = pipe(fds);
  if (err != 0)
    return; // If we can't make pipes, this isn't testing anything.

  // Close the read pipe.
  close(fds[0]);

  // Attempt to write to the write pipe. Currently we're asserting that the
  // write fails, which isn't great.
  //
  // What we really want is a death test that checks that this block exits
  // with a special exit "success" code, as opposed to unexpectedly exiting due
  // to a kill-by-SIGNAL or due to the default SIGPIPE handler.
  //
  // Unfortunately llvm's unit tests aren't set up to support death tests well.
  // For one, death tests are flaky in a multithreaded context. And sigactions
  // inherited from llvm-lit interfere with what's being tested.
  const void *buf = (const void *)&fds;
  err = write(fds[1], buf, 1);
  ASSERT_EQ(err, -1);
  err = write(fds[1], buf, 1);
  ASSERT_EQ(err, -1);
}
#endif // !defined(_WIN32)
<commit_msg>Fix llvm signal tests build.<commit_after>//========- unittests/Support/SignalsTest.cpp - Signal handling test =========//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#if !defined(_WIN32)
#include <unistd.h>
#include <sysexits.h>
#include <signal.h>
#endif // !defined(_WIN32)

#include "llvm/Support/Signals.h"

#include "gtest/gtest.h"

using namespace llvm;

#if !defined(_WIN32)
TEST(SignalTest, IgnoreMultipleSIGPIPEs) {
  // Ignore SIGPIPE.
  signal(SIGPIPE, SIG_IGN);

  // Disable exit-on-SIGPIPE.
  sys::SetPipeSignalFunction(nullptr);

  // Create unidirectional read/write pipes.
  int fds[2];
  int err = pipe(fds);
  if (err != 0)
    return; // If we can't make pipes, this isn't testing anything.

  // Close the read pipe.
  close(fds[0]);

  // Attempt to write to the write pipe. Currently we're asserting that the
  // write fails, which isn't great.
  //
  // What we really want is a death test that checks that this block exits
  // with a special exit "success" code, as opposed to unexpectedly exiting due
  // to a kill-by-SIGNAL or due to the default SIGPIPE handler.
  //
  // Unfortunately llvm's unit tests aren't set up to support death tests well.
  // For one, death tests are flaky in a multithreaded context. And sigactions
  // inherited from llvm-lit interfere with what's being tested.
  const void *buf = (const void *)&fds;
  err = write(fds[1], buf, 1);
  ASSERT_EQ(err, -1);
  err = write(fds[1], buf, 1);
  ASSERT_EQ(err, -1);
}
#endif // !defined(_WIN32)
<|endoftext|>