<commit_before>#include <dlfcn.h>
#include <cassert>
#include "common/util.h"
#include "ace/interface.h"
#include "protoc/processjob.pb.h"
#include "dirent.h"
#include "wal.h"
#include "exec.h"

typedef int (*regclass_t)();
typedef Ace::Job *(*facade_t)();

void Execute::init(ControlClient *control) {
	DIR *dir = nullptr;
	struct dirent *ent = nullptr;

	Execute& exec = Execute::getInstance();
	exec.setControl(control);

	if ((dir = opendir("cache/wal/")) != NULL) {

		/* print all the files and directories within directory */
		while ((ent = readdir(dir)) != NULL) {
			if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
				continue;

			Wal::rollback(ent->d_name);
		}

		closedir(dir);
	} else {

		/* could not open directory */
		perror("");
	}
}

void Execute::run(const std::string& name, Parameter& param) {
	Wal *executionLog = new Wal(name, param);

	Execute *exec = &Execute::getInstance();

	std::cout << "Running module " << std::endl;

	/* Move worker in accept mode */
	exec->jobcontrol->setStateAccepted();

	/* Set members of shared object via callback */
	exec->workerid = exec->jobcontrol->workerId();
	exec->clusterjobs = exec->jobcontrol->clusterJobs();
	exec->module = name;
	exec->jobid = param.jobid;
	exec->jobname = param.jobname;
	exec->jobquid = param.jobquid;
	exec->jobpartition = param.jobpartition;
	exec->jobpartition_count = param.jobpartition_count;
	exec->jobstate = param.jobstate;
	exec->jobparent = param.jobparent;

	executionLog->setCheckpoint(Wal::Checkpoint::INIT);

	if (!file_exist("cache/module/" + name)) {
		std::cerr << "Cannot access library" << std::endl;
		return;
	}

	void *handle = dlopen(("cache/module/" + name).c_str(), RTLD_LAZY);
	if (!handle) {
		std::cerr << "Cannot open library: " << dlerror() << std::endl;
		return;
	}

	regclass_t exec_register = (int (*)()) dlsym(handle, "register_class");
	facade_t exec_facade = (Ace::Job * (*)()) dlsym(handle, "object_facade");
	executionLog->setCheckpoint(Wal::Checkpoint::LOAD);

	/* Inject job and cluster */
	assert(exec_register() == ACE_MAGIC);
	Ace::Job *jobObject = (Ace::Job *)exec_facade();
	jobObject->Inject(exec);
	executionLog->setCheckpoint(Wal::Checkpoint::INJECT);

	/* Call this setup once in the cluster */
	if (exec->jobstate == SPAWN) {
		exec->jobcontrol->setStateSetup();
		jobObject->SetupOnce();
		executionLog->setCheckpoint(Wal::Checkpoint::SETUP_ONCE);
	}

	/* Call setup routine */
	exec->jobcontrol->setStateSetup();
	jobObject->Setup();
	executionLog->setCheckpoint(Wal::Checkpoint::SETUP);

	/* Call main routine */
	exec->jobcontrol->setStateRunning();
	jobObject->Run();
	executionLog->setCheckpoint(Wal::Checkpoint::RUN);

	/* Call teardown routine */
	exec->jobcontrol->setStateTeardown();
	jobObject->Teardown();
	executionLog->setCheckpoint(Wal::Checkpoint::TEARDOWN);

	/* Call this teardown once in the cluster */
	if (exec->jobstate == FUNNEL) {
		exec->jobcontrol->setStateSetup();
		jobObject->TeardownOnce();
		executionLog->setCheckpoint(Wal::Checkpoint::TEARDOWN_ONCE);
	}

	/* Pull the chain */
	exec->chain = jobObject->PullChain();
	executionLog->setCheckpoint(Wal::Checkpoint::PULLCHAIN);

	int r = dlclose(handle);
	if (r)
		dlclose(handle);

	/* Release resources allocated for this job */
	exec->sessionCleanup();

	/* Move worker in idle mode */
	exec->jobcontrol->setStateIdle();

	/* Mark WAL done */
	executionLog->markDone();

	delete executionLog;
}

void Execute::prospect() {
	Execute *exec = &Execute::getInstance();

	if (!exec->chain) {
		std::cout << "no chain, done" << std::endl;
		return;
	}

	std::cout << "Chain found" << std::endl;
	std::cout << "Subjobs " << exec->chain->size() << std::endl;

	for (unsigned int i = 0; i < exec->chain->size(); ++i) {
		auto subjob = exec->chain->at(i);

		ProcessJob job;
		job.set_name(subjob->name);
		job.set_id(i);
		job.set_quid("5f7920eb-ef78-4a2a-a04e-e8763cf35716");
		job.set_content(subjob->content);
		job.set_partition(i);
		job.set_partition_count(exec->chain->size());
		job.set_state(ProcessJob::PARTITION);
		job.set_quid_parent(exec->chain->parentQuid());

		std::cout << "Submit subjob " << i << " linked to parent " << exec->chain->parentQuid() + "(" + exec->chain->parentName() + ")" << std::endl;
	}

	delete exec->chain;
}

void Execute::dispose() {
	DIR *dir = nullptr;
	struct dirent *ent = nullptr;

	if ((dir = opendir("cache/module/")) != NULL) {

		/* print all the files and directories within directory */
		while ((ent = readdir(dir)) != NULL) {
			if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
				continue;
			remove(("cache/module/" + std::string(ent->d_name)).c_str());
		}

		closedir(dir);
	} else {

		/* could not open directory */
		perror("");
	}

	if ((dir = opendir("cache/wal/")) != NULL) {

		/* print all the files and directories within directory */
		while ((ent = readdir(dir)) != NULL) {
			if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
				continue;
			remove(("cache/wal/" + std::string(ent->d_name)).c_str());
		}

		closedir(dir);
	} else {

		/* could not open directory */
		perror("");
	}
}
<commit_msg>Catch any exceptions from DSO<commit_after>#include <dlfcn.h>
#include <cassert>
#include "common/util.h"
#include "ace/interface.h"
#include "protoc/processjob.pb.h"
#include "dirent.h"
#include "wal.h"
#include "exec.h"

typedef int (*regclass_t)();
typedef Ace::Job *(*facade_t)();

void Execute::init(ControlClient *control) {
	DIR *dir = nullptr;
	struct dirent *ent = nullptr;

	Execute& exec = Execute::getInstance();
	exec.setControl(control);

	if ((dir = opendir("cache/wal/")) != NULL) {

		/* print all the files and directories within directory */
		while ((ent = readdir(dir)) != NULL) {
			if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
				continue;

			Wal::rollback(ent->d_name);
		}

		closedir(dir);
	} else {

		/* could not open directory */
		perror("");
	}
}

void Execute::run(const std::string& name, Parameter& param) {
	Wal *executionLog = new Wal(name, param);

	Execute *exec = &Execute::getInstance();

	std::cout << "Running module " << std::endl;

	/* Move worker in accept mode */
	exec->jobcontrol->setStateAccepted();

	/* Set members of shared object via callback */
	exec->workerid = exec->jobcontrol->workerId();
	exec->clusterjobs = exec->jobcontrol->clusterJobs();
	exec->module = name;
	exec->jobid = param.jobid;
	exec->jobname = param.jobname;
	exec->jobquid = param.jobquid;
	exec->jobpartition = param.jobpartition;
	exec->jobpartition_count = param.jobpartition_count;
	exec->jobstate = param.jobstate;
	exec->jobparent = param.jobparent;

	executionLog->setCheckpoint(Wal::Checkpoint::INIT);

	if (!file_exist("cache/module/" + name)) {
		std::cerr << "Cannot access library" << std::endl;
		return;
	}

	void *handle = dlopen(("cache/module/" + name).c_str(), RTLD_LAZY);
	if (!handle) {
		std::cerr << "Cannot open library: " << dlerror() << std::endl;
		return;
	}

	regclass_t exec_register = (int (*)()) dlsym(handle, "register_class");
	facade_t exec_facade = (Ace::Job * (*)()) dlsym(handle, "object_facade");
	executionLog->setCheckpoint(Wal::Checkpoint::LOAD);

	/* Inject job and cluster */
	assert(exec_register() == ACE_MAGIC);
	Ace::Job *jobObject = (Ace::Job *)exec_facade();
	try {
		jobObject->Inject(exec);
		executionLog->setCheckpoint(Wal::Checkpoint::INJECT);
	} catch (const std::exception& ex) {
		std::cerr << ex.what() << std::endl;
	}

	/* Call this setup once in the cluster */
	if (exec->jobstate == SPAWN) {
		try {
			exec->jobcontrol->setStateSetup();
			jobObject->SetupOnce();
			executionLog->setCheckpoint(Wal::Checkpoint::SETUP_ONCE);
		} catch (const std::exception& ex) {
			std::cerr << ex.what() << std::endl;
		}
	}

	/* Call setup routine */
	try {
		exec->jobcontrol->setStateSetup();
		jobObject->Setup();
		executionLog->setCheckpoint(Wal::Checkpoint::SETUP);
	} catch (const std::exception& ex) {
		std::cerr << ex.what() << std::endl;
	}

	/* Call main routine */
	try {
		exec->jobcontrol->setStateRunning();
		jobObject->Run();
		executionLog->setCheckpoint(Wal::Checkpoint::RUN);
	} catch (const std::exception& ex) {
		std::cerr << ex.what() << std::endl;
	}

	/* Call teardown routine */
	try {
		exec->jobcontrol->setStateTeardown();
		jobObject->Teardown();
		executionLog->setCheckpoint(Wal::Checkpoint::TEARDOWN);
	} catch (const std::exception& ex) {
		std::cerr << ex.what() << std::endl;
	}

	/* Call this teardown once in the cluster */
	if (exec->jobstate == FUNNEL) {
		try {
			exec->jobcontrol->setStateSetup();
			jobObject->TeardownOnce();
			executionLog->setCheckpoint(Wal::Checkpoint::TEARDOWN_ONCE);
		} catch (const std::exception& ex) {
			std::cerr << ex.what() << std::endl;
		}
	}

	/* Pull the chain */
	try {
		exec->chain = jobObject->PullChain();
		executionLog->setCheckpoint(Wal::Checkpoint::PULLCHAIN);
	} catch (const std::exception& ex) {
		std::cerr << ex.what() << std::endl;
	}

	int r = dlclose(handle);
	if (r)
		dlclose(handle);

	/* Release resources allocated for this job */
	exec->sessionCleanup();

	/* Move worker in idle mode */
	exec->jobcontrol->setStateIdle();

	/* Mark WAL done */
	executionLog->markDone();

	delete executionLog;
}

void Execute::prospect() {
	Execute *exec = &Execute::getInstance();

	if (!exec->chain) {
		std::cout << "no chain, done" << std::endl;
		return;
	}

	std::cout << "Chain found" << std::endl;
	std::cout << "Subjobs " << exec->chain->size() << std::endl;

	for (unsigned int i = 0; i < exec->chain->size(); ++i) {
		auto subjob = exec->chain->at(i);

		ProcessJob job;
		job.set_name(subjob->name);
		job.set_id(i);
		job.set_quid("5f7920eb-ef78-4a2a-a04e-e8763cf35716");
		job.set_content(subjob->content);
		job.set_partition(i);
		job.set_partition_count(exec->chain->size());
		job.set_state(ProcessJob::PARTITION);
		job.set_quid_parent(exec->chain->parentQuid());

		std::cout << "Submit subjob " << i << " linked to parent " << exec->chain->parentQuid() + "(" + exec->chain->parentName() + ")" << std::endl;
	}

	delete exec->chain;
}

void Execute::dispose() {
	DIR *dir = nullptr;
	struct dirent *ent = nullptr;

	if ((dir = opendir("cache/module/")) != NULL) {

		/* print all the files and directories within directory */
		while ((ent = readdir(dir)) != NULL) {
			if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
				continue;
			remove(("cache/module/" + std::string(ent->d_name)).c_str());
		}

		closedir(dir);
	} else {

		/* could not open directory */
		perror("");
	}

	if ((dir = opendir("cache/wal/")) != NULL) {

		/* print all the files and directories within directory */
		while ((ent = readdir(dir)) != NULL) {
			if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
				continue;
			remove(("cache/wal/" + std::string(ent->d_name)).c_str());
		}

		closedir(dir);
	} else {

		/* could not open directory */
		perror("");
	}
}
<|endoftext|>


<commit_before>#ifndef __UTILS2_HPP__
#define __UTILS2_HPP__

/* utils2.hpp is a collection of utility functions and types that sits below the IO layer.
The reason it is separate from utils.hpp is that the IO layer needs some of the things in
utils2.hpp, but utils.hpp needs some things in the IO layer. */

#include <cstdlib>
#include <stdint.h>
#include <time.h>
#include "config/args.hpp"
#include "errors.hpp"

typedef uint64_t cas_t;

/* Note that repli_timestamp_t does NOT represent an actual timestamp; instead it's an arbitrary
counter. */

// for safety  TODO: move this to a different file
struct repli_timestamp_t {
    uint32_t time;

    bool operator==(repli_timestamp_t t) const {
        return time == t.time;
    }
    bool operator<(repli_timestamp_t t) const {
        return time < t.time;
    }
    bool operator>=(repli_timestamp_t t) const {
        return time >= t.time;
    }

    repli_timestamp_t next() const {
        repli_timestamp_t t;
        t.time = time + 1;
        return t;
    }

    static const repli_timestamp_t distant_past;
    static const repli_timestamp_t invalid;
};
typedef repli_timestamp_t repli_timestamp;   // TODO switch name over completely to "_t" version

struct charslice {
    char *beg, *end;
    charslice(char *beg_, char *end_) : beg(beg_), end(end_) { }
    charslice() : beg(NULL), end(NULL) { }
};

struct const_charslice {
    const char *beg, *end;
    const_charslice(const char *beg_, const char *end_) : beg(beg_), end(end_) { }
    const_charslice() : beg(NULL), end(NULL) { }
};

typedef uint64_t microtime_t;

microtime_t current_microtime();

// Like std::max, except it's technically not associative.
repli_timestamp_t repli_max(repli_timestamp_t x, repli_timestamp_t y);

void *malloc_aligned(size_t size, size_t alignment = 64);

template <class T1, class T2>
T1 ceil_aligned(T1 value, T2 alignment) {
    return value + alignment - (((value + alignment - 1) % alignment) + 1);
}

template <class T1, class T2>
T1 ceil_divide(T1 dividend, T2 alignment) {
    return (dividend + alignment - 1) / alignment;
}

template <class T1, class T2>
T1 floor_aligned(T1 value, T2 alignment) {
    return value - (value % alignment);
}

typedef unsigned long long ticks_t;
ticks_t secs_to_ticks(float secs);
ticks_t get_ticks();
long get_ticks_res();
double ticks_to_secs(ticks_t ticks);

// HEY: Maybe debugf and log_call and TRACEPOINT should be placed in
// debug.hpp (and debug.cc).
/* Debugging printing API (prints current thread in addition to message) */

void debugf(const char *msg, ...) __attribute__((format (printf, 1, 2)));

#ifndef NDEBUG
#define trace_call(fn, args...) do {                                          \
        debugf("%s:%u: %s: entered\n", __FILE__, __LINE__, stringify(fn));  \
        fn(args);                                                           \
        debugf("%s:%u: %s: returned\n", __FILE__, __LINE__, stringify(fn)); \
    } while (0)
#define TRACEPOINT debugf("%s:%u reached\n", __FILE__, __LINE__)
#else
#define trace_call(fn, args...) fn(args)
// TRACEPOINT is not defined in release, so that TRACEPOINTS do not linger in the code unnecessarily
#endif

// Returns a random number in [0, n).  Is not perfectly uniform; the
// bias tends to get worse when RAND_MAX is far from a multiple of n.
int randint(int n);

// The existence of these functions does not constitute an endorsement
// for casts.  These constitute an endorsement for the use of
// reinterpret_cast, rather than C-style casts.  The latter can break
// const correctness.
template <class T>
inline const T* ptr_cast(const void *p) { return reinterpret_cast<const T*>(p); }

template <class T>
inline T* ptr_cast(void *p) { return reinterpret_cast<T*>(p); }

bool ptr_in_byte_range(const void *p, const void *range_start, size_t size_in_bytes);
bool range_inside_of_byte_range(const void *p, size_t n_bytes, const void *range_start, size_t size_in_bytes);

bool begins_with_minus(const char *string);
// strtoul() and strtoull() will for some reason not fail if the input begins with a minus
// sign. strtoul_strict() and strtoull_strict() do.
long strtol_strict(const char *string, char **end, int base);
unsigned long strtoul_strict(const char *string, char **end, int base);
unsigned long long strtoull_strict(const char *string, char **end, int base);
bool strtobool_strict(const char *string, char **end);

// Put this in a private: section.
#define DISABLE_COPYING(T)                      \
    T(const T&);                                \
    void operator=(const T&)

// This is inefficient, it calls vsnprintf twice and copies the
// arglist and output buffer excessively.
std::string strprintf(const char *format, ...) __attribute__ ((format (printf, 1, 2)));

#endif /* __UTILS2_HPP__ */
<commit_msg>Removed the unused type charslice.<commit_after>#ifndef __UTILS2_HPP__
#define __UTILS2_HPP__

/* utils2.hpp is a collection of utility functions and types that sits below the IO layer.
The reason it is separate from utils.hpp is that the IO layer needs some of the things in
utils2.hpp, but utils.hpp needs some things in the IO layer. */

#include <cstdlib>
#include <stdint.h>
#include <time.h>
#include "config/args.hpp"
#include "errors.hpp"

typedef uint64_t cas_t;

/* Note that repli_timestamp_t does NOT represent an actual timestamp; instead it's an arbitrary
counter. */

// for safety  TODO: move this to a different file
struct repli_timestamp_t {
    uint32_t time;

    bool operator==(repli_timestamp_t t) const {
        return time == t.time;
    }
    bool operator<(repli_timestamp_t t) const {
        return time < t.time;
    }
    bool operator>=(repli_timestamp_t t) const {
        return time >= t.time;
    }

    repli_timestamp_t next() const {
        repli_timestamp_t t;
        t.time = time + 1;
        return t;
    }

    static const repli_timestamp_t distant_past;
    static const repli_timestamp_t invalid;
};
typedef repli_timestamp_t repli_timestamp;   // TODO switch name over completely to "_t" version

struct const_charslice {
    const char *beg, *end;
    const_charslice(const char *beg_, const char *end_) : beg(beg_), end(end_) { }
    const_charslice() : beg(NULL), end(NULL) { }
};

typedef uint64_t microtime_t;

microtime_t current_microtime();

// Like std::max, except it's technically not associative.
repli_timestamp_t repli_max(repli_timestamp_t x, repli_timestamp_t y);

void *malloc_aligned(size_t size, size_t alignment = 64);

template <class T1, class T2>
T1 ceil_aligned(T1 value, T2 alignment) {
    return value + alignment - (((value + alignment - 1) % alignment) + 1);
}

template <class T1, class T2>
T1 ceil_divide(T1 dividend, T2 alignment) {
    return (dividend + alignment - 1) / alignment;
}

template <class T1, class T2>
T1 floor_aligned(T1 value, T2 alignment) {
    return value - (value % alignment);
}

typedef unsigned long long ticks_t;
ticks_t secs_to_ticks(float secs);
ticks_t get_ticks();
long get_ticks_res();
double ticks_to_secs(ticks_t ticks);

// HEY: Maybe debugf and log_call and TRACEPOINT should be placed in
// debug.hpp (and debug.cc).
/* Debugging printing API (prints current thread in addition to message) */

void debugf(const char *msg, ...) __attribute__((format (printf, 1, 2)));

#ifndef NDEBUG
#define trace_call(fn, args...) do {                                          \
        debugf("%s:%u: %s: entered\n", __FILE__, __LINE__, stringify(fn));  \
        fn(args);                                                           \
        debugf("%s:%u: %s: returned\n", __FILE__, __LINE__, stringify(fn)); \
    } while (0)
#define TRACEPOINT debugf("%s:%u reached\n", __FILE__, __LINE__)
#else
#define trace_call(fn, args...) fn(args)
// TRACEPOINT is not defined in release, so that TRACEPOINTS do not linger in the code unnecessarily
#endif

// Returns a random number in [0, n).  Is not perfectly uniform; the
// bias tends to get worse when RAND_MAX is far from a multiple of n.
int randint(int n);

// The existence of these functions does not constitute an endorsement
// for casts.  These constitute an endorsement for the use of
// reinterpret_cast, rather than C-style casts.  The latter can break
// const correctness.
template <class T>
inline const T* ptr_cast(const void *p) { return reinterpret_cast<const T*>(p); }

template <class T>
inline T* ptr_cast(void *p) { return reinterpret_cast<T*>(p); }

bool ptr_in_byte_range(const void *p, const void *range_start, size_t size_in_bytes);
bool range_inside_of_byte_range(const void *p, size_t n_bytes, const void *range_start, size_t size_in_bytes);

bool begins_with_minus(const char *string);
// strtoul() and strtoull() will for some reason not fail if the input begins with a minus
// sign. strtoul_strict() and strtoull_strict() do.
long strtol_strict(const char *string, char **end, int base);
unsigned long strtoul_strict(const char *string, char **end, int base);
unsigned long long strtoull_strict(const char *string, char **end, int base);
bool strtobool_strict(const char *string, char **end);

// Put this in a private: section.
#define DISABLE_COPYING(T)                      \
    T(const T&);                                \
    void operator=(const T&)

// This is inefficient, it calls vsnprintf twice and copies the
// arglist and output buffer excessively.
std::string strprintf(const char *format, ...) __attribute__ ((format (printf, 1, 2)));

#endif /* __UTILS2_HPP__ */
<|endoftext|>


<commit_before>#pragma once

namespace CodeUnit {
    PS::F64 grav         = 1.;
    PS::F64 UnitOfLength = 1.;
    PS::F64 UnitOfEnergy = 1.;
}

class Density{
public:
    PS::F64 dens;
    PS::F64 grdh;
    PS::F64 ksr;
    PS::F64 rotv;
    PS::F64 divv;
    PS::S32 np;
    bool    itr;
    PS::F64 eta;
    void clear(){
        dens = 0.0;
        grdh = 0.0;
        ksr  = 0.0;
        rotv = 0.0;
        divv = 0.0;
        np   = 0;
        itr  = false;
        eta  = 0.0;
    }
};

class Derivative{
public:
    PS::F64vec acc;
    PS::F64vec accg;
    PS::F64    udot;
    PS::F64    vsmx;
    void clear(){
        acc  = 0.0;
        accg = 0.0;
        udot = 0.0;
        vsmx = 0.0;
    }
};

class Gravity{
public:
    PS::F64vec acc;
    PS::F64    pot;
    void clear(){
        acc = 0.0;
        pot = 0.0;
    }
};

class Header {
public:
    PS::F64    time;
    PS::F64    tend;
    PS::F64    dtsp;
    PS::F64ort cbox;
    PS::F64    gamma;
    PS::F64    alphamax;
    PS::F64    alphamin;
    PS::F64    tceff;
    PS::F64    eps;
    PS::S64    nptcl;

    Header() {
        time       = 0.0;
        tend       = 0.0;
        dtsp       = 0.0;
        cbox.low_  = 0.0;
        cbox.high_ = 0.0;
        gamma      = 0.0;
        alphamax   = 0.0;
        alphamin   = 0.0;
        tceff      = 0.0;
        eps        = 0.0;
        nptcl      = 0;
    }

    PS::S32 readAscii(FILE *fp) {
        fscanf(fp, "%lf%lf%lf", &time, &tend, &dtsp);
        fscanf(fp, "%lf%lf%lf", &cbox.low_[0], &cbox.low_[1], &cbox.low_[2]);
        fscanf(fp, "%lf%lf%lf", &cbox.high_[0], &cbox.high_[1], &cbox.high_[2]);
        fscanf(fp, "%lf%lf%lf%lf", &gamma, &alphamax, &alphamin, &tceff);
#ifdef GRAVITY
        fscanf(fp, "%lf", &eps);
#endif
        fscanf(fp, "%d", &nptcl);

        return nptcl;
    }
};

class SPH{
public:
    PS::S64    id;
    PS::F64    mass;
    PS::F64vec pos;
    PS::F64vec vel;
    PS::F64vec acc;
    PS::F64    uene;
    PS::F64    udot;
    PS::F64    alph;
    PS::F64    alph2;
    PS::F64    adot;
    PS::F64    dens;
    PS::F64    pres;
    PS::F64    vsnd;
    PS::F64    divv;
    PS::F64    rotv;
    PS::F64    bswt;
    PS::S64    np;
    PS::F64vec vel2;
    PS::F64    uene2;
    PS::F64    ksr;
    PS::F64    rs;
    PS::F64    grdh;
    PS::F64    vsmx;
    PS::F64    pot;
    PS::F64vec accg;
    PS::F64    eta;
    static PS::F64ort cbox;
    static PS::F64    cinv;
    static PS::F64    alphamax, alphamin;
    static PS::F64    tceff;
    static PS::F64    eps;
    static PS::F64    ksrmax;
    static PS::F64vec omg;

    PS::F64vec getPos() const {
        return this->pos;
    }

    void setPos(PS::F64vec pos_new) {
        this->pos = pos_new;
    }

    void copyFromForce(const Density & density){
        this->dens = density.dens;
        this->grdh = density.grdh;
        this->np   = density.np;
        this->ksr  = density.ksr;
        this->rotv = density.rotv;
        this->divv = density.divv;
        this->eta  = density.eta;
    }

    void copyFromForce(const Derivative & derivative){
        this->acc  = derivative.acc + derivative.accg;
        this->accg = derivative.accg;
        this->udot = derivative.udot;
        this->vsmx = derivative.vsmx;
    }

    void copyFromForce(const Gravity & gravity) {
        this->acc  += gravity.acc;
#ifdef SYMMETRIZED_GRAVITY
        this->pot   = gravity.pot;
        this->accg += gravity.acc;
#else
        this->pot   = gravity.pot + this->mass / this->eps;
        this->accg  = gravity.acc;
#endif
    }

    void readAscii(FILE *fp) {
        fscanf(fp, "%lld%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
               &this->id, &this->mass,
               &this->pos[0], &this->pos[1], &this->pos[2],
               &this->vel[0], &this->vel[1], &this->vel[2],
               &this->uene,   &this->alph,   &this->ksr);
    }

    void writeAscii(FILE *fp) const {
        fprintf(fp, "%6d %+e", this->id, this->mass);
        fprintf(fp, " %+e %+e %+e", this->pos[0], this->pos[1], this->pos[2]);
        fprintf(fp, " %+e %+e %+e", this->vel[0], this->vel[1], this->vel[2]);
        fprintf(fp, " %+e %+e %+e", this->acc[0], this->acc[1], this->acc[2]);
        fprintf(fp, " %+e %+e %+e", this->uene, this->alph, this->ksr);
        fprintf(fp, " %+e %+e %+e", this->dens, this->vsnd, this->pres);
        fprintf(fp, " %+e %+e %+e", this->divv, this->rotv, this->bswt);
        fprintf(fp, " %+e %6d %+e", this->grdh, this->np, this->pot);
//        fprintf(fp, " %+e %+e %+e", this->accg[0], this->accg[1], this->accg[2]);
//        fprintf(fp, " %+e %+e", this->udot, this->vsmx);
        fprintf(fp, "\n");
    }

    void referEquationOfState() {
        this->pres = cinv * this->dens * this->uene;
        this->vsnd = sqrt((1. + cinv) * this->pres / this->dens);
    }

    void calcBalsaraSwitch() {
        /*
        this->bswt = fabs(this->grdh * this->divv)
            / (fabs(this->grdh * this->divv) + fabs(this->grdh * this->rotv)
               + 1e-4 * this->vsnd * KernelSph::ksrh / this->ksr);
        */
        this->bswt = fabs(this->divv)
            / (fabs(this->divv) + fabs(this->rotv)
               + 1e-4 * this->vsnd * KernelSph::ksrh / this->ksr);
    }

    void calcAlphaDot() {
        PS::F64 src;
        src = - divv * (alphamax - this->alph);
        src = (src > 0.) ? src : 0.;
        this->adot = - (this->alph - alphamin)
            * (0.25 * this->vsnd * KernelSph::ksrh) / this->ksr + src;
    }

#if 1
    PS::F64 calcTimeStep() {
        return tceff * 2. * this->ksr / (this->vsmx * KernelSph::ksrh);
        //return 0.5 * tceff * 2. * this->ksr / (this->vsmx * KernelSph::ksrh);
    }
#else
    PS::F64 calcTimeStep() {
        PS::F64 dthydro = tceff * 2. * this->ksr / (this->vsmx * KernelSph::ksrh);
        PS::F64 dtgrav  = tceff * sqrt(this->ksr * this->ksr / (this->acc * this->acc));
        return ((dthydro < dtgrav) ? dthydro : dtgrav);
    }
#endif

//    PS::F64 calcTimeStep() {
//        PS::F64 dthydro  = tceff * 2. * this->ksr / this->vsmx;
//        PS::F64 dtenergy = tceff * this->uene / fabs(this->udot);
//        return ((dthydro < dtenergy) ? dthydro : dtenergy);
//    }

    PS::F64 calcEnergy() {
#ifdef GRAVITY
        return this->mass * (0.5 * this->vel * this->vel + this->uene + 0.5 * this->pot);
#else
        return this->mass * (0.5 * this->vel * this->vel + this->uene);
#endif
    }

    static inline PS::F64 calcVolumeInverse(const PS::F64 hi);
    static inline PS::F64 calcPowerOfDimInverse(PS::F64 mass,
                                                PS::F64 dens);
    static inline v4df calcVolumeInverse(const v4df hi);
    static inline v8sf calcVolumeInverse(const v8sf hi);

#ifdef DAMPING
    inline void addAdditionalForce() {
        ;
    }

    void predict(PS::F64 dt) {
        this->pos   = this->pos  +       this->vel  * dt  + 0.5 * this->acc * dt * dt;
        this->vel2  = this->vel  + 0.5 * this->acc  * dt;
        this->vel   = this->vel  +       this->acc  * dt;
    }

    void correct(PS::F64 dt) {
        this->vel   = this->vel2  + 0.5 * this->acc  * dt;
    }
#else
    inline void addAdditionalForce() {
        ;
    }

    void predict(PS::F64 dt) {
        this->pos   = this->pos  +       this->vel  * dt  + 0.5 * this->acc * dt * dt;
        this->vel2  = this->vel  + 0.5 * this->acc  * dt;
        this->vel   = this->vel  +       this->acc  * dt;
        this->uene2 = this->uene + 0.5 * this->udot * dt;
        this->uene  = this->uene +       this->udot * dt;
        this->alph2 = this->alph + 0.5 * this->adot * dt;
        this->alph  = this->alph +       this->adot * dt;
    }

    void correct(PS::F64 dt) {
        this->vel   = this->vel2  + 0.5 * this->acc  * dt;
        this->uene  = this->uene2 + 0.5 * this->udot * dt;
        this->alph  = this->alph2 + 0.5 * this->adot * dt;
    }
#endif

    void dampVelocity(PS::F64 dt) {
//        this->vel *= exp(- 0.1 * this->vsnd / this->ksr * dt);
        this->vel *= exp(- 0.1 * this->vsnd * KernelSph::ksrh / this->ksr * dt);
    }

};

PS::F64ort SPH::cbox;
PS::F64    SPH::cinv;
PS::F64    SPH::tceff;
PS::F64    SPH::alphamax, SPH::alphamin;
//PS::F64    SPH::eps = 1e-3;
PS::F64    SPH::eps;
PS::F64    SPH::ksrmax = std::numeric_limits<double>::max();
PS::F64vec SPH::omg;

#ifdef USE_AT1D
inline PS::F64 SPH::calcVolumeInverse(const PS::F64 hi) {return hi;}
inline PS::F64 SPH::calcPowerOfDimInverse(PS::F64 mass,
                                          PS::F64 dens) {
    return mass / dens;
}
inline v4df SPH::calcVolumeInverse(const v4df hi) {return hi;}
inline v8sf SPH::calcVolumeInverse(const v8sf hi) {return hi;}
#else
#ifdef USE_AT2D
inline PS::F64 SPH::calcVolumeInverse(const PS::F64 hi) {return hi * hi;}
inline PS::F64 SPH::calcPowerOfDimInverse(PS::F64 mass,
                                          PS::F64 dens) {
    return sqrt(mass / dens);
}
inline v4df SPH::calcVolumeInverse(const v4df hi) {return hi * hi;}
inline v8sf SPH::calcVolumeInverse(const v8sf hi) {return hi * hi;}
#else
inline PS::F64 SPH::calcVolumeInverse(const PS::F64 hi) {return hi * hi * hi;}
inline PS::F64 SPH::calcPowerOfDimInverse(PS::F64 mass,
                                          PS::F64 dens) {
    return pow(mass / dens, 1.d / 3.d);
}
inline v4df SPH::calcVolumeInverse(const v4df hi) {return hi * hi * hi;}
inline v8sf SPH::calcVolumeInverse(const v8sf hi) {return hi * hi * hi;}
#endif
#endif

template <class Theader>
void setParameterParticle(Theader & header) {
    SPH::cbox     = header.cbox;
    SPH::cinv     = header.gamma - 1.d;
    SPH::alphamax = header.alphamax;
    SPH::alphamin = header.alphamin;
    SPH::tceff    = header.tceff;
    SPH::eps      = header.eps;

    return;
}

template <class Tptcl>
void calcFieldVariable(Tptcl & system) {
    return;
}

template <class Tptcl>
void finalizeSimulation(PS::S32 nstp,
                        Tptcl & system) {
    char filename[64];

    sprintf(filename, "snap/sph_t%04d.dat", nstp);
    system.writeParticleAscii(filename);

    PS::F64    msloc = 0.0d;
    PS::F64vec xcloc = 0.0d;
    PS::F64vec vcloc = 0.0d;
    PS::S32 nloc = system.getNumberOfParticleLocal();
    for(PS::S32 i = 0; i < nloc; i++) {
        msloc += system[i].mass;
        xcloc += system[i].mass * system[i].pos;
        vcloc += system[i].mass * system[i].vel;
    }
}

<commit_msg>update the latest version<commit_after>#pragma once

namespace CodeUnit {
    PS::F64 grav         = 1.;
    PS::F64 UnitOfLength = 1.;
    PS::F64 UnitOfEnergy = 1.;
}

class Density{
public:
    PS::F64 dens;
    PS::F64 grdh;
    PS::F64 ksr;
    PS::F64 rotv;
    PS::F64 divv;
    PS::S32 np;
    bool    itr;
    PS::F64 eta;
    void clear(){
        dens = 0.0;
        grdh = 0.0;
        ksr  = 0.0;
        rotv = 0.0;
        divv = 0.0;
        np   = 0;
        itr  = false;
        eta  = 0.0;
    }
};

class Derivative{
public:
    PS::F64vec acc;
    PS::F64vec accg;
    PS::F64    udot;
    PS::F64    vsmx;
    void clear(){
        acc  = 0.0;
        accg = 0.0;
        udot = 0.0;
        vsmx = 0.0;
    }
};

class Gravity{
public:
    PS::F64vec acc;
    PS::F64    pot;
    void clear(){
        acc = 0.0;
        pot = 0.0;
    }
};

class Header {
public:
    PS::F64    time;
    PS::F64    tend;
    PS::F64    dtsp;
    PS::F64ort cbox;
    PS::F64    gamma;
    PS::F64    alphamax;
    PS::F64    alphamin;
    PS::F64    tceff;
    PS::F64    eps;
    PS::S64    nptcl;

    Header() {
        time       = 0.0;
        tend       = 0.0;
        dtsp       = 0.0;
        cbox.low_  = 0.0;
        cbox.high_ = 0.0;
        gamma      = 0.0;
        alphamax   = 0.0;
        alphamin   = 0.0;
        tceff      = 0.0;
        eps        = 0.0;
        nptcl      = 0;
    }

    PS::S32 readAscii(FILE *fp) {
        fscanf(fp, "%lf%lf%lf", &time, &tend, &dtsp);
        fscanf(fp, "%lf%lf%lf", &cbox.low_[0], &cbox.low_[1], &cbox.low_[2]);
        fscanf(fp, "%lf%lf%lf", &cbox.high_[0], &cbox.high_[1], &cbox.high_[2]);
        fscanf(fp, "%lf%lf%lf%lf", &gamma, &alphamax, &alphamin, &tceff);
#ifdef GRAVITY
        fscanf(fp, "%lf", &eps);
#endif
        fscanf(fp, "%d", &nptcl);

        return nptcl;
    }
};

class SPH{
public:
    PS::S64    id;
    PS::F64    mass;
    PS::F64vec pos;
    PS::F64vec vel;
    PS::F64vec acc;
    PS::F64    uene;
    PS::F64    udot;
    PS::F64    alph;
    PS::F64    alph2;
    PS::F64    adot;
    PS::F64    dens;
    PS::F64    pres;
    PS::F64    vsnd;
    PS::F64    divv;
    PS::F64    rotv;
    PS::F64    bswt;
    PS::S64    np;
    PS::F64vec vel2;
    PS::F64    uene2;
    PS::F64    ksr;
    PS::F64    rs;
    PS::F64    grdh;
    PS::F64    vsmx;
    PS::F64    pot;
    PS::F64vec accg;
    PS::F64    eta;
    static PS::F64ort cbox;
    static PS::F64    cinv;
    static PS::F64    alphamax, alphamin;
    static PS::F64    tceff;
    static PS::F64    eps;
    static PS::F64    ksrmax;
    static PS::F64vec omg;

    PS::F64vec getPos() const {
        return this->pos;
    }

    void setPos(PS::F64vec pos_new) {
        this->pos = pos_new;
    }

    void copyFromForce(const Density & density){
        this->dens = density.dens;
        this->grdh = density.grdh;
        this->np   = density.np;
        this->ksr  = density.ksr;
        this->rotv = density.rotv;
        this->divv = density.divv;
        this->eta  = density.eta;
    }

    void copyFromForce(const Derivative & derivative){
        this->acc  = derivative.acc + derivative.accg;
        this->accg = derivative.accg;
        this->udot = derivative.udot;
        this->vsmx = derivative.vsmx;
    }

    void copyFromForce(const Gravity & gravity) {
        this->acc  += gravity.acc;
#ifdef SYMMETRIZED_GRAVITY
        this->pot   = gravity.pot;
        this->accg += gravity.acc;
#else
        this->pot   = gravity.pot + this->mass / this->eps;
        this->accg  = gravity.acc;
#endif
    }

    void readAscii(FILE *fp) {
        fscanf(fp, "%lld%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
               &this->id, &this->mass,
               &this->pos[0], &this->pos[1], &this->pos[2],
               &this->vel[0], &this->vel[1], &this->vel[2],
               &this->uene,   &this->alph,   &this->ksr);
    }

    void writeAscii(FILE *fp) const {
        fprintf(fp, "%6d %+e", this->id, this->mass);
        fprintf(fp, " %+e %+e %+e", this->pos[0], this->pos[1], this->pos[2]);
        fprintf(fp, " %+e %+e %+e", this->vel[0], this->vel[1], this->vel[2]);
        fprintf(fp, " %+e %+e %+e", this->acc[0], this->acc[1], this->acc[2]);
        fprintf(fp, " %+e %+e %+e", this->uene, this->alph, this->ksr);
        fprintf(fp, " %+e %+e %+e", this->dens, this->vsnd, this->pres);
        fprintf(fp, " %+e %+e %+e", this->divv, this->rotv, this->bswt);
        fprintf(fp, " %+e %6d %+e", this->grdh, this->np, this->pot);
//        fprintf(fp, " %+e %+e %+e", this->accg[0], this->accg[1], this->accg[2]);
//        fprintf(fp, " %+e %+e", this->udot, this->vsmx);
        fprintf(fp, "\n");
    }

    void referEquationOfState() {
        this->pres = cinv * this->dens * this->uene;
        this->vsnd = sqrt((1. + cinv) * this->pres / this->dens);
    }

    void calcBalsaraSwitch() {
        /*
        this->bswt = fabs(this->grdh * this->divv)
            / (fabs(this->grdh * this->divv) + fabs(this->grdh * this->rotv)
               + 1e-4 * this->vsnd * KernelSph::ksrh / this->ksr);
        */
        this->bswt = fabs(this->divv)
            / (fabs(this->divv) + fabs(this->rotv)
               + 1e-4 * this->vsnd * KernelSph::ksrh / this->ksr);
    }

    void calcAlphaDot() {
        PS::F64 src;
        src = - divv * (alphamax - this->alph);
        src = (src > 0.) ? src : 0.;
        this->adot = - (this->alph - alphamin)
            * (0.25 * this->vsnd * KernelSph::ksrh) / this->ksr + src;
    }

#if 1
    PS::F64 calcTimeStep() {
        return tceff * 2. * this->ksr / (this->vsmx * KernelSph::ksrh);
    }
#else
    PS::F64 calcTimeStep() {
        PS::F64 dthydro = tceff * 2. * this->ksr / (this->vsmx * KernelSph::ksrh);
        PS::F64 dtgrav  = tceff * sqrt(this->ksr * this->ksr / (this->acc * this->acc));
        return ((dthydro < dtgrav) ? dthydro : dtgrav);
    }
#endif

//    PS::F64 calcTimeStep() {
//        PS::F64 dthydro  = tceff * 2. * this->ksr / this->vsmx;
//        PS::F64 dtenergy = tceff * this->uene / fabs(this->udot);
//        return ((dthydro < dtenergy) ? dthydro : dtenergy);
//    }

    PS::F64 calcEnergy() {
#ifdef GRAVITY
        return this->mass * (0.5 * this->vel * this->vel + this->uene + 0.5 * this->pot);
#else
        return this->mass * (0.5 * this->vel * this->vel + this->uene);
#endif
    }

    static inline PS::F64 calcVolumeInverse(const PS::F64 hi);
    static inline PS::F64 calcPowerOfDimInverse(PS::F64 mass,
                                                PS::F64 dens);
    static inline v4df calcVolumeInverse(const v4df hi);
    static inline v8sf calcVolumeInverse(const v8sf hi);

#ifdef DAMPING
    inline void addAdditionalForce() {
        ;
    }

    void predict(PS::F64 dt) {
        this->pos   = this->pos  +       this->vel  * dt  + 0.5 * this->acc * dt * dt;
        this->vel2  = this->vel  + 0.5 * this->acc  * dt;
        this->vel   = this->vel  +       this->acc  * dt;
    }

    void correct(PS::F64 dt) {
        this->vel   = this->vel2  + 0.5 * this->acc  * dt;
    }
#else
    inline void addAdditionalForce() {
        ;
    }

    void predict(PS::F64 dt) {
        this->pos   = this->pos  +       this->vel  * dt  + 0.5 * this->acc * dt * dt;
        this->vel2  = this->vel  + 0.5 * this->acc  * dt;
        this->vel   = this->vel  +       this->acc  * dt;
        this->uene2 = this->uene + 0.5 * this->udot * dt;
        this->uene  = this->uene +       this->udot * dt;
        this->alph2 = this->alph + 0.5 * this->adot * dt;
        this->alph  = this->alph +       this->adot * dt;
    }

    void correct(PS::F64 dt) {
        this->vel   = this->vel2  + 0.5 * this->acc  * dt;
        this->uene  = this->uene2 + 0.5 * this->udot * dt;
        this->alph  = this->alph2 + 0.5 * this->adot * dt;
    }
#endif

    void dampVelocity(PS::F64 dt) {
//        this->vel *= exp(- 0.1 * this->vsnd / this->ksr * dt);
        this->vel *= exp(- 0.1 * this->vsnd * KernelSph::ksrh / this->ksr * dt);
    }

};

PS::F64ort SPH::cbox;
PS::F64    SPH::cinv;
PS::F64    SPH::tceff;
PS::F64    SPH::alphamax, SPH::alphamin;
//PS::F64    SPH::eps = 1e-3;
PS::F64    SPH::eps;
PS::F64    SPH::ksrmax = std::numeric_limits<double>::max();
PS::F64vec SPH::omg;

#ifdef USE_AT1D
inline PS::F64 SPH::calcVolumeInverse(const PS::F64 hi) {return hi;}
inline PS::F64 SPH::calcPowerOfDimInverse(PS::F64 mass,
                                          PS::F64 dens) {
    return mass / dens;
}
inline v4df SPH::calcVolumeInverse(const v4df hi) {return hi;}
inline v8sf SPH::calcVolumeInverse(const v8sf hi) {return hi;}
#else
#ifdef USE_AT2D
inline PS::F64 SPH::calcVolumeInverse(const PS::F64 hi) {return hi * hi;}
inline PS::F64 SPH::calcPowerOfDimInverse(PS::F64 mass,
                                          PS::F64 dens) {
    return sqrt(mass / dens);
}
inline v4df SPH::calcVolumeInverse(const v4df hi) {return hi * hi;}
inline v8sf SPH::calcVolumeInverse(const v8sf hi) {return hi * hi;}
#else
inline PS::F64 SPH::calcVolumeInverse(const PS::F64 hi) {return hi * hi * hi;}
inline PS::F64 SPH::calcPowerOfDimInverse(PS::F64 mass,
                                          PS::F64 dens) {
    return pow(mass / dens, 1.d / 3.d);
}
inline v4df SPH::calcVolumeInverse(const v4df hi) {return hi * hi * hi;}
inline v8sf SPH::calcVolumeInverse(const v8sf hi) {return hi * hi * hi;}
#endif
#endif

template <class Theader>
void setParameterParticle(Theader & header) {
    SPH::cbox     = header.cbox;
    SPH::cinv     = header.gamma - 1.d;
    SPH::alphamax = header.alphamax;
    SPH::alphamin = header.alphamin;
    SPH::tceff    = header.tceff;
    SPH::eps      = header.eps;

    return;
}

template <class Tptcl>
void calcFieldVariable(Tptcl & system) {
    return;
}

template <class Tptcl>
void finalizeSimulation(PS::S32 nstp,
                        Tptcl & system) {
    char filename[64];

    sprintf(filename, "snap/sph_t%04d.dat", nstp);
    system.writeParticleAscii(filename);

    PS::F64    msloc = 0.0d;
    PS::F64vec xcloc = 0.0d;
    PS::F64vec vcloc = 0.0d;
    PS::S32 nloc = system.getNumberOfParticleLocal();
    for(PS::S32 i = 0; i < nloc; i++) {
        msloc += system[i].mass;
        xcloc += system[i].mass * system[i].pos;
        vcloc += system[i].mass * system[i].vel;
    }
}

<|endoftext|>


<commit_before>/*
  Copyright 2013 Larry Gritz and the other authors and contributors.
  All Rights Reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:
  * Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
  * Neither the name of the software's owners nor the names of its
    contributors may be used to endorse or promote products derived from
    this software without specific prior written permission.
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  (This is the Modified BSD License)
*/

#include <boost/bind.hpp>
#include <OpenEXR/half.h>

#include <cmath>
#include <iostream>
#include <stdexcept>

#include "imagebuf.h"
#include "imagebufalgo.h"
#include "imagebufalgo_util.h"
#include "dassert.h"
#include "sysutil.h"
#include "thread.h"

OIIO_NAMESPACE_ENTER
{

// Helper for flatten: identify channels in the spec that are important to
// deciphering deep images. Return true if appropriate alphas were found.
static bool
find_deep_channels (const ImageSpec &spec, int &alpha_channel,
                    int &RA_channel, int &GA_channel, int &BA_channel,
                    int &R_channel, int &G_channel, int &B_channel,
                    int &Z_channel, int &Zback_channel)
{
    static const char *names[] = { "A", "RA", "GA", "BA",
                                   "R", "G", "B", "Z", "Zback", NULL };
    int *chans[] = { &alpha_channel, &RA_channel, &GA_channel, &BA_channel,
                     &R_channel, &G_channel, &B_channel,
                     &Z_channel, &Zback_channel };
    for (int i = 0;  names[i];  ++i)
        *chans[i] = -1;
    for (int c = 0, e = int(spec.channelnames.size()); c < e; ++c) {
        for (int i = 0;  names[i];  ++i) {
            if (spec.channelnames[c] == names[i]) {
                *chans[i] = c;
                break;
            }
        }
    }
    if (Zback_channel < 0)
        Zback_channel = Z_channel;
    return (alpha_channel >= 0 ||
            (RA_channel >= 0 && GA_channel >= 0 && BA_channel >= 0));
}

// FIXME -- NOT CORRECT!  This code assumes sorted, non-overlapping samples.
// That is not a valid assumption in general. We will come back to fix this.
template<class DSTTYPE>
static bool
flatten_ (ImageBuf &dst, const ImageBuf &src,
          ROI roi, int nthreads)
{
    if (nthreads != 1 && roi.npixels() >= 1000) {
        // Possible multiple thread case -- recurse via parallel_image
        ImageBufAlgo::parallel_image (
            boost::bind(flatten_<DSTTYPE>, boost::ref(dst), boost::cref(src),
                        _1 /*roi*/, 1 /*nthreads*/),
            roi, nthreads);
        return true;
    }

    // We need to convert our "cumulative" alpha values to the
    // "local" values that OpenEXR conventions dictate.
    // For cumulative values cum[i] and alpha[i], we can derive
    // local val[i] as follows:
    //       cum[i] = cum[i-1] + (1 - alpha[i-1]) * val[i]
    //       val[i] = (cum[i] - cum[i-1]) / (1 - alpha[i-1])

    const ImageSpec &srcspec (src.spec());
    int nc = srcspec.nchannels;

    int alpha_channel, RA_channel, GA_channel, BA_channel;
    int R_channel, G_channel, B_channel;
    int Z_channel, Zback_channel;
    if (! find_deep_channels (srcspec, alpha_channel,
                              RA_channel, GA_channel, BA_channel,
                              R_channel, G_channel, B_channel,
                              Z_channel, Zback_channel)) {
        dst.error ("No alpha channel could be identified");
        return false;
    }

    float *val = ALLOCA (float, nc);

    for (ImageBuf::Iterator<DSTTYPE> r (dst, roi);  !r.done();  ++r) {
        int x = r.x(), y = r.y(), z = r.z();
        int samps = src.deep_samples (x, y, z);
        // Clear accumulated values for this pixel (0 for colors, big for Z)
        memset (val, 0, nc*sizeof(float));
        if (Z_channel >= 0 && samps == 0)
            val[Z_channel] = 1.0e30;
        if (Zback_channel >= 0 && samps == 0)
            val[Zback_channel] = 1.0e30;

        for (int s = 0;  s < samps;  ++s) {
            float RA, GA, BA, alpha;   // The running totals
            if (RA_channel >= 0) {
                RA = val[RA_channel];
                GA = val[GA_channel];
                BA = val[BA_channel];
                alpha = (RA + GA + BA) / 3.0f;
            } else {
                alpha = val[alpha_channel];
                RA = GA = BA = alpha;
            }
            if (alpha >= 1)
                break;
            for (int c = 0;  c < nc;  ++c) {
                float a = alpha;
                if (c == R_channel)
                    a = RA;
                else if (c == G_channel)
                    a = GA;
                else if (c == B_channel)
                    a = BA;
                val[c] += (1.0f - a) * src.deep_value (x, y, z, c, s);
            }
        }

        for (int c = roi.chbegin;  c < roi.chend;  ++c)
            r[c] = val[c];
    }

    return true;
}

bool
ImageBufAlgo::flatten (ImageBuf &dst, const ImageBuf &src,
                       ROI roi, int nthreads)
{
    // Construct an ideal spec for dst, which is like src but not deep.
    ImageSpec force_spec = src.spec();
    force_spec.deep = false;
    force_spec.channelformats.clear();

    if (! IBAprep (roi, &dst, &src, NULL, &force_spec))
        return false;
    if (dst.spec().deep) {
        dst.error ("Cannot flatten to a deep image");
        return false;
    }

    const ImageSpec &srcspec (src.spec());
    int alpha_channel, RA_channel, GA_channel, BA_channel;
    int R_channel, G_channel, B_channel, Z_channel, Zback_channel;
    if (! find_deep_channels (srcspec, alpha_channel,
                              RA_channel, GA_channel, BA_channel,
                              R_channel, G_channel, B_channel,
                              Z_channel, Zback_channel)) {
        dst.error ("No alpha channel could be identified");
        return false;
    }

    OIIO_DISPATCH_TYPES ("flatten", flatten_, dst.spec().format,
                         dst, src, roi, nthreads);
}

}
OIIO_NAMESPACE_EXIT
<commit_msg>Fix missing return in ImageBugAlgo::flatten().<commit_after>/*
  Copyright 2013 Larry Gritz and the other authors and contributors.
  All Rights Reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:
  * Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
  * Neither the name of the software's owners nor the names of its
    contributors may be used to endorse or promote products derived from
    this software without specific prior written permission.
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  (This is the Modified BSD License)
*/

#include <boost/bind.hpp>
#include <OpenEXR/half.h>

#include <cmath>
#include <iostream>
#include <stdexcept>

#include "imagebuf.h"
#include "imagebufalgo.h"
#include "imagebufalgo_util.h"
#include "dassert.h"
#include "sysutil.h"
#include "thread.h"

OIIO_NAMESPACE_ENTER
{

// Helper for flatten: identify channels in the spec that are important to
// deciphering deep images. Return true if appropriate alphas were found.
static bool
find_deep_channels (const ImageSpec &spec, int &alpha_channel,
                    int &RA_channel, int &GA_channel, int &BA_channel,
                    int &R_channel, int &G_channel, int &B_channel,
                    int &Z_channel, int &Zback_channel)
{
    static const char *names[] = { "A", "RA", "GA", "BA",
                                   "R", "G", "B", "Z", "Zback", NULL };
    int *chans[] = { &alpha_channel, &RA_channel, &GA_channel, &BA_channel,
                     &R_channel, &G_channel, &B_channel,
                     &Z_channel, &Zback_channel };
    for (int i = 0;  names[i];  ++i)
        *chans[i] = -1;
    for (int c = 0, e = int(spec.channelnames.size()); c < e; ++c) {
        for (int i = 0;  names[i];  ++i) {
            if (spec.channelnames[c] == names[i]) {
                *chans[i] = c;
                break;
            }
        }
    }
    if (Zback_channel < 0)
        Zback_channel = Z_channel;
    return (alpha_channel >= 0 ||
            (RA_channel >= 0 && GA_channel >= 0 && BA_channel >= 0));
}

// FIXME -- NOT CORRECT!  This code assumes sorted, non-overlapping samples.
// That is not a valid assumption in general. We will come back to fix this.
template<class DSTTYPE>
static bool
flatten_ (ImageBuf &dst, const ImageBuf &src,
          ROI roi, int nthreads)
{
    if (nthreads != 1 && roi.npixels() >= 1000) {
        // Possible multiple thread case -- recurse via parallel_image
        ImageBufAlgo::parallel_image (
            boost::bind(flatten_<DSTTYPE>, boost::ref(dst), boost::cref(src),
                        _1 /*roi*/, 1 /*nthreads*/),
            roi, nthreads);
        return true;
    }

    // We need to convert our "cumulative" alpha values to the
    // "local" values that OpenEXR conventions dictate.
    // For cumulative values cum[i] and alpha[i], we can derive
    // local val[i] as follows:
    //       cum[i] = cum[i-1] + (1 - alpha[i-1]) * val[i]
    //       val[i] = (cum[i] - cum[i-1]) / (1 - alpha[i-1])

    const ImageSpec &srcspec (src.spec());
    int nc = srcspec.nchannels;

    int alpha_channel, RA_channel, GA_channel, BA_channel;
    int R_channel, G_channel, B_channel;
    int Z_channel, Zback_channel;
    if (! find_deep_channels (srcspec, alpha_channel,
                              RA_channel, GA_channel, BA_channel,
                              R_channel, G_channel, B_channel,
                              Z_channel, Zback_channel)) {
        dst.error ("No alpha channel could be identified");
        return false;
    }

    float *val = ALLOCA (float, nc);

    for (ImageBuf::Iterator<DSTTYPE> r (dst, roi);  !r.done();  ++r) {
        int x = r.x(), y = r.y(), z = r.z();
        int samps = src.deep_samples (x, y, z);
        // Clear accumulated values for this pixel (0 for colors, big for Z)
        memset (val, 0, nc*sizeof(float));
        if (Z_channel >= 0 && samps == 0)
            val[Z_channel] = 1.0e30;
        if (Zback_channel >= 0 && samps == 0)
            val[Zback_channel] = 1.0e30;

        for (int s = 0;  s < samps;  ++s) {
            float RA, GA, BA, alpha;   // The running totals
            if (RA_channel >= 0) {
                RA = val[RA_channel];
                GA = val[GA_channel];
                BA = val[BA_channel];
                alpha = (RA + GA + BA) / 3.0f;
            } else {
                alpha = val[alpha_channel];
                RA = GA = BA = alpha;
            }
            if (alpha >= 1)
                break;
            for (int c = 0;  c < nc;  ++c) {
                float a = alpha;
                if (c == R_channel)
                    a = RA;
                else if (c == G_channel)
                    a = GA;
                else if (c == B_channel)
                    a = BA;
                val[c] += (1.0f - a) * src.deep_value (x, y, z, c, s);
            }
        }

        for (int c = roi.chbegin;  c < roi.chend;  ++c)
            r[c] = val[c];
    }

    return true;
}

bool
ImageBufAlgo::flatten (ImageBuf &dst, const ImageBuf &src,
                       ROI roi, int nthreads)
{
    // Construct an ideal spec for dst, which is like src but not deep.
    ImageSpec force_spec = src.spec();
    force_spec.deep = false;
    force_spec.channelformats.clear();

    if (! IBAprep (roi, &dst, &src, NULL, &force_spec))
        return false;
    if (dst.spec().deep) {
        dst.error ("Cannot flatten to a deep image");
        return false;
    }

    const ImageSpec &srcspec (src.spec());
    int alpha_channel, RA_channel, GA_channel, BA_channel;
    int R_channel, G_channel, B_channel, Z_channel, Zback_channel;
    if (! find_deep_channels (srcspec, alpha_channel,
                              RA_channel, GA_channel, BA_channel,
                              R_channel, G_channel, B_channel,
                              Z_channel, Zback_channel)) {
        dst.error ("No alpha channel could be identified");
        return false;
    }

    OIIO_DISPATCH_TYPES ("flatten", flatten_, dst.spec().format,
                         dst, src, roi, nthreads);
    return false;
}

}
OIIO_NAMESPACE_EXIT
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: 3dchld.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 04:57:29 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SD_3DCHLD_HXX
#define _SD_3DCHLD_HXX

#ifndef _SFX_CHILDWIN_HXX //autogen
#include <sfx2/childwin.hxx>
#endif

/*************************************************************************
|*
|* Ableitung vom SfxChildWindow als "Behaelter" fuer 3D Window
|*
\************************************************************************/

class Sd3DChildWindow : public SfxChildWindow
{
 public:
    Sd3DChildWindow( Window*, USHORT, SfxBindings*, SfxChildWinInfo* );

    SFX_DECL_CHILDWINDOW(Sd3DChildWindow);
};

#endif      // _SD_3DCHLD_HXX

<commit_msg>INTEGRATION: CWS changefileheader (1.2.624); FILE MERGED 2008/04/01 15:34:58 thb 1.2.624.2: #i85898# Stripping all external header guards 2008/03/31 13:58:07 rt 1.2.624.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: 3dchld.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _SD_3DCHLD_HXX
#define _SD_3DCHLD_HXX

#include <sfx2/childwin.hxx>

/*************************************************************************
|*
|* Ableitung vom SfxChildWindow als "Behaelter" fuer 3D Window
|*
\************************************************************************/

class Sd3DChildWindow : public SfxChildWindow
{
 public:
    Sd3DChildWindow( Window*, USHORT, SfxBindings*, SfxChildWinInfo* );

    SFX_DECL_CHILDWINDOW(Sd3DChildWindow);
};

#endif      // _SD_3DCHLD_HXX

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: fupage.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: vg $ $Date: 2005-02-17 09:43:20 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SD_FU_PAGE_HXX
#define SD_FU_PAGE_HXX

#ifndef SD_FU_POOR_HXX
#include "fupoor.hxx"
#endif

class SfxItemSet;
class SdBackgroundObjUndoAction;
class SdPage;

namespace sd {
class DrawViewShell;

class FuPage
    : public FuPoor
{
 public:
    TYPEINFO();

    FuPage (
        ViewShell* pViewSh,
        ::sd::Window* pWin,
        ::sd::View* pView,
        SdDrawDocument* pDoc,
        SfxRequest& rReq );
    virtual ~FuPage (void);

    virtual void Activate();           // Function aktivieren
    virtual void Deactivate();         // Function deaktivieren

    const SfxItemSet* ExecuteDialog( Window* pParent );
    void ApplyItemSet( const SfxItemSet* pArgs );

private:
    SfxRequest&                 mrReq;
    const SfxItemSet*           mpArgs;
    SdBackgroundObjUndoAction*  mpBackgroundObjUndoAction;
    Size                        maSize;
    bool                        mbPageBckgrdDeleted;
    bool                        mbMasterPage;
    bool                        mbDisplayBackgroundTabPage;
    SdPage*                     mpPage;
    DrawViewShell*              mpDrawViewShell;
};

} // end of namespace sd

#endif

<commit_msg>INTEGRATION: CWS ooo19126 (1.3.198); FILE MERGED 2005/09/05 13:23:11 rt 1.3.198.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fupage.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 05:37:08 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SD_FU_PAGE_HXX
#define SD_FU_PAGE_HXX

#ifndef SD_FU_POOR_HXX
#include "fupoor.hxx"
#endif

class SfxItemSet;
class SdBackgroundObjUndoAction;
class SdPage;

namespace sd {
class DrawViewShell;

class FuPage
    : public FuPoor
{
 public:
    TYPEINFO();

    FuPage (
        ViewShell* pViewSh,
        ::sd::Window* pWin,
        ::sd::View* pView,
        SdDrawDocument* pDoc,
        SfxRequest& rReq );
    virtual ~FuPage (void);

    virtual void Activate();           // Function aktivieren
    virtual void Deactivate();         // Function deaktivieren

    const SfxItemSet* ExecuteDialog( Window* pParent );
    void ApplyItemSet( const SfxItemSet* pArgs );

private:
    SfxRequest&                 mrReq;
    const SfxItemSet*           mpArgs;
    SdBackgroundObjUndoAction*  mpBackgroundObjUndoAction;
    Size                        maSize;
    bool                        mbPageBckgrdDeleted;
    bool                        mbMasterPage;
    bool                        mbDisplayBackgroundTabPage;
    SdPage*                     mpPage;
    DrawViewShell*              mpDrawViewShell;
};

} // end of namespace sd

#endif

<|endoftext|>


<commit_before>// Copyright (c) 2016 Kasper Kronborg Isager.
#pragma once

#include <string>
#include <vector>

namespace lsh {
  class vector {
    private:
      /**
       * The number of components in this vector.
       */
      unsigned int size_;

      /**
       * The chunked components of this vector.
       */
      std::vector<unsigned int> components_;

    public:
      /**
       * Construct a new vector.
       *
       * @param components The components of the vector.
       */
      vector(std::vector<bool> components);

      /**
       * Get the number of components in this vector.
       *
       * @return The number of components in this vector.
       */
      unsigned int size();

      /**
       * Get the component at the specified index of this vector.
       *
       * @param index The index of the component to get.
       * @return The component at the index.
       */
      bool get(int index);

      /**
       * Get a string representation of this vector.
       *
       * @return The string representation of the vector.
       */
      std::string to_string();

      /**
       * Check if this vector equals another vector.
       *
       * @param vector The other vector.
       * @return `true` if this vector equals the other vector, otherwise `false`.
       */
      bool operator==(vector& vector);

      /**
       * Compupte the hash of this vector.
       *
       * @return The hash of this vector.
       */
      int hash();

      /**
       * Compute the distance between two vectors.
       *
       * @see http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
       *
       * @param u The first vector.
       * @param v The second vector.
       * @return The distance between the two vectors.
       */
      static int distance(vector& u, vector& v);
  };
}
<commit_msg>Allow use of `vector` in `std::hash`<commit_after>// Copyright (c) 2016 Kasper Kronborg Isager.
#pragma once

#include <string>
#include <vector>

namespace lsh {
  class vector {
    private:
      /**
       * The number of components in this vector.
       */
      unsigned int size_;

      /**
       * The chunked components of this vector.
       */
      std::vector<unsigned int> components_;

    public:
      /**
       * Construct a new vector.
       *
       * @param components The components of the vector.
       */
      vector(std::vector<bool> components);

      /**
       * Get the number of components in this vector.
       *
       * @return The number of components in this vector.
       */
      unsigned int size();

      /**
       * Get the component at the specified index of this vector.
       *
       * @param index The index of the component to get.
       * @return The component at the index.
       */
      bool get(int index);

      /**
       * Get a string representation of this vector.
       *
       * @return The string representation of the vector.
       */
      std::string to_string();

      /**
       * Check if this vector equals another vector.
       *
       * @param vector The other vector.
       * @return `true` if this vector equals the other vector, otherwise `false`.
       */
      bool operator==(vector& vector);

      /**
       * Compupte the hash of this vector.
       *
       * @return The hash of this vector.
       */
      int hash();

      /**
       * Compute the distance between two vectors.
       *
       * @see http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
       *
       * @param u The first vector.
       * @param v The second vector.
       * @return The distance between the two vectors.
       */
      static int distance(vector& u, vector& v);
  };
}

namespace std {
  template <> struct hash<lsh::vector> {
    public:
      /**
       * Compute the hash of a vector.
       *
       * This bit of ugliness is required in order for the C++ standard library
       * to utilise LSH vectors in hash-based data structures such as the unordered
       * sets used in lookup tables.
       *
       * @return The hash of the vector.
       */
      size_t operator()(lsh::vector& vector) {
        return vector.hash();
      }
  };
}
<|endoftext|>


<commit_before>//! @file getusername.cpp
//! @author Andrew Schwartzmeyer <andschwa@microsoft.com>
//! @brief Implements GetUserName Win32 API

#include <errno.h>
#include <langinfo.h>
#include <locale.h>
#include <unistd.h>
#include <string>
#include <unicode/utypes.h>
#include <unicode/ucnv.h>
#include <unicode/ustring.h>
#include <unicode/uchar.h>
#include "getusername.h"

//! @brief GetUserName retrieves the name of the user associated with
//! the current thread.
//!
//! GetUserNameW is the Unicode variation. See [MSDN documentation].
//!
//! @param[out] lpBuffer
//! @parblock
//! A pointer to the buffer to receive the user's
//! logon name. If this buffer is not large enough to contain the
//! entire user name, the function fails.
//!
//! WCHAR_T* is a Unicode [LPTSTR].
//! @endparblock
//!
//! @param[in, out] lpnSize
//! @parblock
//! On input, this variable specifies the size of the lpBuffer buffer,
//! in TCHARs. On output, the variable receives the number of TCHARs
//! copied to the buffer, including the terminating null character.
//!
//! TCHAR is a Unicode 16-bit [WCHAR].
//!
//! If lpBuffer is too small, the function fails and GetLastError
//! returns ERROR_INSUFFICIENT_BUFFER. This parameter receives the
//! required buffer size, including the terminating null character.
//! @endparblock
//!
//! @exception errno Passes these errors via errno to GetLastError:
//! - ERROR_INVALID_PARAMETER: parameter is not valid
//! - ERROR_BAD_ENVIRONMENT: locale is not UTF-8
//! - ERROR_TOO_MANY_OPEN_FILES: already have the maximum allowed number of open files
//! - ERROR_NO_ASSOCIATION: calling process has no controlling terminal
//! - ERROR_INSUFFICIENT_BUFFER: buffer not large enough to hold username string
//! - ERROR_NO_SUCH_USER: there was no corresponding entry in the utmp-file
//! - ERROR_OUTOFMEMORY: insufficient memory to allocate passwd structure
//! - ERROR_NO_ASSOCIATION: standard input didn't refer to a terminal
//! - ERROR_INVALID_FUNCTION: getlogin_r() returned an unrecognized error code
//!
//! @retval 1 If the function succeeds, the return value is a nonzero
//! value, and the variable pointed to by lpnSize contains the number
//! of TCHARs copied to the buffer specified by lpBuffer, including
//! the terminating null character.
//!
//! @retval 0 If the function fails, the return value is zero. To get
//! extended error information, call GetLastError.
//!
//! [MSDN documentation]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724432(v=vs.85).aspx
//! [WCHAR]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx#WCHAR
//! [LPTSTR]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx#LPTSTR
BOOL GetUserNameW(WCHAR_T* lpBuffer, LPDWORD lpnSize)
{
	const std::string utf8 = "UTF-8";

	errno = FALSE;

	// Check parameters
	if (!lpBuffer || !lpnSize) {
		errno = ERROR_INVALID_PARAMETER;
		return 0;
	}

	// Select locale from environment
	setlocale(LC_ALL, "");
	// Check that locale is UTF-8
	if (nl_langinfo(CODESET) != utf8) {
		errno = ERROR_BAD_ENVIRONMENT;
		return FALSE;
	}

	// Get username from system in a thread-safe manner
	std::string username(LOGIN_NAME_MAX, '\0');
	int ret = getlogin_r(&username[0], username.size());
	// Map errno to Win32 Error Codes
	if (ret) {
		switch (errno) {
		case EMFILE:
		case ENFILE:
			errno = ERROR_TOO_MANY_OPEN_FILES;
			break;
		case ENXIO:
			errno = ERROR_NO_ASSOCIATION;
			break;
		case ERANGE:
			errno = ERROR_INSUFFICIENT_BUFFER;
			break;
		case ENOENT:
			errno = ERROR_NO_SUCH_USER;
			break;
		case ENOMEM:
			errno = ERROR_OUTOFMEMORY;
			break;
		case ENOTTY:
			errno = ERROR_NO_ASSOCIATION;
			break;
		default:
			errno = ERROR_INVALID_FUNCTION;
		}
		return FALSE;
	}

	// Convert to char* to WCHAR_T* (UTF-8 to UTF-16 LE w/o BOM)
	std::basic_string<char16_t> username16(LOGIN_NAME_MAX+1, 0);
	icu::UnicodeString username8(username.c_str(), "UTF-8");
	int32_t targetSize = username8.extract(0, username8.length(),
	                                       reinterpret_cast<char*>(&username16[0]),
	                                       (username16.size()-1)*sizeof(char16_t),
	                                       "UTF-16LE");
	// Number of characters including null
	username16.resize(targetSize/sizeof(char16_t)+1);

	// Size in WCHARs including null
	const DWORD size = username16.length();
	if (size > *lpnSize) {
		errno = ERROR_INSUFFICIENT_BUFFER;
		// Set lpnSize if buffer is too small to inform user
		// of necessary size
		*lpnSize = size;
		return 0;
	}

	// Copy bytes from string to buffer
	memcpy(lpBuffer, &username16[0], size*sizeof(char16_t));
	*lpnSize = size;

	return TRUE;
}
<commit_msg>Map getlogin_r()'s ERANGE to ERROR_GEN_FAILURE<commit_after>//! @file getusername.cpp
//! @author Andrew Schwartzmeyer <andschwa@microsoft.com>
//! @brief Implements GetUserName Win32 API

#include <errno.h>
#include <langinfo.h>
#include <locale.h>
#include <unistd.h>
#include <string>
#include <unicode/utypes.h>
#include <unicode/ucnv.h>
#include <unicode/ustring.h>
#include <unicode/uchar.h>
#include "getusername.h"

//! @brief GetUserName retrieves the name of the user associated with
//! the current thread.
//!
//! GetUserNameW is the Unicode variation. See [MSDN documentation].
//!
//! @param[out] lpBuffer
//! @parblock
//! A pointer to the buffer to receive the user's
//! logon name. If this buffer is not large enough to contain the
//! entire user name, the function fails.
//!
//! WCHAR_T* is a Unicode [LPTSTR].
//! @endparblock
//!
//! @param[in, out] lpnSize
//! @parblock
//! On input, this variable specifies the size of the lpBuffer buffer,
//! in TCHARs. On output, the variable receives the number of TCHARs
//! copied to the buffer, including the terminating null character.
//!
//! TCHAR is a Unicode 16-bit [WCHAR].
//!
//! If lpBuffer is too small, the function fails and GetLastError
//! returns ERROR_INSUFFICIENT_BUFFER. This parameter receives the
//! required buffer size, including the terminating null character.
//! @endparblock
//!
//! @exception errno Passes these errors via errno to GetLastError:
//! - ERROR_INVALID_PARAMETER: parameter is not valid
//! - ERROR_BAD_ENVIRONMENT: locale is not UTF-8
//! - ERROR_TOO_MANY_OPEN_FILES: already have the maximum allowed number of open files
//! - ERROR_NO_ASSOCIATION: calling process has no controlling terminal
//! - ERROR_INSUFFICIENT_BUFFER: buffer not large enough to hold username string
//! - ERROR_NO_SUCH_USER: there was no corresponding entry in the utmp-file
//! - ERROR_OUTOFMEMORY: insufficient memory to allocate passwd structure
//! - ERROR_NO_ASSOCIATION: standard input didn't refer to a terminal
//! - ERROR_INVALID_FUNCTION: getlogin_r() returned an unrecognized error code
//!
//! @retval 1 If the function succeeds, the return value is a nonzero
//! value, and the variable pointed to by lpnSize contains the number
//! of TCHARs copied to the buffer specified by lpBuffer, including
//! the terminating null character.
//!
//! @retval 0 If the function fails, the return value is zero. To get
//! extended error information, call GetLastError.
//!
//! [MSDN documentation]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724432(v=vs.85).aspx
//! [WCHAR]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx#WCHAR
//! [LPTSTR]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx#LPTSTR
BOOL GetUserNameW(WCHAR_T* lpBuffer, LPDWORD lpnSize)
{
	const std::string utf8 = "UTF-8";

	errno = FALSE;

	// Check parameters
	if (!lpBuffer || !lpnSize) {
		errno = ERROR_INVALID_PARAMETER;
		return 0;
	}

	// Select locale from environment
	setlocale(LC_ALL, "");
	// Check that locale is UTF-8
	if (nl_langinfo(CODESET) != utf8) {
		errno = ERROR_BAD_ENVIRONMENT;
		return FALSE;
	}

	// Get username from system in a thread-safe manner
	std::string username(LOGIN_NAME_MAX, '\0');
	int ret = getlogin_r(&username[0], username.size());
	// Map errno to Win32 Error Codes
	if (ret) {
		switch (errno) {
		case EMFILE:
		case ENFILE:
			errno = ERROR_TOO_MANY_OPEN_FILES;
			break;
		case ENXIO:
			errno = ERROR_NO_ASSOCIATION;
			break;
		case ERANGE:
			errno = ERROR_GEN_FAILURE;
			break;
		case ENOENT:
			errno = ERROR_NO_SUCH_USER;
			break;
		case ENOMEM:
			errno = ERROR_OUTOFMEMORY;
			break;
		case ENOTTY:
			errno = ERROR_NO_ASSOCIATION;
			break;
		default:
			errno = ERROR_INVALID_FUNCTION;
		}
		return FALSE;
	}

	// Convert to char* to WCHAR_T* (UTF-8 to UTF-16 LE w/o BOM)
	std::basic_string<char16_t> username16(LOGIN_NAME_MAX+1, 0);
	icu::UnicodeString username8(username.c_str(), "UTF-8");
	int32_t targetSize = username8.extract(0, username8.length(),
	                                       reinterpret_cast<char*>(&username16[0]),
	                                       (username16.size()-1)*sizeof(char16_t),
	                                       "UTF-16LE");
	// Number of characters including null
	username16.resize(targetSize/sizeof(char16_t)+1);

	// Size in WCHARs including null
	const DWORD size = username16.length();
	if (size > *lpnSize) {
		errno = ERROR_INSUFFICIENT_BUFFER;
		// Set lpnSize if buffer is too small to inform user
		// of necessary size
		*lpnSize = size;
		return 0;
	}

	// Copy bytes from string to buffer
	memcpy(lpBuffer, &username16[0], size*sizeof(char16_t));
	*lpnSize = size;

	return TRUE;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: tbx_ww.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-18 15:18:22 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SD_TBX_WW_HXX
#define _SD_TBX_WW_HXX

#ifndef _SDRESID_HXX
#include <sdresid.hxx>
#endif

#ifndef _SFXTBXCTRL_HXX //autogen
#include <sfx2/tbxctrl.hxx>
#endif

//------------------------------------------------------------------------

/*
class SdPopupWindowTbx : public SfxPopupWindow
{
private:
    SfxToolBoxManager   aTbx;
    SdResId             aSdResIdWin;
    SdResId             aSdResIdTbx;
    WindowAlign         eTbxAlign;
    Link                aSelectLink;

    DECL_LINK( TbxSelectHdl, ToolBox * );

public:
    SdPopupWindowTbx( USHORT nId, WindowAlign eAlign,
                      SdResId aRIdWin, SdResId aRIdTbx, SfxBindings& rBindings );
    ~SdPopupWindowTbx();

    virtual SfxPopupWindow* Clone() const;

    virtual void PopupModeEnd();

    void         StartSelection() { aTbx.GetToolBox().StartSelection(); }
    void         Update();

private:

    // Adapt the toolbox to whether CTL is active or not.  If CTL is not
    //    active then all toolbox items that describe CTL specific shapes are
    //    deleted from it and its size is re-calculated.
    void AdaptToCTL (void);
};
*/
//------------------------------------------------------------------------

class SdTbxControl : public SfxToolBoxControl
{
private:
    BOOL    IsCheckable( USHORT nSId );

public:
            SFX_DECL_TOOLBOX_CONTROL();

            SdTbxControl(USHORT nSlotId, USHORT nId, ToolBox& rTbx );
            ~SdTbxControl() {}

    virtual SfxPopupWindowType  GetPopupWindowType() const;
    virtual SfxPopupWindow*     CreatePopupWindow();
    virtual void StateChanged( USHORT nSId, SfxItemState eState,
                                const SfxPoolItem* pState );
};

#endif      // _SD_TBX_WW_HXX

<commit_msg>INTEGRATION: CWS ooo19126 (1.5.236); FILE MERGED 2005/09/05 13:23:29 rt 1.5.236.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: tbx_ww.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 05:55:36 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SD_TBX_WW_HXX
#define _SD_TBX_WW_HXX

#ifndef _SDRESID_HXX
#include <sdresid.hxx>
#endif

#ifndef _SFXTBXCTRL_HXX //autogen
#include <sfx2/tbxctrl.hxx>
#endif

//------------------------------------------------------------------------

/*
class SdPopupWindowTbx : public SfxPopupWindow
{
private:
    SfxToolBoxManager   aTbx;
    SdResId             aSdResIdWin;
    SdResId             aSdResIdTbx;
    WindowAlign         eTbxAlign;
    Link                aSelectLink;

    DECL_LINK( TbxSelectHdl, ToolBox * );

public:
    SdPopupWindowTbx( USHORT nId, WindowAlign eAlign,
                      SdResId aRIdWin, SdResId aRIdTbx, SfxBindings& rBindings );
    ~SdPopupWindowTbx();

    virtual SfxPopupWindow* Clone() const;

    virtual void PopupModeEnd();

    void         StartSelection() { aTbx.GetToolBox().StartSelection(); }
    void         Update();

private:

    // Adapt the toolbox to whether CTL is active or not.  If CTL is not
    //    active then all toolbox items that describe CTL specific shapes are
    //    deleted from it and its size is re-calculated.
    void AdaptToCTL (void);
};
*/
//------------------------------------------------------------------------

class SdTbxControl : public SfxToolBoxControl
{
private:
    BOOL    IsCheckable( USHORT nSId );

public:
            SFX_DECL_TOOLBOX_CONTROL();

            SdTbxControl(USHORT nSlotId, USHORT nId, ToolBox& rTbx );
            ~SdTbxControl() {}

    virtual SfxPopupWindowType  GetPopupWindowType() const;
    virtual SfxPopupWindow*     CreatePopupWindow();
    virtual void StateChanged( USHORT nSId, SfxItemState eState,
                                const SfxPoolItem* pState );
};

#endif      // _SD_TBX_WW_HXX

<|endoftext|>