<commit_before>/*
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include <utility>
#include <vector>
#include "util/interrupt.h"
#include "kernel/metavar.h"
#include "kernel/free_vars.h"
#include "kernel/justification.h"
#include "kernel/instantiate.h"
#include "kernel/find_fn.h"
#include "kernel/expr_maps.h"
#include "kernel/level.h"
#include "kernel/cache_stack.h"
#include "kernel/expr_cache.h"

#ifndef LEAN_INSTANTIATE_METAVARS_CACHE_CAPACITY
#define LEAN_INSTANTIATE_METAVARS_CACHE_CAPACITY 1024*8
#endif

namespace lean {
substitution::substitution() {}

bool substitution::is_expr_assigned(name const & m) const {
    return m_expr_subst.contains(m);
}

auto substitution::get_expr_assignment(name const & m) const -> opt_expr_jst {
    auto it = m_expr_subst.find(m);
    if (it)
        return opt_expr_jst(mk_pair(*it, get_expr_jst(m)));
    else
        return opt_expr_jst();
}

bool substitution::is_level_assigned(name const & m) const {
    return m_level_subst.contains(m);
}

auto substitution::get_level_assignment(name const & m) const -> opt_level_jst {
    auto it = m_level_subst.find(m);
    if (it)
        return opt_level_jst(mk_pair(*it, get_level_jst(m)));
    else
        return opt_level_jst();
}

optional<expr> substitution::get_expr(name const & m) const {
    auto it = m_expr_subst.find(m);
    return it ? some_expr(*it) : none_expr();
}

optional<level> substitution::get_level(name const & m) const {
    auto it = m_level_subst.find(m);
    return it ? some_level(*it) : none_level();
}

void substitution::assign(name const & m, expr const & t, justification const & j) {
    lean_assert(closed(t));
    m_expr_subst.insert(m, t);
    m_occs_map.erase(m);
    if (!j.is_none())
        m_expr_jsts.insert(m, j);
}

void substitution::assign(name const & m, level const & l, justification const & j) {
    m_level_subst.insert(m, l);
    if (!j.is_none())
        m_level_jsts.insert(m, j);
}

pair<level, justification> substitution::instantiate_metavars(level const & l, bool use_jst) {
    if (!has_meta(l))
        return mk_pair(l, justification());
    justification j;
    auto save_jst = [&](justification const & j2) { j = mk_composite1(j, j2); };
    level r = replace(l, [&](level const & l) {
            if (!has_meta(l)) {
                return some_level(l);
            } else if (is_meta(l)) {
                auto p1 = get_assignment(l);
                if (p1) {
                    auto p2 = instantiate_metavars(p1->first, use_jst);
                    if (use_jst) {
                        justification new_jst = mk_composite1(p1->second, p2.second);
                        assign(meta_id(l), p2.first, new_jst);
                        save_jst(new_jst);
                    } else {
                        assign(meta_id(l), p2.first);
                    }
                    return some_level(p2.first);
                }
            }
            return none_level();
        });
    return mk_pair(r, j);
}

typedef expr_cache instantiate_metavars_cache;
MK_CACHE_STACK(instantiate_metavars_cache, LEAN_INSTANTIATE_METAVARS_CACHE_CAPACITY)

class instantiate_metavars_fn {
protected:
    typedef instantiate_metavars_cache_ref cache_ref;
    substitution & m_subst;
    cache_ref      m_cache;
    justification  m_jst;
    bool           m_use_jst;
    // if m_inst_local_types, then instantiate metavariables nested in the types of local constants and metavariables.
    bool           m_inst_local_types;

    void save_jst(justification const & j) { m_jst = mk_composite1(m_jst, j); }

    level visit_level(level const & l) {
        auto p1 = m_subst.instantiate_metavars(l, m_use_jst);
        if (m_use_jst)
            save_jst(p1.second);
        return p1.first;
    }

    levels visit_levels(levels const & ls) {
        return map_reuse(ls,
                         [&](level const & l) { return visit_level(l); },
                         [](level const & l1, level const & l2) { return is_eqp(l1, l2); });
    }

    expr visit_sort(expr const & s) {
        return update_sort(s, visit_level(sort_level(s)));
    }

    expr visit_constant(expr const & c) {
        return update_constant(c, visit_levels(const_levels(c)));
    }

    expr visit_meta(expr const & m) {
        name const & m_name = mlocal_name(m);
        auto p1 = m_subst.get_expr_assignment(m_name);
        if (p1) {
            if (!has_metavar(p1->first)) {
                if (m_use_jst)
                    save_jst(p1->second);
                return p1->first;
            } else if (m_use_jst) {
                auto p2 = m_subst.instantiate_metavars(p1->first);
                justification new_jst = mk_composite1(p1->second, p2.second);
                m_subst.assign(m_name, p2.first, new_jst);
                save_jst(new_jst);
                return p2.first;
            } else {
                auto p2 = m_subst.instantiate_metavars(p1->first);
                m_subst.assign(m_name, p2.first, mk_composite1(p1->second, p2.second));
                return p2.first;
            }
        } else {
            if (m_inst_local_types)
                return update_mlocal(m, visit(mlocal_type(m)));
            else
                return m;
        }
    }

    expr visit_app(expr const & e) {
        buffer<expr> args;
        expr const & f = get_app_rev_args(e, args);
        if (is_metavar(f)) {
            if (auto p1 = m_subst.get_expr_assignment(mlocal_name(f))) {
                if (m_use_jst)
                    save_jst(p1->second);
                expr new_app = apply_beta(p1->first, args.size(), args.data());
                return visit(new_app);
            }
        }
        expr new_f = visit(f);
        buffer<expr> new_args;
        bool modified = !is_eqp(new_f, f);
        for (expr const & arg : args) {
            expr new_arg = visit(arg);
            if (!is_eqp(arg, new_arg))
                modified = true;
            new_args.push_back(new_arg);
        }
        if (!modified)
            return e;
        else
            return mk_rev_app(new_f, new_args);
    }

    expr save_result(expr const & e, expr && r) {
        m_cache->insert(e, r);
        return r;
    }

    expr visit_macro(expr const & e) {
        lean_assert(is_macro(e));
        buffer<expr> new_args;
        for (unsigned i = 0; i < macro_num_args(e); i++)
            new_args.push_back(visit(macro_arg(e, i)));
        return update_macro(e, new_args.size(), new_args.data());
    }

    expr visit_binding(expr const & e) {
        lean_assert(is_binding(e));
        expr new_d = visit(binding_domain(e));
        expr new_b = visit(binding_body(e));
        return update_binding(e, new_d, new_b);
    }

    expr visit(expr const & e) {
        if (!has_metavar(e))
            return e;
        check_system("instantiate metavars");

        if (auto it = m_cache->find(e))
            return *it;

        switch (e.kind()) {
        case expr_kind::Sort:      return save_result(e, visit_sort(e));
        case expr_kind::Var:       lean_unreachable();
        case expr_kind::Local:
            if (m_inst_local_types)
                return save_result(e, update_mlocal(e, visit(mlocal_type(e))));
            else
                return e;
        case expr_kind::Constant:  return save_result(e, visit_constant(e));
        case expr_kind::Macro:     return save_result(e, visit_macro(e));
        case expr_kind::Meta:      return save_result(e, visit_meta(e));
        case expr_kind::App:       return save_result(e, visit_app(e));
        case expr_kind::Lambda:
        case expr_kind::Pi:        return save_result(e, visit_binding(e));
        }
        lean_unreachable();
    }

public:
    instantiate_metavars_fn(substitution & s, bool use_jst, bool inst_local_types):
        m_subst(s), m_use_jst(use_jst), m_inst_local_types(inst_local_types) {}
    justification const & get_justification() const { return m_jst; }
    expr operator()(expr const & e) { return visit(e); }
};

pair<expr, justification> substitution::instantiate_metavars_core(expr const & e, bool inst_local_types) {
    if (!has_metavar(e)) {
        return mk_pair(e, justification());
    } else {
        instantiate_metavars_fn fn(*this, true, inst_local_types);
        expr r = fn(e);
        return mk_pair(r, fn.get_justification());
    }
}

expr substitution::instantiate_metavars_wo_jst(expr const & e, bool inst_local_types) {
    return instantiate_metavars_fn(*this, false, inst_local_types)(e);
}

static name_set merge(name_set s1, name_set const & s2) {
    s2.for_each([&](name const & n) { s1.insert(n); });
    return s1;
}

static bool all_unassigned(substitution const & subst, name_set const & s) {
    return !s.find_if([&](name const & m) { return subst.is_expr_assigned(m); });
}

name_set substitution::get_occs(name const & m, name_set & fresh) {
    lean_assert(is_expr_assigned(m));
    check_system("substitution occurs check");
    if (fresh.contains(m)) {
        return *m_occs_map.find(m);
    } else if (name_set const * it = m_occs_map.find(m)) {
        name_set curr_occs = *it;
        if (all_unassigned(*this, curr_occs)) {
            return curr_occs;
        }
        name_set new_occs;
        curr_occs.for_each([&](name const & n) {
                if (is_expr_assigned(n)) {
                    new_occs = merge(new_occs, get_occs(n, fresh));
                } else {
                    // we need to update
                    new_occs.insert(n);
                }
            });
        m_occs_map.insert(m, new_occs);
        fresh.insert(m);
        return new_occs;
    } else {
        expr e = *get_expr(m);
        name_set occs;
        ::lean::for_each(e, [&](expr const & e, unsigned) {
                if (!has_expr_metavar(e)) return false;
                if (is_local(e)) return false; // do not process type
                if (is_metavar(e)) {
                    name const & n = mlocal_name(e);
                    if (is_expr_assigned(n)) {
                        occs = merge(occs, get_occs(n, fresh));
                    } else {
                        occs.insert(n);
                    }
                    return false;
                }
                return true;
            });
        m_occs_map.insert(m, occs);
        fresh.insert(m);
        return occs;
    }
}

bool substitution::occurs_expr(name const & m, expr const & e) {
    if (!has_expr_metavar(e))
        return false;
    name_set fresh;
    bool found = false;
    for_each(e, [&](expr const & e, unsigned) {
            if (found || !has_expr_metavar(e)) return false;
            if (is_metavar(e)) {
                name const & n = mlocal_name(e);
                if (is_expr_assigned(n)) {
                    if (get_occs(n, fresh).contains(m))
                        found = true;
                } else if (n == m) {
                    found = true;
                }
                return false; // do not visit type
            }
            if (is_local(e)) return false; // do not visit type
            return true;
        });
    return found;
}
}
<commit_msg>fix(kernel/metavar): improve error messages by propagating the tag when we execute instantiate_all<commit_after>/*
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include <utility>
#include <vector>
#include "util/interrupt.h"
#include "kernel/metavar.h"
#include "kernel/free_vars.h"
#include "kernel/justification.h"
#include "kernel/instantiate.h"
#include "kernel/find_fn.h"
#include "kernel/expr_maps.h"
#include "kernel/level.h"
#include "kernel/cache_stack.h"
#include "kernel/expr_cache.h"

#ifndef LEAN_INSTANTIATE_METAVARS_CACHE_CAPACITY
#define LEAN_INSTANTIATE_METAVARS_CACHE_CAPACITY 1024*8
#endif

namespace lean {
substitution::substitution() {}

bool substitution::is_expr_assigned(name const & m) const {
    return m_expr_subst.contains(m);
}

auto substitution::get_expr_assignment(name const & m) const -> opt_expr_jst {
    auto it = m_expr_subst.find(m);
    if (it)
        return opt_expr_jst(mk_pair(*it, get_expr_jst(m)));
    else
        return opt_expr_jst();
}

bool substitution::is_level_assigned(name const & m) const {
    return m_level_subst.contains(m);
}

auto substitution::get_level_assignment(name const & m) const -> opt_level_jst {
    auto it = m_level_subst.find(m);
    if (it)
        return opt_level_jst(mk_pair(*it, get_level_jst(m)));
    else
        return opt_level_jst();
}

optional<expr> substitution::get_expr(name const & m) const {
    auto it = m_expr_subst.find(m);
    return it ? some_expr(*it) : none_expr();
}

optional<level> substitution::get_level(name const & m) const {
    auto it = m_level_subst.find(m);
    return it ? some_level(*it) : none_level();
}

void substitution::assign(name const & m, expr const & t, justification const & j) {
    lean_assert(closed(t));
    m_expr_subst.insert(m, t);
    m_occs_map.erase(m);
    if (!j.is_none())
        m_expr_jsts.insert(m, j);
}

void substitution::assign(name const & m, level const & l, justification const & j) {
    m_level_subst.insert(m, l);
    if (!j.is_none())
        m_level_jsts.insert(m, j);
}

pair<level, justification> substitution::instantiate_metavars(level const & l, bool use_jst) {
    if (!has_meta(l))
        return mk_pair(l, justification());
    justification j;
    auto save_jst = [&](justification const & j2) { j = mk_composite1(j, j2); };
    level r = replace(l, [&](level const & l) {
            if (!has_meta(l)) {
                return some_level(l);
            } else if (is_meta(l)) {
                auto p1 = get_assignment(l);
                if (p1) {
                    auto p2 = instantiate_metavars(p1->first, use_jst);
                    if (use_jst) {
                        justification new_jst = mk_composite1(p1->second, p2.second);
                        assign(meta_id(l), p2.first, new_jst);
                        save_jst(new_jst);
                    } else {
                        assign(meta_id(l), p2.first);
                    }
                    return some_level(p2.first);
                }
            }
            return none_level();
        });
    return mk_pair(r, j);
}

typedef expr_cache instantiate_metavars_cache;
MK_CACHE_STACK(instantiate_metavars_cache, LEAN_INSTANTIATE_METAVARS_CACHE_CAPACITY)

class instantiate_metavars_fn {
protected:
    typedef instantiate_metavars_cache_ref cache_ref;
    substitution & m_subst;
    cache_ref      m_cache;
    justification  m_jst;
    bool           m_use_jst;
    // if m_inst_local_types, then instantiate metavariables nested in the types of local constants and metavariables.
    bool           m_inst_local_types;

    void save_jst(justification const & j) { m_jst = mk_composite1(m_jst, j); }

    level visit_level(level const & l) {
        auto p1 = m_subst.instantiate_metavars(l, m_use_jst);
        if (m_use_jst)
            save_jst(p1.second);
        return p1.first;
    }

    levels visit_levels(levels const & ls) {
        return map_reuse(ls,
                         [&](level const & l) { return visit_level(l); },
                         [](level const & l1, level const & l2) { return is_eqp(l1, l2); });
    }

    expr visit_sort(expr const & s) {
        return update_sort(s, visit_level(sort_level(s)));
    }

    expr visit_constant(expr const & c) {
        return update_constant(c, visit_levels(const_levels(c)));
    }

    expr visit_meta(expr const & m) {
        name const & m_name = mlocal_name(m);
        auto p1 = m_subst.get_expr_assignment(m_name);
        if (p1) {
            if (!has_metavar(p1->first)) {
                if (m_use_jst)
                    save_jst(p1->second);
                return p1->first;
            } else if (m_use_jst) {
                auto p2 = m_subst.instantiate_metavars(p1->first);
                justification new_jst = mk_composite1(p1->second, p2.second);
                m_subst.assign(m_name, p2.first, new_jst);
                save_jst(new_jst);
                return p2.first;
            } else {
                auto p2 = m_subst.instantiate_metavars(p1->first);
                m_subst.assign(m_name, p2.first, mk_composite1(p1->second, p2.second));
                return p2.first;
            }
        } else {
            if (m_inst_local_types)
                return update_mlocal(m, visit(mlocal_type(m)));
            else
                return m;
        }
    }

    expr visit_app(expr const & e) {
        buffer<expr> args;
        expr const & f = get_app_rev_args(e, args);
        if (is_metavar(f)) {
            if (auto p1 = m_subst.get_expr_assignment(mlocal_name(f))) {
                if (m_use_jst)
                    save_jst(p1->second);
                expr new_app = apply_beta(p1->first, args.size(), args.data());
                return visit(new_app);
            }
        }
        expr new_f = visit(f);
        buffer<expr> new_args;
        bool modified = !is_eqp(new_f, f);
        for (expr const & arg : args) {
            expr new_arg = visit(arg);
            if (!is_eqp(arg, new_arg))
                modified = true;
            new_args.push_back(new_arg);
        }
        if (!modified)
            return e;
        else
            return mk_rev_app(new_f, new_args, e.get_tag());
    }

    expr save_result(expr const & e, expr && r) {
        m_cache->insert(e, r);
        return r;
    }

    expr visit_macro(expr const & e) {
        lean_assert(is_macro(e));
        buffer<expr> new_args;
        for (unsigned i = 0; i < macro_num_args(e); i++)
            new_args.push_back(visit(macro_arg(e, i)));
        return update_macro(e, new_args.size(), new_args.data());
    }

    expr visit_binding(expr const & e) {
        lean_assert(is_binding(e));
        expr new_d = visit(binding_domain(e));
        expr new_b = visit(binding_body(e));
        return update_binding(e, new_d, new_b);
    }

    expr visit(expr const & e) {
        if (!has_metavar(e))
            return e;
        check_system("instantiate metavars");

        if (auto it = m_cache->find(e))
            return *it;

        switch (e.kind()) {
        case expr_kind::Sort:      return save_result(e, visit_sort(e));
        case expr_kind::Var:       lean_unreachable();
        case expr_kind::Local:
            if (m_inst_local_types)
                return save_result(e, update_mlocal(e, visit(mlocal_type(e))));
            else
                return e;
        case expr_kind::Constant:  return save_result(e, visit_constant(e));
        case expr_kind::Macro:     return save_result(e, visit_macro(e));
        case expr_kind::Meta:      return save_result(e, visit_meta(e));
        case expr_kind::App:       return save_result(e, visit_app(e));
        case expr_kind::Lambda:
        case expr_kind::Pi:        return save_result(e, visit_binding(e));
        }
        lean_unreachable();
    }

public:
    instantiate_metavars_fn(substitution & s, bool use_jst, bool inst_local_types):
        m_subst(s), m_use_jst(use_jst), m_inst_local_types(inst_local_types) {}
    justification const & get_justification() const { return m_jst; }
    expr operator()(expr const & e) { return visit(e); }
};

pair<expr, justification> substitution::instantiate_metavars_core(expr const & e, bool inst_local_types) {
    if (!has_metavar(e)) {
        return mk_pair(e, justification());
    } else {
        instantiate_metavars_fn fn(*this, true, inst_local_types);
        expr r = fn(e);
        return mk_pair(r, fn.get_justification());
    }
}

expr substitution::instantiate_metavars_wo_jst(expr const & e, bool inst_local_types) {
    return instantiate_metavars_fn(*this, false, inst_local_types)(e);
}

static name_set merge(name_set s1, name_set const & s2) {
    s2.for_each([&](name const & n) { s1.insert(n); });
    return s1;
}

static bool all_unassigned(substitution const & subst, name_set const & s) {
    return !s.find_if([&](name const & m) { return subst.is_expr_assigned(m); });
}

name_set substitution::get_occs(name const & m, name_set & fresh) {
    lean_assert(is_expr_assigned(m));
    check_system("substitution occurs check");
    if (fresh.contains(m)) {
        return *m_occs_map.find(m);
    } else if (name_set const * it = m_occs_map.find(m)) {
        name_set curr_occs = *it;
        if (all_unassigned(*this, curr_occs)) {
            return curr_occs;
        }
        name_set new_occs;
        curr_occs.for_each([&](name const & n) {
                if (is_expr_assigned(n)) {
                    new_occs = merge(new_occs, get_occs(n, fresh));
                } else {
                    // we need to update
                    new_occs.insert(n);
                }
            });
        m_occs_map.insert(m, new_occs);
        fresh.insert(m);
        return new_occs;
    } else {
        expr e = *get_expr(m);
        name_set occs;
        ::lean::for_each(e, [&](expr const & e, unsigned) {
                if (!has_expr_metavar(e)) return false;
                if (is_local(e)) return false; // do not process type
                if (is_metavar(e)) {
                    name const & n = mlocal_name(e);
                    if (is_expr_assigned(n)) {
                        occs = merge(occs, get_occs(n, fresh));
                    } else {
                        occs.insert(n);
                    }
                    return false;
                }
                return true;
            });
        m_occs_map.insert(m, occs);
        fresh.insert(m);
        return occs;
    }
}

bool substitution::occurs_expr(name const & m, expr const & e) {
    if (!has_expr_metavar(e))
        return false;
    name_set fresh;
    bool found = false;
    for_each(e, [&](expr const & e, unsigned) {
            if (found || !has_expr_metavar(e)) return false;
            if (is_metavar(e)) {
                name const & n = mlocal_name(e);
                if (is_expr_assigned(n)) {
                    if (get_occs(n, fresh).contains(m))
                        found = true;
                } else if (n == m) {
                    found = true;
                }
                return false; // do not visit type
            }
            if (is_local(e)) return false; // do not visit type
            return true;
        });
    return found;
}
}
<|endoftext|>


<commit_before>#include "kraken_headers.hpp"
#include "krakendb.hpp"
#include "quickfile.hpp"

#include <sys/stat.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#include <stdarg.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

// #define TEST_TAXA

using namespace std;
using namespace kraken;

static const char * INDEX = "database.idx";
static const char * DB = "database.kdb";
static const uint64_t NT_MASK = uint64_t(3) << 62;

char* kmerInterpreter(uint64_t kmer, uint8_t k) {
	char* res = new char[k];
	kmer <<= (sizeof(kmer) * 8) - (k * 2);
	for(int i=0; i<k; i++) {
		switch ((kmer & NT_MASK) >> 62) {
			case 0:
				res[i] = 'A';
				break;
			case 1:
				res[i] = 'C';
				break;
			case 2:
				res[i] = 'G';
				break;
			case 3:
				res[i] = 'T';
				break;
		}
		kmer <<= 2;
	}
	return res;
}

void test_taxa(KrakenDB db, uint64_t kmer, uint32_t taxid,
				uint64_t val_len, ofstream err_file)
{
	uint64_t last_bin_key = 0;
	int64_t min_pos = 1;
	int64_t max_pos = 0;
	uint32_t taxid_e = 0;
	uint32_t* kmer_pos = db.kmer_query(kmer,&last_bin_key,
							&min_pos,&max_pos,true);
	memcpy(&taxid_e, kmer_pos, val_len);
	err_file << "exp:\t" << taxid_e << endl;
	err_file << "act:\t" << taxid << endl;
}

int main() {

	#ifdef TEST_TAXA
	ofstream err_file;
	err_file.open("trans_kra.log");
	#endif

	QuickFile idx_file(INDEX);
	KrakenDBIndex idx(idx_file.ptr());
	idx_file.load_file();

	QuickFile db_file(DB);
	KrakenDB db(db_file.ptr());
	db.set_index(&idx);
	db_file.load_file();

	// Return pointer to start of pairs
	char* pairs = db.get_pair_ptr();
	// how many bits are in each key?
    uint64_t key_bits = db.get_key_bits();
    // how many bytes does each key occupy?
    uint64_t key_len = db.get_key_len();
    // how many bytes does each value occupy?
    uint64_t val_len = db.get_val_len();
    // how many key/value pairs are there?
    uint64_t key_ct = db.get_key_ct();
    // how many bytes does each pair occupy?
    uint64_t pair_size = db.pair_size();

    uint64_t* offsets = idx.get_array();
	uint64_t nt = idx.indexed_nt();
	uint64_t n_bins = (1ull << (2 * nt)) + 1;
	uint64_t bin_len = 64*key_ct/n_bins;

	uint64_t mask = (1ull << key_bits) -1;

	char* bin = (char*) malloc(bin_len*pair_size);
	uint64_t* kmers = (uint64_t*) calloc(bin_len, sizeof(uint64_t));
	uint32_t* taxa = (uint32_t*) calloc(bin_len, sizeof(uint32_t));
	uint64_t* temp_kmers;
	uint32_t* temp_taxa;
	uint64_t start = 0, stop = 0, len = 0;

	uint64_t kmer_id = 1;

	for(uint64_t* temp_offsets = offsets+1;
			temp_offsets < offsets+300; temp_offsets++)
	{

		temp_kmers = kmers;
		temp_taxa = taxa;

		start = stop;
		stop = *temp_offsets;
		len = stop - start;

		if (start < stop) {

			if (len > bin_len) {
				bin_len = 2*len;
				bin = (char*) realloc(bin, bin_len*pair_size);
				kmers = (uint64_t*) realloc(kmers, bin_len*sizeof(uint64_t));
				taxa = (uint32_t*) realloc(taxa, bin_len*sizeof(uint32_t));
				temp_kmers = kmers;
				temp_taxa = taxa;
			}

			memcpy(bin, pairs + (start * pair_size), len * pair_size);

			for(char* next_pair = bin;
				next_pair < bin + (len*pair_size);
				next_pair += pair_size)
			{

				memcpy(temp_kmers, next_pair, key_len);
				memcpy(temp_taxa, next_pair+key_len, val_len);
				*temp_kmers &= mask;

				#ifdef TEST_TAXA
				test_taxa(db, *temp_kmers, *temp_taxa, val_len, err_file);
				#endif

				temp_kmers++;
				temp_taxa++;
			}

			for(temp_kmers = kmers, temp_taxa = taxa;
				temp_kmers < kmers + len;
				temp_kmers++, temp_taxa++)
			{
				cout << ">kmer|" << kmer_id++ << "|taxid|" << *temp_taxa << endl;
				cout << kmerInterpreter(*temp_kmers, key_bits/2) << endl << endl;
			}
		}
	}

	free(bin);
	free(kmers);
	free(taxa);

	return 0;
}
<commit_msg>Typo<commit_after>#include "kraken_headers.hpp"
#include "krakendb.hpp"
#include "quickfile.hpp"

#include <sys/stat.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#include <stdarg.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

// #define TEST_TAXA

using namespace std;
using namespace kraken;

static const char * INDEX = "database.idx";
static const char * DB = "database.kdb";
static const uint64_t NT_MASK = uint64_t(3) << 62;

char* kmerInterpreter(uint64_t kmer, uint8_t k) {
	char* res = new char[k];
	kmer <<= (sizeof(kmer) * 8) - (k * 2);
	for(int i=0; i<k; i++) {
		switch ((kmer & NT_MASK) >> 62) {
			case 0:
				res[i] = 'A';
				break;
			case 1:
				res[i] = 'C';
				break;
			case 2:
				res[i] = 'G';
				break;
			case 3:
				res[i] = 'T';
				break;
		}
		kmer <<= 2;
	}
	return res;
}

void test_taxa(KrakenDB db, uint64_t kmer, uint32_t taxid,
				uint64_t val_len, ofstream err_file)
{
	uint64_t last_bin_key = 0;
	int64_t min_pos = 1;
	int64_t max_pos = 0;
	uint32_t taxid_e = 0;
	uint32_t* kmer_pos = db.kmer_query(kmer,&last_bin_key,
							&min_pos,&max_pos,true);
	memcpy(&taxid_e, kmer_pos, val_len);
	err_file << "exp:\t" << taxid_e << endl;
	err_file << "act:\t" << taxid << endl;
}

int main() {

	#ifdef TEST_TAXA
	ofstream err_file;
	err_file.open("trans_kra.log");
	#endif

	QuickFile idx_file(INDEX);
	KrakenDBIndex idx(idx_file.ptr());
	idx_file.load_file();

	QuickFile db_file(DB);
	KrakenDB db(db_file.ptr());
	db.set_index(&idx);
	db_file.load_file();

	// Return pointer to start of pairs
	char* pairs = db.get_pair_ptr();
	// how many bits are in each key?
    uint64_t key_bits = db.get_key_bits();
    // how many bytes does each key occupy?
    uint64_t key_len = db.get_key_len();
    // how many bytes does each value occupy?
    uint64_t val_len = db.get_val_len();
    // how many key/value pairs are there?
    uint64_t key_ct = db.get_key_ct();
    // how many bytes does each pair occupy?
    uint64_t pair_size = db.pair_size();

    uint64_t* offsets = idx.get_array();
	uint64_t nt = idx.indexed_nt();
	uint64_t n_bins = (1ull << (2 * nt)) + 1;
	uint64_t bin_len = 64*key_ct/n_bins;

	uint64_t mask = (1ull << key_bits) -1;

	char* bin = (char*) malloc(bin_len*pair_size);
	uint64_t* kmers = (uint64_t*) calloc(bin_len, sizeof(uint64_t));
	uint32_t* taxa = (uint32_t*) calloc(bin_len, sizeof(uint32_t));
	uint64_t* temp_kmers;
	uint32_t* temp_taxa;
	uint64_t start = 0, stop = 0, len = 0;

	uint64_t kmer_id = 1;

	for(uint64_t* temp_offsets = offsets+1;
			temp_offsets < n_bins; temp_offsets++)
	{

		temp_kmers = kmers;
		temp_taxa = taxa;

		start = stop;
		stop = *temp_offsets;
		len = stop - start;

		if (start < stop) {

			if (len > bin_len) {
				bin_len = 2*len;
				bin = (char*) realloc(bin, bin_len*pair_size);
				kmers = (uint64_t*) realloc(kmers, bin_len*sizeof(uint64_t));
				taxa = (uint32_t*) realloc(taxa, bin_len*sizeof(uint32_t));
				temp_kmers = kmers;
				temp_taxa = taxa;
			}

			memcpy(bin, pairs + (start * pair_size), len * pair_size);

			for(char* next_pair = bin;
				next_pair < bin + (len*pair_size);
				next_pair += pair_size)
			{

				memcpy(temp_kmers, next_pair, key_len);
				memcpy(temp_taxa, next_pair+key_len, val_len);
				*temp_kmers &= mask;

				#ifdef TEST_TAXA
				test_taxa(db, *temp_kmers, *temp_taxa, val_len, err_file);
				#endif

				temp_kmers++;
				temp_taxa++;
			}

			for(temp_kmers = kmers, temp_taxa = taxa;
				temp_kmers < kmers + len;
				temp_kmers++, temp_taxa++)
			{
				cout << ">kmer|" << kmer_id++ << "|taxid|" << *temp_taxa << endl;
				cout << kmerInterpreter(*temp_kmers, key_bits/2) << endl << endl;
			}
		}
	}

	free(bin);
	free(kmers);
	free(taxa);

	return 0;
}
<|endoftext|>


<commit_before>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>"
// Copyright 2007      Inge Wallin  <ingwa@kde.org>"
//

#include "Quaternion.h"

#include <cmath>

#include <QtCore/QString>
#include <QtCore/QDebug>

#define quatNorm (v[Q_W] * v[Q_W] + v[Q_X] * v[Q_X] + v[Q_Y] * v[Q_Y] + v[Q_Z] * v[Q_Z])

Quaternion::Quaternion()
{
//    like in libeigen we keep the quaternion uninitialized
//    set( 1.0, 0.0, 0.0, 0.0 );
}

Quaternion::Quaternion(double w, double x, double y, double z)
{
    set( w, x, y, z );
}

Quaternion::Quaternion(double alpha, double beta)
{
    v[Q_W] = 0.0;

    const double  cosBeta = cos(beta);
    v[Q_X] = -cosBeta * sin(alpha);
    v[Q_Y] = -sin(beta);
    v[Q_Z] = cosBeta * cos(alpha);
}

void Quaternion::normalize()
{
    scalar( 1.0 / sqrt(quatNorm) );
}

void Quaternion::scalar(double mult)
{
    v[Q_W] *= mult;
    v[Q_X] *= mult;
    v[Q_Y] *= mult;
    v[Q_Z] *= mult;
}

Quaternion Quaternion::inverse() const
{
    Quaternion  inverse( v[Q_W], -v[Q_X], -v[Q_Y], -v[Q_Z] );
    inverse.normalize();

    return inverse;
}

void Quaternion::createFromEuler(double pitch, double yaw, double roll)
{
    double cX, cY, cZ, sX, sY, sZ, cYcZ, sYsZ, sYcZ, cYsZ;

    pitch *= 0.5;
    yaw   *= 0.5;
    roll  *= 0.5;

    cX = cos(pitch);
    cY = cos(yaw);
    cZ = cos(roll);

    sX = sin(pitch);
    sY = sin(yaw);
    sZ = sin(roll);

    cYcZ = cY * cZ;
    sYsZ = sY * sZ;
    sYcZ = sY * cZ;
    cYsZ = cY * sZ;

    v[Q_W] = cX * cYcZ + sX * sYsZ;
    v[Q_X] = sX * cYcZ - cX * sYsZ;
    v[Q_Y] = cX * sYcZ + sX * cYsZ;
    v[Q_Z] = cX * cYsZ - sX * sYcZ;
}

double Quaternion::pitch() const
{
    return atan2(2.0*(v[Q_W]*v[Q_X]+v[Q_Y]*v[Q_Z]),(1-2*(v[Q_X]*v[Q_X]+v[Q_Y]*v[Q_Y])));
//    return atan(2.0*(v[Q_W]*v[Q_X]+v[Q_Y]*v[Q_Z])/(1-2*(v[Q_X]*v[Q_X]+v[Q_Y]*v[Q_Y])));
}

double Quaternion::yaw() const
{
    return asin(2.0*(v[Q_W]*v[Q_Y]-v[Q_Z]*v[Q_X]));
}

double Quaternion::roll() const
{
    return atan2(2.0*(v[Q_W]*v[Q_Z]+v[Q_X]*v[Q_Y]),(1-2*(v[Q_Y]*v[Q_Y]+v[Q_Z]*v[Q_Z])));
//    return atan(2.0*(v[Q_W]*v[Q_Z]+v[Q_X]*v[Q_Y])/(1-2*(v[Q_Y]*v[Q_Y]+v[Q_Z]*v[Q_Z])));
}

void Quaternion::display() const
{
    QString quatdisplay = QString("Quaternion: w= %1, x= %2, y= %3, z= %4, |q|= %5" )
        .arg(v[Q_W]).arg(v[Q_X]).arg(v[Q_Y]).arg(v[Q_Z]).arg(quatNorm);

    qDebug() << quatdisplay;
}

void Quaternion::operator*=(const Quaternion &q)
{
    double x, y, z, w;

    w = v[Q_W] * q.v[Q_W] - v[Q_X] * q.v[Q_X] - v[Q_Y] * q.v[Q_Y] - v[Q_Z] * q.v[Q_Z];
    x = v[Q_W] * q.v[Q_X] + v[Q_X] * q.v[Q_W] + v[Q_Y] * q.v[Q_Z] - v[Q_Z] * q.v[Q_Y];
    y = v[Q_W] * q.v[Q_Y] - v[Q_X] * q.v[Q_Z] + v[Q_Y] * q.v[Q_W] + v[Q_Z] * q.v[Q_X];
    z = v[Q_W] * q.v[Q_Z] + v[Q_X] * q.v[Q_Y] - v[Q_Y] * q.v[Q_X] + v[Q_Z] * q.v[Q_W];

    set( w, x, y, z );
}

bool Quaternion::operator==(const Quaternion &q) const
{

    return ( v[Q_W] == q.v[Q_W]
         && v[Q_X] == q.v[Q_X]
         && v[Q_Y] == q.v[Q_Y]
         && v[Q_Z] == q.v[Q_Z] );
}

Quaternion Quaternion::operator*(const Quaternion &q) const
{
    double  w, x, y, z;

    w = v[Q_W] * q.v[Q_W] - v[Q_X] * q.v[Q_X] - v[Q_Y] * q.v[Q_Y] - v[Q_Z] * q.v[Q_Z];
    x = v[Q_W] * q.v[Q_X] + v[Q_X] * q.v[Q_W] + v[Q_Y] * q.v[Q_Z] - v[Q_Z] * q.v[Q_Y];
    y = v[Q_W] * q.v[Q_Y] - v[Q_X] * q.v[Q_Z] + v[Q_Y] * q.v[Q_W] + v[Q_Z] * q.v[Q_X];
    z = v[Q_W] * q.v[Q_Z] + v[Q_X] * q.v[Q_Y] - v[Q_Y] * q.v[Q_X] + v[Q_Z] * q.v[Q_W];
    return Quaternion( w, x, y, z );
}

void Quaternion::rotateAroundAxis(const Quaternion &q)
{
    double w, x, y, z;

    w = + v[Q_X] * q.v[Q_X] + v[Q_Y] * q.v[Q_Y] + v[Q_Z] * q.v[Q_Z];
    x = + v[Q_X] * q.v[Q_W] - v[Q_Y] * q.v[Q_Z] + v[Q_Z] * q.v[Q_Y];
    y = + v[Q_X] * q.v[Q_Z] + v[Q_Y] * q.v[Q_W] - v[Q_Z] * q.v[Q_X];
    z = - v[Q_X] * q.v[Q_Y] + v[Q_Y] * q.v[Q_X] + v[Q_Z] * q.v[Q_W];

    v[Q_W] = q.v[Q_W] * w - q.v[Q_X] * x - q.v[Q_Y] * y - q.v[Q_Z] * z;
    v[Q_X] = q.v[Q_W] * x + q.v[Q_X] * w + q.v[Q_Y] * z - q.v[Q_Z] * y;
    v[Q_Y] = q.v[Q_W] * y - q.v[Q_X] * z + q.v[Q_Y] * w + q.v[Q_Z] * x;
    v[Q_Z] = q.v[Q_W] * z + q.v[Q_X] * y - q.v[Q_Y] * x + q.v[Q_Z] * w;
}

void Quaternion::slerp(const Quaternion q1, const Quaternion q2, double t)
{
    double p1, p2;

    double cosAlpha = ( q1.v[Q_X]*q2.v[Q_X] + q1.v[Q_Y]*q2.v[Q_Y]
		       + q1.v[Q_Z]*q2.v[Q_Z] + q1.v[Q_W]*q2.v[Q_W] );
    double alpha    = acos(cosAlpha);
    double sinAlpha = sin(alpha);

    if( sinAlpha > 0.0 ) {
        p1 = sin( (1.0-t)*alpha ) / sinAlpha;
        p2 = sin( t*alpha ) / sinAlpha;
    } else {
        // both Quaternions are equal
        p1 = 1.0;
        p2 = 0.0;
    }

    v[Q_X] = p1*q1.v[Q_X] + p2*q2.v[Q_X];
    v[Q_Y] = p1*q1.v[Q_Y] + p2*q2.v[Q_Y];
    v[Q_Z] = p1*q1.v[Q_Z] + p2*q2.v[Q_Z];
    v[Q_W] = p1*q1.v[Q_W] + p2*q2.v[Q_W];
}

void Quaternion::getSpherical(double &alpha, double &beta) const
{
    double  y = v[Q_Y];
    if ( y > 1.0 )
        y = 1.0;
    else if ( y < -1.0 )
        y = -1.0;

        beta = -asin( y );

    if(v[Q_X] * v[Q_X] + v[Q_Z] * v[Q_Z] > 0.00005)
        alpha = -atan2(v[Q_X], v[Q_Z]);
    else
        alpha = 0.0;
}

void Quaternion::toMatrix(matrix &m) const
{

    double xy = v[Q_X] * v[Q_Y], xz = v[Q_X] * v[Q_Z];
    double yy = v[Q_Y] * v[Q_Y], yw = v[Q_Y] * v[Q_W];
    double zw = v[Q_Z] * v[Q_W], zz = v[Q_Z] * v[Q_Z];

    m[0][0] = 1.0 - 2.0 * (yy + zz);
    m[0][1] = 2.0 * (xy + zw);
    m[0][2] = 2.0 * (xz - yw);
    m[0][3] = 0.0;

    double xx = v[Q_X] * v[Q_X], xw = v[Q_X] * v[Q_W], yz = v[Q_Y] * v[Q_Z];

    m[1][0] = 2.0 * (xy - zw);
    m[1][1] = 1.0 - 2.0 * (xx + zz);
    m[1][2] = 2.0 * (yz + xw);
    m[1][3] = 0.0;

    m[2][0] = 2.0 * (xz + yw);
    m[2][1] = 2.0 * (yz - xw);
    m[2][2] = 1.0 - 2.0 * (xx + yy);
    m[2][3] = 0.0;
}

void Quaternion::rotateAroundAxis(const matrix &m)
{
    double x, y, z;

    x =  m[0][0] * v[Q_X] + m[1][0] * v[Q_Y] + m[2][0] * v[Q_Z];
    y =  m[0][1] * v[Q_X] + m[1][1] * v[Q_Y] + m[2][1] * v[Q_Z];
    z =  m[0][2] * v[Q_X] + m[1][2] * v[Q_Y] + m[2][2] * v[Q_Z];

    v[Q_W] = 1.0; v[Q_X] = x; v[Q_Y] = y; v[Q_Z] = z;
}
<commit_msg>fix wrong indentation mistakenly introduced by tackat<commit_after>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>"
// Copyright 2007      Inge Wallin  <ingwa@kde.org>"
//

#include "Quaternion.h"

#include <cmath>

#include <QtCore/QString>
#include <QtCore/QDebug>

#define quatNorm (v[Q_W] * v[Q_W] + v[Q_X] * v[Q_X] + v[Q_Y] * v[Q_Y] + v[Q_Z] * v[Q_Z])

Quaternion::Quaternion()
{
//    like in libeigen we keep the quaternion uninitialized
//    set( 1.0, 0.0, 0.0, 0.0 );
}

Quaternion::Quaternion(double w, double x, double y, double z)
{
    set( w, x, y, z );
}

Quaternion::Quaternion(double alpha, double beta)
{
    v[Q_W] = 0.0;

    const double  cosBeta = cos(beta);
    v[Q_X] = -cosBeta * sin(alpha);
    v[Q_Y] = -sin(beta);
    v[Q_Z] = cosBeta * cos(alpha);
}

void Quaternion::normalize()
{
    scalar( 1.0 / sqrt(quatNorm) );
}

void Quaternion::scalar(double mult)
{
    v[Q_W] *= mult;
    v[Q_X] *= mult;
    v[Q_Y] *= mult;
    v[Q_Z] *= mult;
}

Quaternion Quaternion::inverse() const
{
    Quaternion  inverse( v[Q_W], -v[Q_X], -v[Q_Y], -v[Q_Z] );
    inverse.normalize();

    return inverse;
}

void Quaternion::createFromEuler(double pitch, double yaw, double roll)
{
    double cX, cY, cZ, sX, sY, sZ, cYcZ, sYsZ, sYcZ, cYsZ;

    pitch *= 0.5;
    yaw   *= 0.5;
    roll  *= 0.5;

    cX = cos(pitch);
    cY = cos(yaw);
    cZ = cos(roll);

    sX = sin(pitch);
    sY = sin(yaw);
    sZ = sin(roll);

    cYcZ = cY * cZ;
    sYsZ = sY * sZ;
    sYcZ = sY * cZ;
    cYsZ = cY * sZ;

    v[Q_W] = cX * cYcZ + sX * sYsZ;
    v[Q_X] = sX * cYcZ - cX * sYsZ;
    v[Q_Y] = cX * sYcZ + sX * cYsZ;
    v[Q_Z] = cX * cYsZ - sX * sYcZ;
}

double Quaternion::pitch() const
{
    return atan2(2.0*(v[Q_W]*v[Q_X]+v[Q_Y]*v[Q_Z]),(1-2*(v[Q_X]*v[Q_X]+v[Q_Y]*v[Q_Y])));
//    return atan(2.0*(v[Q_W]*v[Q_X]+v[Q_Y]*v[Q_Z])/(1-2*(v[Q_X]*v[Q_X]+v[Q_Y]*v[Q_Y])));
}

double Quaternion::yaw() const
{
    return asin(2.0*(v[Q_W]*v[Q_Y]-v[Q_Z]*v[Q_X]));
}

double Quaternion::roll() const
{
    return atan2(2.0*(v[Q_W]*v[Q_Z]+v[Q_X]*v[Q_Y]),(1-2*(v[Q_Y]*v[Q_Y]+v[Q_Z]*v[Q_Z])));
//    return atan(2.0*(v[Q_W]*v[Q_Z]+v[Q_X]*v[Q_Y])/(1-2*(v[Q_Y]*v[Q_Y]+v[Q_Z]*v[Q_Z])));
}

void Quaternion::display() const
{
    QString quatdisplay = QString("Quaternion: w= %1, x= %2, y= %3, z= %4, |q|= %5" )
        .arg(v[Q_W]).arg(v[Q_X]).arg(v[Q_Y]).arg(v[Q_Z]).arg(quatNorm);

    qDebug() << quatdisplay;
}

void Quaternion::operator*=(const Quaternion &q)
{
    double x, y, z, w;

    w = v[Q_W] * q.v[Q_W] - v[Q_X] * q.v[Q_X] - v[Q_Y] * q.v[Q_Y] - v[Q_Z] * q.v[Q_Z];
    x = v[Q_W] * q.v[Q_X] + v[Q_X] * q.v[Q_W] + v[Q_Y] * q.v[Q_Z] - v[Q_Z] * q.v[Q_Y];
    y = v[Q_W] * q.v[Q_Y] - v[Q_X] * q.v[Q_Z] + v[Q_Y] * q.v[Q_W] + v[Q_Z] * q.v[Q_X];
    z = v[Q_W] * q.v[Q_Z] + v[Q_X] * q.v[Q_Y] - v[Q_Y] * q.v[Q_X] + v[Q_Z] * q.v[Q_W];

    set( w, x, y, z );
}

bool Quaternion::operator==(const Quaternion &q) const
{

    return ( v[Q_W] == q.v[Q_W]
         && v[Q_X] == q.v[Q_X]
         && v[Q_Y] == q.v[Q_Y]
         && v[Q_Z] == q.v[Q_Z] );
}

Quaternion Quaternion::operator*(const Quaternion &q) const
{
    double  w, x, y, z;

    w = v[Q_W] * q.v[Q_W] - v[Q_X] * q.v[Q_X] - v[Q_Y] * q.v[Q_Y] - v[Q_Z] * q.v[Q_Z];
    x = v[Q_W] * q.v[Q_X] + v[Q_X] * q.v[Q_W] + v[Q_Y] * q.v[Q_Z] - v[Q_Z] * q.v[Q_Y];
    y = v[Q_W] * q.v[Q_Y] - v[Q_X] * q.v[Q_Z] + v[Q_Y] * q.v[Q_W] + v[Q_Z] * q.v[Q_X];
    z = v[Q_W] * q.v[Q_Z] + v[Q_X] * q.v[Q_Y] - v[Q_Y] * q.v[Q_X] + v[Q_Z] * q.v[Q_W];
    return Quaternion( w, x, y, z );
}

void Quaternion::rotateAroundAxis(const Quaternion &q)
{
    double w, x, y, z;

    w = + v[Q_X] * q.v[Q_X] + v[Q_Y] * q.v[Q_Y] + v[Q_Z] * q.v[Q_Z];
    x = + v[Q_X] * q.v[Q_W] - v[Q_Y] * q.v[Q_Z] + v[Q_Z] * q.v[Q_Y];
    y = + v[Q_X] * q.v[Q_Z] + v[Q_Y] * q.v[Q_W] - v[Q_Z] * q.v[Q_X];
    z = - v[Q_X] * q.v[Q_Y] + v[Q_Y] * q.v[Q_X] + v[Q_Z] * q.v[Q_W];

    v[Q_W] = q.v[Q_W] * w - q.v[Q_X] * x - q.v[Q_Y] * y - q.v[Q_Z] * z;
    v[Q_X] = q.v[Q_W] * x + q.v[Q_X] * w + q.v[Q_Y] * z - q.v[Q_Z] * y;
    v[Q_Y] = q.v[Q_W] * y - q.v[Q_X] * z + q.v[Q_Y] * w + q.v[Q_Z] * x;
    v[Q_Z] = q.v[Q_W] * z + q.v[Q_X] * y - q.v[Q_Y] * x + q.v[Q_Z] * w;
}

void Quaternion::slerp(const Quaternion q1, const Quaternion q2, double t)
{
    double p1, p2;

    double cosAlpha = ( q1.v[Q_X]*q2.v[Q_X] + q1.v[Q_Y]*q2.v[Q_Y]
		       + q1.v[Q_Z]*q2.v[Q_Z] + q1.v[Q_W]*q2.v[Q_W] );
    double alpha    = acos(cosAlpha);
    double sinAlpha = sin(alpha);

    if( sinAlpha > 0.0 ) {
        p1 = sin( (1.0-t)*alpha ) / sinAlpha;
        p2 = sin( t*alpha ) / sinAlpha;
    } else {
        // both Quaternions are equal
        p1 = 1.0;
        p2 = 0.0;
    }

    v[Q_X] = p1*q1.v[Q_X] + p2*q2.v[Q_X];
    v[Q_Y] = p1*q1.v[Q_Y] + p2*q2.v[Q_Y];
    v[Q_Z] = p1*q1.v[Q_Z] + p2*q2.v[Q_Z];
    v[Q_W] = p1*q1.v[Q_W] + p2*q2.v[Q_W];
}

void Quaternion::getSpherical(double &alpha, double &beta) const
{
    double  y = v[Q_Y];
    if ( y > 1.0 )
        y = 1.0;
    else if ( y < -1.0 )
        y = -1.0;

    beta = -asin( y );

    if(v[Q_X] * v[Q_X] + v[Q_Z] * v[Q_Z] > 0.00005)
        alpha = -atan2(v[Q_X], v[Q_Z]);
    else
        alpha = 0.0;
}

void Quaternion::toMatrix(matrix &m) const
{

    double xy = v[Q_X] * v[Q_Y], xz = v[Q_X] * v[Q_Z];
    double yy = v[Q_Y] * v[Q_Y], yw = v[Q_Y] * v[Q_W];
    double zw = v[Q_Z] * v[Q_W], zz = v[Q_Z] * v[Q_Z];

    m[0][0] = 1.0 - 2.0 * (yy + zz);
    m[0][1] = 2.0 * (xy + zw);
    m[0][2] = 2.0 * (xz - yw);
    m[0][3] = 0.0;

    double xx = v[Q_X] * v[Q_X], xw = v[Q_X] * v[Q_W], yz = v[Q_Y] * v[Q_Z];

    m[1][0] = 2.0 * (xy - zw);
    m[1][1] = 1.0 - 2.0 * (xx + zz);
    m[1][2] = 2.0 * (yz + xw);
    m[1][3] = 0.0;

    m[2][0] = 2.0 * (xz + yw);
    m[2][1] = 2.0 * (yz - xw);
    m[2][2] = 1.0 - 2.0 * (xx + yy);
    m[2][3] = 0.0;
}

void Quaternion::rotateAroundAxis(const matrix &m)
{
    double x, y, z;

    x =  m[0][0] * v[Q_X] + m[1][0] * v[Q_Y] + m[2][0] * v[Q_Z];
    y =  m[0][1] * v[Q_X] + m[1][1] * v[Q_Y] + m[2][1] * v[Q_Z];
    z =  m[0][2] * v[Q_X] + m[1][2] * v[Q_Y] + m[2][2] * v[Q_Z];

    v[Q_W] = 1.0; v[Q_X] = x; v[Q_Y] = y; v[Q_Z] = z;
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libkeynote project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <cassert>

#include "KNCollectorBase.h"
#include "KNDictionary.h"
#include "KNText.h"

namespace libkeynote
{

KNCollectorBase::KNCollectorBase(KNDictionary &dict)
  : m_dict(dict)
  , m_objectsStack()
  , m_currentGeometry()
  , m_currentText()
  , m_collecting(false)
  , m_layerOpened(false)
  , m_groupLevel(0)
{
}

KNCollectorBase::~KNCollectorBase()
{
  assert(!m_collecting);
  assert(m_objectsStack.empty());
}

void KNCollectorBase::collectCharacterStyle(const ID_t &id, const KNStylePtr_t &style)
{
  if (m_collecting)
    m_dict.characterStyles[id] = style;
}

void KNCollectorBase::collectGraphicStyle(const ID_t &id, const KNStylePtr_t &style)
{
  if (m_collecting)
    m_dict.graphicStyles[id] = style;
}

void KNCollectorBase::collectHeadlineStyle(const ID_t &id, const KNStylePtr_t &style)
{
  if (m_collecting)
    m_dict.headlineStyles[id] = style;
}

void KNCollectorBase::collectLayoutStyle(const ID_t &id, const KNStylePtr_t &style)
{
  if (m_collecting)
    m_dict.layoutStyles[id] = style;
}

void KNCollectorBase::collectParagraphStyle(const ID_t &id, const KNStylePtr_t &style)
{
  if (m_collecting)
    m_dict.paragraphStyles[id] = style;
}

void KNCollectorBase::collectGeometry(const ID_t &, const KNGeometryPtr_t &geometry)
{
  if (m_collecting)
    m_currentGeometry = geometry;
}

void KNCollectorBase::collectGroup(const ID_t &, const KNGroupPtr_t &group)
{
  if (m_collecting)
  {
    assert(!m_objectsStack.empty());

    group->objects = m_objectsStack.top();
    m_objectsStack.pop();
    assert(!m_objectsStack.empty());
    m_objectsStack.top().push_back(makeObject(group));
  }
}

void KNCollectorBase::collectImage(const ID_t &id, const KNImagePtr_t &image)
{
  if (m_collecting)
  {
    assert(!m_objectsStack.empty());

    image->geometry = m_currentGeometry;
    m_currentGeometry.reset();
    m_dict.images[id] = image;
    m_objectsStack.top().push_back(makeObject(image));
  }
}

void KNCollectorBase::collectLine(const ID_t &, const KNLinePtr_t &line)
{
  if (m_collecting)
  {
    assert(!m_objectsStack.empty());

    line->geometry = m_currentGeometry;
    m_currentGeometry.reset();
    m_objectsStack.top().push_back(makeObject(line));
  }
}

void KNCollectorBase::collectMedia(const ID_t &, const KNMediaPtr_t &media)
{
  if (m_collecting)
  {
    assert(!m_objectsStack.empty());

    media->geometry = m_currentGeometry;
    m_currentGeometry.reset();
    m_objectsStack.top().push_back(makeObject(media));
  }
}

void KNCollectorBase::collectPath(const ID_t &, const KNPathPtr_t &path)
{
  if (m_collecting)
  {
    assert(!m_objectsStack.empty());

    path->setGeometry(m_currentGeometry);
    m_currentGeometry.reset();
    m_objectsStack.top().push_back(makeObject(path));
  }
}

void KNCollectorBase::collectLayer(const ID_t &, bool)
{
  if (m_collecting)
  {
    assert(m_layerOpened);
    assert(!m_objectsStack.empty());

    m_currentLayer.reset(new KNLayer());
    m_currentLayer->objects = m_objectsStack.top();
    m_objectsStack.pop();
  }
}

void KNCollectorBase::collectText(const std::string &text, const ID_t &style)
{
  if (m_collecting)
  {
    assert(bool(m_currentText));

    m_currentText->insertText(text, m_dict.characterStyles[style]);
  }
}

void KNCollectorBase::collectTab()
{
  if (m_collecting)
  {
    assert(bool(m_currentText));

    m_currentText->insertTab();
  }
}

void KNCollectorBase::collectLineBreak()
{
  if (m_collecting)
  {
    assert(bool(m_currentText));

    m_currentText->insertLineBreak();
  }
}

void KNCollectorBase::collectSlideText(const ID_t &id, const bool title)
{
  if (m_collecting)
  {
    assert(!m_objectsStack.empty());

    KNTextBodyPtr_t textBody(new KNTextBody(title));
    textBody->geometry = m_currentGeometry;
    textBody->text = m_currentText;
    if (title)
      m_dict.titlePlaceholders[id] = textBody;
    else
      m_dict.bodyPlaceholders[id] = textBody;
    m_objectsStack.top().push_back(makeObject(textBody));

    m_currentGeometry.reset();
    m_currentText.reset();
  }
}

void KNCollectorBase::startLayer()
{
  if (m_collecting)
  {
    assert(!m_layerOpened);
    assert(m_objectsStack.empty());
    assert(!m_currentLayer);

    m_objectsStack.push(KNObjectList_t());
    m_layerOpened = true;

    assert(!m_objectsStack.empty());
  }
}

void KNCollectorBase::endLayer()
{
  if (m_collecting)
  {
    assert(m_layerOpened);
    // object stack is already cleared by collectLayer()
    assert(m_objectsStack.empty());

    m_currentLayer.reset();
    m_layerOpened = false;

    assert(m_objectsStack.empty());
  }
}

void KNCollectorBase::startGroup()
{
  if (m_collecting)
  {
    assert(m_layerOpened);
    assert(!m_objectsStack.empty());

    m_objectsStack.push(KNObjectList_t());
    ++m_groupLevel;
  }
}

void KNCollectorBase::endGroup()
{
  if (m_collecting)
  {
    assert(m_layerOpened);
    assert(!m_objectsStack.empty());
    assert(m_groupLevel > 0);

    --m_groupLevel;
    // stack is popped in collectGroup already
  }
}

void KNCollectorBase::startParagraph(const ID_t &style)
{
  if (m_collecting)
  {
    assert(bool(m_currentText));

    m_currentText->openParagraph(m_dict.paragraphStyles[style]);
  }
}

void KNCollectorBase::endParagraph()
{
  if (m_collecting)
  {
    assert(bool(m_currentText));

    m_currentText->closeParagraph();
  }
}

void KNCollectorBase::startTextLayout(const ID_t &style)
{
  if (m_collecting)
  {
    assert(!m_currentText);

    m_currentText.reset(new KNText());
    const KNStylePtr_t layoutStyle = m_dict.layoutStyles[style];
    m_currentText->setLayoutStyle(layoutStyle);
  }
}

void KNCollectorBase::endTextLayout()
{
  if (m_collecting)
  {
    assert(bool(m_currentText));

    m_currentText.reset();
  }
}

bool KNCollectorBase::getCollecting() const
{
  return m_collecting;
}

void KNCollectorBase::setCollecting(bool collecting)
{
  m_collecting = collecting;
}

const KNLayerPtr_t &KNCollectorBase::getLayer() const
{
  return m_currentLayer;
}

} // namespace libkeynote

/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
<commit_msg>do not process text placeholders for now<commit_after>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libkeynote project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <cassert>

#include "KNCollectorBase.h"
#include "KNDictionary.h"
#include "KNText.h"

namespace libkeynote
{

KNCollectorBase::KNCollectorBase(KNDictionary &dict)
  : m_dict(dict)
  , m_objectsStack()
  , m_currentGeometry()
  , m_currentText()
  , m_collecting(false)
  , m_layerOpened(false)
  , m_groupLevel(0)
{
}

KNCollectorBase::~KNCollectorBase()
{
  assert(!m_collecting);
  assert(m_objectsStack.empty());
}

void KNCollectorBase::collectCharacterStyle(const ID_t &id, const KNStylePtr_t &style)
{
  if (m_collecting)
    m_dict.characterStyles[id] = style;
}

void KNCollectorBase::collectGraphicStyle(const ID_t &id, const KNStylePtr_t &style)
{
  if (m_collecting)
    m_dict.graphicStyles[id] = style;
}

void KNCollectorBase::collectHeadlineStyle(const ID_t &id, const KNStylePtr_t &style)
{
  if (m_collecting)
    m_dict.headlineStyles[id] = style;
}

void KNCollectorBase::collectLayoutStyle(const ID_t &id, const KNStylePtr_t &style)
{
  if (m_collecting)
    m_dict.layoutStyles[id] = style;
}

void KNCollectorBase::collectParagraphStyle(const ID_t &id, const KNStylePtr_t &style)
{
  if (m_collecting)
    m_dict.paragraphStyles[id] = style;
}

void KNCollectorBase::collectGeometry(const ID_t &, const KNGeometryPtr_t &geometry)
{
  if (m_collecting)
    m_currentGeometry = geometry;
}

void KNCollectorBase::collectGroup(const ID_t &, const KNGroupPtr_t &group)
{
  if (m_collecting)
  {
    assert(!m_objectsStack.empty());

    group->objects = m_objectsStack.top();
    m_objectsStack.pop();
    assert(!m_objectsStack.empty());
    m_objectsStack.top().push_back(makeObject(group));
  }
}

void KNCollectorBase::collectImage(const ID_t &id, const KNImagePtr_t &image)
{
  if (m_collecting)
  {
    assert(!m_objectsStack.empty());

    image->geometry = m_currentGeometry;
    m_currentGeometry.reset();
    m_dict.images[id] = image;
    m_objectsStack.top().push_back(makeObject(image));
  }
}

void KNCollectorBase::collectLine(const ID_t &, const KNLinePtr_t &line)
{
  if (m_collecting)
  {
    assert(!m_objectsStack.empty());

    line->geometry = m_currentGeometry;
    m_currentGeometry.reset();
    m_objectsStack.top().push_back(makeObject(line));
  }
}

void KNCollectorBase::collectMedia(const ID_t &, const KNMediaPtr_t &media)
{
  if (m_collecting)
  {
    assert(!m_objectsStack.empty());

    media->geometry = m_currentGeometry;
    m_currentGeometry.reset();
    m_objectsStack.top().push_back(makeObject(media));
  }
}

void KNCollectorBase::collectPath(const ID_t &, const KNPathPtr_t &path)
{
  if (m_collecting)
  {
    assert(!m_objectsStack.empty());

    path->setGeometry(m_currentGeometry);
    m_currentGeometry.reset();
    m_objectsStack.top().push_back(makeObject(path));
  }
}

void KNCollectorBase::collectLayer(const ID_t &, bool)
{
  if (m_collecting)
  {
    assert(m_layerOpened);
    assert(!m_objectsStack.empty());

    m_currentLayer.reset(new KNLayer());
    m_currentLayer->objects = m_objectsStack.top();
    m_objectsStack.pop();
  }
}

void KNCollectorBase::collectText(const std::string &text, const ID_t &style)
{
  if (m_collecting)
  {
    assert(bool(m_currentText));

    m_currentText->insertText(text, m_dict.characterStyles[style]);
  }
}

void KNCollectorBase::collectTab()
{
  if (m_collecting)
  {
    assert(bool(m_currentText));

    m_currentText->insertTab();
  }
}

void KNCollectorBase::collectLineBreak()
{
  if (m_collecting)
  {
    assert(bool(m_currentText));

    m_currentText->insertLineBreak();
  }
}

void KNCollectorBase::collectSlideText(const ID_t &id, const bool title)
{
  if (m_collecting)
  {
    // assert(!m_objectsStack.empty());

    KNTextBodyPtr_t textBody(new KNTextBody(title));
    textBody->geometry = m_currentGeometry;
    textBody->text = m_currentText;
    if (title)
      m_dict.titlePlaceholders[id] = textBody;
    else
      m_dict.bodyPlaceholders[id] = textBody;
    // m_objectsStack.top().push_back(makeObject(textBody));

    m_currentGeometry.reset();
    m_currentText.reset();
  }
}

void KNCollectorBase::startLayer()
{
  if (m_collecting)
  {
    assert(!m_layerOpened);
    assert(m_objectsStack.empty());
    assert(!m_currentLayer);

    m_objectsStack.push(KNObjectList_t());
    m_layerOpened = true;

    assert(!m_objectsStack.empty());
  }
}

void KNCollectorBase::endLayer()
{
  if (m_collecting)
  {
    assert(m_layerOpened);
    // object stack is already cleared by collectLayer()
    assert(m_objectsStack.empty());

    m_currentLayer.reset();
    m_layerOpened = false;

    assert(m_objectsStack.empty());
  }
}

void KNCollectorBase::startGroup()
{
  if (m_collecting)
  {
    assert(m_layerOpened);
    assert(!m_objectsStack.empty());

    m_objectsStack.push(KNObjectList_t());
    ++m_groupLevel;
  }
}

void KNCollectorBase::endGroup()
{
  if (m_collecting)
  {
    assert(m_layerOpened);
    assert(!m_objectsStack.empty());
    assert(m_groupLevel > 0);

    --m_groupLevel;
    // stack is popped in collectGroup already
  }
}

void KNCollectorBase::startParagraph(const ID_t &style)
{
  if (m_collecting)
  {
    assert(bool(m_currentText));

    m_currentText->openParagraph(m_dict.paragraphStyles[style]);
  }
}

void KNCollectorBase::endParagraph()
{
  if (m_collecting)
  {
    assert(bool(m_currentText));

    m_currentText->closeParagraph();
  }
}

void KNCollectorBase::startTextLayout(const ID_t &style)
{
  if (m_collecting)
  {
    assert(!m_currentText);

    m_currentText.reset(new KNText());
    const KNStylePtr_t layoutStyle = m_dict.layoutStyles[style];
    m_currentText->setLayoutStyle(layoutStyle);
  }
}

void KNCollectorBase::endTextLayout()
{
  if (m_collecting)
  {
    assert(bool(m_currentText));

    m_currentText.reset();
  }
}

bool KNCollectorBase::getCollecting() const
{
  return m_collecting;
}

void KNCollectorBase::setCollecting(bool collecting)
{
  m_collecting = collecting;
}

const KNLayerPtr_t &KNCollectorBase::getLayer() const
{
  return m_currentLayer;
}

} // namespace libkeynote

/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
<|endoftext|>


<commit_before>/*
*
* Copyright 2013 Telefonica Investigacion y Desarrollo, S.A.U
*
* This file is part of Orion Context Broker.
*
* Orion Context Broker is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Orion Context Broker 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 Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
*
* For those usages not covered by this license please contact with
* fermin at tid dot es
*
* Author: Fermin Galan
*/
#include <semaphore.h>
#include <errno.h>

#include "logMsg/logMsg.h"
#include "logMsg/traceLevels.h"

#include "common/sem.h"

/* ****************************************************************************
*
* Globals -
*/
static sem_t reqSem;
static sem_t mongoSem;

/* ****************************************************************************
*
* semInit -
*
*   parameter #1: 0 - the semaphore is to be shared between threads,
*   parameter #2: 1 - initially the semaphore is free
*
* RETURN VALUE (of sem_init)
*   0 on success,
*  -1 on failure
*
*/
int semInit(int shared, int takenInitially)
{
  if (sem_init(&reqSem, shared, takenInitially) == -1)
    LM_RE(1, ("Error initializing 'req' semaphore: %s\n", strerror(errno)));
  if (sem_init(&mongoSem, shared, takenInitially) == -1)
    LM_RE(2, ("Error initializing 'mongo' semaphore: %s\n", strerror(errno)));

  LM_T(LmtReqSem,   ("Initialized 'req' semaphore"));
  LM_T(LmtMongoSem, ("Initialized 'mongo' semaphore"));

  return 0;
}

/* ****************************************************************************
*
* reqSemTake -
*/
int reqSemTake(const char* who, const char* what)
{
  int x;

  LM_T(LmtReqSem, ("%s taking the 'req' semaphore for '%s'", who, what));
  x = sem_wait(&reqSem);
  LM_T(LmtReqSem, ("%s has the 'req' semaphore", who));

  return x;
}

/* ****************************************************************************
*
* mongoSemTake -
*/
int mongoSemTake(const char* who, const char* what)
{
  int x;

  LM_T(LmtMongoSem, ("%s taking the 'mongo' semaphore for '%s'", who, what));
  x = sem_wait(&mongoSem);
  LM_T(LmtMongoSem, ("%s has the 'mongo' semaphore", who));

  return x;
}

/* ****************************************************************************
*
* reqSemGive -
*/
int reqSemGive(const char* who, const char* what)
{
  if (what != NULL)
    LM_T(LmtReqSem, ("%s gives the 'req' semaphore for '%s'", who, what));
  else
    LM_T(LmtReqSem, ("%s gives the 'req' semaphore", who));

  return sem_post(&reqSem);
}

/* ****************************************************************************
*
* mongoSemGive -
*/
int mongoSemGive(const char* who, const char* what)
{
  if (what != NULL)
    LM_T(LmtMongoSem, ("%s gives the 'mongo' semaphore for '%s'", who, what));
  else
    LM_T(LmtMongoSem, ("%s gives the 'mongo' semaphore", who));

  return sem_post(&mongoSem);
}
<commit_msg>x -> r in sem.cpp<commit_after>/*
*
* Copyright 2013 Telefonica Investigacion y Desarrollo, S.A.U
*
* This file is part of Orion Context Broker.
*
* Orion Context Broker is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Orion Context Broker 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 Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
*
* For those usages not covered by this license please contact with
* fermin at tid dot es
*
* Author: Fermin Galan
*/
#include <semaphore.h>
#include <errno.h>

#include "logMsg/logMsg.h"
#include "logMsg/traceLevels.h"

#include "common/sem.h"

/* ****************************************************************************
*
* Globals -
*/
static sem_t reqSem;
static sem_t mongoSem;

/* ****************************************************************************
*
* semInit -
*
*   parameter #1: 0 - the semaphore is to be shared between threads,
*   parameter #2: 1 - initially the semaphore is free
*
* RETURN VALUE (of sem_init)
*   0 on success,
*  -1 on failure
*
*/
int semInit(int shared, int takenInitially)
{
  if (sem_init(&reqSem, shared, takenInitially) == -1)
    LM_RE(1, ("Error initializing 'req' semaphore: %s\n", strerror(errno)));
  if (sem_init(&mongoSem, shared, takenInitially) == -1)
    LM_RE(2, ("Error initializing 'mongo' semaphore: %s\n", strerror(errno)));

  LM_T(LmtReqSem,   ("Initialized 'req' semaphore"));
  LM_T(LmtMongoSem, ("Initialized 'mongo' semaphore"));

  return 0;
}

/* ****************************************************************************
*
* reqSemTake -
*/
int reqSemTake(const char* who, const char* what)
{
  int r;

  LM_T(LmtReqSem, ("%s taking the 'req' semaphore for '%s'", who, what));
  r = sem_wait(&reqSem);
  LM_T(LmtReqSem, ("%s has the 'req' semaphore", who));

  return r;
}

/* ****************************************************************************
*
* mongoSemTake -
*/
int mongoSemTake(const char* who, const char* what)
{
  int r;

  LM_T(LmtMongoSem, ("%s taking the 'mongo' semaphore for '%s'", who, what));
  r = sem_wait(&mongoSem);
  LM_T(LmtMongoSem, ("%s has the 'mongo' semaphore", who));

  return r;
}

/* ****************************************************************************
*
* reqSemGive -
*/
int reqSemGive(const char* who, const char* what)
{
  if (what != NULL)
    LM_T(LmtReqSem, ("%s gives the 'req' semaphore for '%s'", who, what));
  else
    LM_T(LmtReqSem, ("%s gives the 'req' semaphore", who));

  return sem_post(&reqSem);
}

/* ****************************************************************************
*
* mongoSemGive -
*/
int mongoSemGive(const char* who, const char* what)
{
  if (what != NULL)
    LM_T(LmtMongoSem, ("%s gives the 'mongo' semaphore for '%s'", who, what));
  else
    LM_T(LmtMongoSem, ("%s gives the 'mongo' semaphore", who));

  return sem_post(&mongoSem);
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// Surface.cpp: Implements the egl::Surface class, representing a drawing surface
// such as the client area of a window, including any back buffers.
// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.

#include <tchar.h>
#include <algorithm>

#include "libEGL/Surface.h"

#include "common/debug.h"
#include "libGLESv2/Texture.h"
#include "libGLESv2/renderer/SwapChain.h"
#include "libGLESv2/main.h"

#include "libEGL/main.h"
#include "libEGL/Display.h"

#if defined(ANGLE_PLATFORM_WINRT)
#include "common/winrtutils.h"
#include <wrl/client.h>
#include <wrl\implements.h>
#include <wrl\module.h>
#include <wrl\event.h>
#include <wrl\wrappers\corewrappers.h>
#include <windows.applicationmodel.core.h>

using namespace ABI::Windows::UI::Core;
#endif // #if defined(ANGLE_PLATFORM_WINRT)

namespace egl
{

Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint postSubBufferSupported)
    : mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
{
    mRenderer = mDisplay->getRenderer();
    mSwapChain = NULL;
    mShareHandle = NULL;
    mTexture = NULL;
    mTextureFormat = EGL_NO_TEXTURE;
    mTextureTarget = EGL_NO_TEXTURE;

    mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
    mRenderBuffer = EGL_BACK_BUFFER;
    mSwapBehavior = EGL_BUFFER_PRESERVED;
    mSwapInterval = -1;
    mWidth = -1;
    mHeight = -1;
    setSwapInterval(1);

    subclassWindow();
}

Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType)
    : mDisplay(display), mWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE)
{
    mRenderer = mDisplay->getRenderer();
    mSwapChain = NULL;
    mWindowSubclassed = false;
    mTexture = NULL;
    mTextureFormat = textureFormat;
    mTextureTarget = textureType;

    mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
    mRenderBuffer = EGL_BACK_BUFFER;
    mSwapBehavior = EGL_BUFFER_PRESERVED;
    mSwapInterval = -1;
    setSwapInterval(1);
}

Surface::~Surface()
{
    unsubclassWindow();
    release();
}

bool Surface::initialize()
{
    if (!resetSwapChain())
      return false;

    return true;
}

void Surface::release()
{
    delete mSwapChain;
    mSwapChain = NULL;

    if (mTexture)
    {
        mTexture->releaseTexImage();
        mTexture = NULL;
    }
}

bool Surface::resetSwapChain()
{
    ASSERT(!mSwapChain);

    int width;
    int height;

    if (mWindow)
    {
#if defined(ANGLE_PLATFORM_WINRT)
        winrt::getCurrentWindowDimensions(width, height);
#else
        RECT windowRect;
        if (!GetClientRect(getWindowHandle(), &windowRect))
        {
            ASSERT(false);

            ERR("Could not retrieve the window dimensions");
            return error(EGL_BAD_SURFACE, false);
        }

        width = windowRect.right - windowRect.left;
        height = windowRect.bottom - windowRect.top;
#endif // #if defined(ANGLE_PLATFORM_WINRT)
    }
    else
    {
        // non-window surface - size is determined at creation
        width = mWidth;
        height = mHeight;
    }

    mSwapChain = mRenderer->createSwapChain(mWindow, mShareHandle,
                                            mConfig->mRenderTargetFormat,
                                            mConfig->mDepthStencilFormat);
    if (!mSwapChain)
    {
        return error(EGL_BAD_ALLOC, false);
    }

    if (!resetSwapChain(width, height))
    {
        delete mSwapChain;
        mSwapChain = NULL;
        return false;
    }

    return true;
}

bool Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
{
    ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
    ASSERT(mSwapChain);

    EGLint status = mSwapChain->resize(backbufferWidth, backbufferHeight);

    if (status == EGL_CONTEXT_LOST)
    {
        mDisplay->notifyDeviceLost();
        return false;
    }
    else if (status != EGL_SUCCESS)
    {
        return error(status, false);
    }

    mWidth = backbufferWidth;
    mHeight = backbufferHeight;

    return true;
}

bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
{
    ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
    ASSERT(mSwapChain);

    EGLint status = mSwapChain->reset(backbufferWidth, backbufferHeight, mSwapInterval);

    if (status == EGL_CONTEXT_LOST)
    {
        mRenderer->notifyDeviceLost();
        return false;
    }
    else if (status != EGL_SUCCESS)
    {
        return error(status, false);
    }

    mWidth = backbufferWidth;
    mHeight = backbufferHeight;
    mSwapIntervalDirty = false;

    return true;
}

bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
{
    if (!mSwapChain)
    {
        return true;
    }

    if (x + width > mWidth)
    {
        width = mWidth - x;
    }

    if (y + height > mHeight)
    {
        height = mHeight - y;
    }

    if (width == 0 || height == 0)
    {
        return true;
    }

    EGLint status = mSwapChain->swapRect(x, y, width, height);

    if (status == EGL_CONTEXT_LOST)
    {
        mRenderer->notifyDeviceLost();
        return false;
    }
    else if (status != EGL_SUCCESS)
    {
        return error(status, false);
    }

    checkForOutOfDateSwapChain();

    return true;
}

EGLNativeWindowType Surface::getWindowHandle()
{
    return mWindow;
}

#define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")

#if !defined(ANGLE_PLATFORM_WINRT)
static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
  if (message == WM_SIZE)
  {
      Surface* surf = reinterpret_cast<Surface*>(GetProp(hwnd, kSurfaceProperty));
      if(surf)
      {
          surf->checkForOutOfDateSwapChain();
      }
  }
  WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
  return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
}
#endif // #if !defined(ANGLE_PLATFORM_WINRT)

void Surface::subclassWindow()
{
    if (!mWindow)
    {
        return;
    }

#if !defined(ANGLE_PLATFORM_WINRT)
    DWORD processId;
    DWORD threadId = GetWindowThreadProcessId(mWindow, &processId);
    if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId())
    {
        return;
    }

    SetLastError(0);
    LONG_PTR oldWndProc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
    if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS)
    {
        mWindowSubclassed = false;
        return;
    }

    SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
    SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
#endif // #if !defined(ANGLE_PLATFORM_WINRT)
    mWindowSubclassed = true;
}

void Surface::unsubclassWindow()
{
    if(!mWindowSubclassed)
    {
        return;
    }

#if !defined(ANGLE_PLATFORM_WINRT)

    // un-subclass
    LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(mWindow, kParentWndProc));

    // Check the windowproc is still SurfaceWindowProc.
    // If this assert fails, then it is likely the application has subclassed the
    // hwnd as well and did not unsubclass before destroying its EGL context. The
    // application should be modified to either subclass before initializing the
    // EGL context, or to unsubclass before destroying the EGL context.
    if(parentWndFunc)
    {
        LONG_PTR prevWndFunc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, parentWndFunc);
        ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
    }

    RemoveProp(mWindow, kSurfaceProperty);
    RemoveProp(mWindow, kParentWndProc);
#endif // #if !defined(ANGLE_PLATFORM_WINRT)
    mWindowSubclassed = false;
}

bool Surface::checkForOutOfDateSwapChain()
{
#if defined(ANGLE_PLATFORM_WINRT)
    int clientWidth = 0;
    int clientHeight = 0;
    winrt::getCurrentWindowDimensions(clientWidth,clientHeight);
#else
    RECT client;
    if (!GetClientRect(getWindowHandle(), &client))
    {
        ASSERT(false);
        return false;
    }

    // Grow the buffer now, if the window has grown. We need to grow now to avoid losing information.
    int clientWidth = client.right - client.left;
    int clientHeight = client.bottom - client.top;
#endif // #if defined(ANGLE_PLATFORM_WINRT)
    bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();

    if (mSwapIntervalDirty)
    {
        resetSwapChain(clientWidth, clientHeight);
    }
    else if (sizeDirty)
    {
        resizeSwapChain(clientWidth, clientHeight);
    }

    if (mSwapIntervalDirty || sizeDirty)
    {
        if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
        {
            glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
        }

        return true;
    }

    return false;
}

bool Surface::swap()
{
    return swapRect(0, 0, mWidth, mHeight);
}

bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
{
    if (!mPostSubBufferSupported)
    {
        // Spec is not clear about how this should be handled.
        return true;
    }

    return swapRect(x, y, width, height);
}

EGLint Surface::getWidth() const
{
    return mWidth;
}

EGLint Surface::getHeight() const
{
    return mHeight;
}

EGLint Surface::isPostSubBufferSupported() const
{
    return mPostSubBufferSupported;
}

rx::SwapChain *Surface::getSwapChain() const
{
    return mSwapChain;
}

void Surface::setSwapInterval(EGLint interval)
{
    if (mSwapInterval == interval)
    {
        return;
    }

    mSwapInterval = interval;
    mSwapInterval = std::max(mSwapInterval, mRenderer->getMinSwapInterval());
    mSwapInterval = std::min(mSwapInterval, mRenderer->getMaxSwapInterval());

    mSwapIntervalDirty = true;
}

EGLenum Surface::getTextureFormat() const
{
    return mTextureFormat;
}

EGLenum Surface::getTextureTarget() const
{
    return mTextureTarget;
}

void Surface::setBoundTexture(gl::Texture2D *texture)
{
    mTexture = texture;
}

gl::Texture2D *Surface::getBoundTexture() const
{
    return mTexture;
}

EGLenum Surface::getFormat() const
{
    return mConfig->mRenderTargetFormat;
}
}
<commit_msg>removed unnecessary winrt includes<commit_after>//
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// Surface.cpp: Implements the egl::Surface class, representing a drawing surface
// such as the client area of a window, including any back buffers.
// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.

#include <tchar.h>
#include <algorithm>

#include "libEGL/Surface.h"

#include "common/debug.h"
#include "libGLESv2/Texture.h"
#include "libGLESv2/renderer/SwapChain.h"
#include "libGLESv2/main.h"

#include "libEGL/main.h"
#include "libEGL/Display.h"

#if defined(ANGLE_PLATFORM_WINRT)
#include "common/winrtutils.h"
#endif // #if defined(ANGLE_PLATFORM_WINRT)

namespace egl
{

Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint postSubBufferSupported)
    : mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
{
    mRenderer = mDisplay->getRenderer();
    mSwapChain = NULL;
    mShareHandle = NULL;
    mTexture = NULL;
    mTextureFormat = EGL_NO_TEXTURE;
    mTextureTarget = EGL_NO_TEXTURE;

    mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
    mRenderBuffer = EGL_BACK_BUFFER;
    mSwapBehavior = EGL_BUFFER_PRESERVED;
    mSwapInterval = -1;
    mWidth = -1;
    mHeight = -1;
    setSwapInterval(1);

    subclassWindow();
}

Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType)
    : mDisplay(display), mWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE)
{
    mRenderer = mDisplay->getRenderer();
    mSwapChain = NULL;
    mWindowSubclassed = false;
    mTexture = NULL;
    mTextureFormat = textureFormat;
    mTextureTarget = textureType;

    mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
    mRenderBuffer = EGL_BACK_BUFFER;
    mSwapBehavior = EGL_BUFFER_PRESERVED;
    mSwapInterval = -1;
    setSwapInterval(1);
}

Surface::~Surface()
{
    unsubclassWindow();
    release();
}

bool Surface::initialize()
{
    if (!resetSwapChain())
      return false;

    return true;
}

void Surface::release()
{
    delete mSwapChain;
    mSwapChain = NULL;

    if (mTexture)
    {
        mTexture->releaseTexImage();
        mTexture = NULL;
    }
}

bool Surface::resetSwapChain()
{
    ASSERT(!mSwapChain);

    int width;
    int height;

    if (mWindow)
    {
#if defined(ANGLE_PLATFORM_WINRT)
        winrt::getCurrentWindowDimensions(width, height);
#else
        RECT windowRect;
        if (!GetClientRect(getWindowHandle(), &windowRect))
        {
            ASSERT(false);

            ERR("Could not retrieve the window dimensions");
            return error(EGL_BAD_SURFACE, false);
        }

        width = windowRect.right - windowRect.left;
        height = windowRect.bottom - windowRect.top;
#endif // #if defined(ANGLE_PLATFORM_WINRT)
    }
    else
    {
        // non-window surface - size is determined at creation
        width = mWidth;
        height = mHeight;
    }

    mSwapChain = mRenderer->createSwapChain(mWindow, mShareHandle,
                                            mConfig->mRenderTargetFormat,
                                            mConfig->mDepthStencilFormat);
    if (!mSwapChain)
    {
        return error(EGL_BAD_ALLOC, false);
    }

    if (!resetSwapChain(width, height))
    {
        delete mSwapChain;
        mSwapChain = NULL;
        return false;
    }

    return true;
}

bool Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
{
    ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
    ASSERT(mSwapChain);

    EGLint status = mSwapChain->resize(backbufferWidth, backbufferHeight);

    if (status == EGL_CONTEXT_LOST)
    {
        mDisplay->notifyDeviceLost();
        return false;
    }
    else if (status != EGL_SUCCESS)
    {
        return error(status, false);
    }

    mWidth = backbufferWidth;
    mHeight = backbufferHeight;

    return true;
}

bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
{
    ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
    ASSERT(mSwapChain);

    EGLint status = mSwapChain->reset(backbufferWidth, backbufferHeight, mSwapInterval);

    if (status == EGL_CONTEXT_LOST)
    {
        mRenderer->notifyDeviceLost();
        return false;
    }
    else if (status != EGL_SUCCESS)
    {
        return error(status, false);
    }

    mWidth = backbufferWidth;
    mHeight = backbufferHeight;
    mSwapIntervalDirty = false;

    return true;
}

bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
{
    if (!mSwapChain)
    {
        return true;
    }

    if (x + width > mWidth)
    {
        width = mWidth - x;
    }

    if (y + height > mHeight)
    {
        height = mHeight - y;
    }

    if (width == 0 || height == 0)
    {
        return true;
    }

    EGLint status = mSwapChain->swapRect(x, y, width, height);

    if (status == EGL_CONTEXT_LOST)
    {
        mRenderer->notifyDeviceLost();
        return false;
    }
    else if (status != EGL_SUCCESS)
    {
        return error(status, false);
    }

    checkForOutOfDateSwapChain();

    return true;
}

EGLNativeWindowType Surface::getWindowHandle()
{
    return mWindow;
}

#define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")

#if !defined(ANGLE_PLATFORM_WINRT)
static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
  if (message == WM_SIZE)
  {
      Surface* surf = reinterpret_cast<Surface*>(GetProp(hwnd, kSurfaceProperty));
      if(surf)
      {
          surf->checkForOutOfDateSwapChain();
      }
  }
  WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
  return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
}
#endif // #if !defined(ANGLE_PLATFORM_WINRT)

void Surface::subclassWindow()
{
    if (!mWindow)
    {
        return;
    }

#if !defined(ANGLE_PLATFORM_WINRT)
    DWORD processId;
    DWORD threadId = GetWindowThreadProcessId(mWindow, &processId);
    if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId())
    {
        return;
    }

    SetLastError(0);
    LONG_PTR oldWndProc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
    if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS)
    {
        mWindowSubclassed = false;
        return;
    }

    SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
    SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
#endif // #if !defined(ANGLE_PLATFORM_WINRT)
    mWindowSubclassed = true;
}

void Surface::unsubclassWindow()
{
    if(!mWindowSubclassed)
    {
        return;
    }

#if !defined(ANGLE_PLATFORM_WINRT)

    // un-subclass
    LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(mWindow, kParentWndProc));

    // Check the windowproc is still SurfaceWindowProc.
    // If this assert fails, then it is likely the application has subclassed the
    // hwnd as well and did not unsubclass before destroying its EGL context. The
    // application should be modified to either subclass before initializing the
    // EGL context, or to unsubclass before destroying the EGL context.
    if(parentWndFunc)
    {
        LONG_PTR prevWndFunc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, parentWndFunc);
        ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
    }

    RemoveProp(mWindow, kSurfaceProperty);
    RemoveProp(mWindow, kParentWndProc);
#endif // #if !defined(ANGLE_PLATFORM_WINRT)
    mWindowSubclassed = false;
}

bool Surface::checkForOutOfDateSwapChain()
{
#if defined(ANGLE_PLATFORM_WINRT)
    int clientWidth = 0;
    int clientHeight = 0;
    winrt::getCurrentWindowDimensions(clientWidth,clientHeight);
#else
    RECT client;
    if (!GetClientRect(getWindowHandle(), &client))
    {
        ASSERT(false);
        return false;
    }

    // Grow the buffer now, if the window has grown. We need to grow now to avoid losing information.
    int clientWidth = client.right - client.left;
    int clientHeight = client.bottom - client.top;
#endif // #if defined(ANGLE_PLATFORM_WINRT)
    bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();

    if (mSwapIntervalDirty)
    {
        resetSwapChain(clientWidth, clientHeight);
    }
    else if (sizeDirty)
    {
        resizeSwapChain(clientWidth, clientHeight);
    }

    if (mSwapIntervalDirty || sizeDirty)
    {
        if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
        {
            glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
        }

        return true;
    }

    return false;
}

bool Surface::swap()
{
    return swapRect(0, 0, mWidth, mHeight);
}

bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
{
    if (!mPostSubBufferSupported)
    {
        // Spec is not clear about how this should be handled.
        return true;
    }

    return swapRect(x, y, width, height);
}

EGLint Surface::getWidth() const
{
    return mWidth;
}

EGLint Surface::getHeight() const
{
    return mHeight;
}

EGLint Surface::isPostSubBufferSupported() const
{
    return mPostSubBufferSupported;
}

rx::SwapChain *Surface::getSwapChain() const
{
    return mSwapChain;
}

void Surface::setSwapInterval(EGLint interval)
{
    if (mSwapInterval == interval)
    {
        return;
    }

    mSwapInterval = interval;
    mSwapInterval = std::max(mSwapInterval, mRenderer->getMinSwapInterval());
    mSwapInterval = std::min(mSwapInterval, mRenderer->getMaxSwapInterval());

    mSwapIntervalDirty = true;
}

EGLenum Surface::getTextureFormat() const
{
    return mTextureFormat;
}

EGLenum Surface::getTextureTarget() const
{
    return mTextureTarget;
}

void Surface::setBoundTexture(gl::Texture2D *texture)
{
    mTexture = texture;
}

gl::Texture2D *Surface::getBoundTexture() const
{
    return mTexture;
}

EGLenum Surface::getFormat() const
{
    return mConfig->mRenderTargetFormat;
}
}
<|endoftext|>


<commit_before>/*
 * Copyright 2009-2011 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <algorithm>
#include <votca/csg/topology.h>
#include <votca/csg/exclusionlist.h>

namespace votca { namespace csg {

void ExclusionList::Clear(void)
{
    list< exclusion_t *>::iterator iter;

    for(iter=_exclusions.begin();iter!=_exclusions.end();++iter)
        delete *iter;
    _exclusions.clear();
}

void ExclusionList::CreateExclusions(Topology *top) {
	InteractionContainer &ic = top->BondedInteractions();
	InteractionContainer::iterator ia;

	for (ia = ic.begin(); ia != ic.end(); ++ia) {
		int beads_in_int = (*ia)->BeadCount();
		list<Bead *> l;

		for (int ibead = 0; ibead < beads_in_int; ibead ++) {
			int ii = (*ia)->getBeadId(ibead);
			l.push_back(top->getBead(ii));
		}
		ExcludeList(l);
	}
}

bool ExclusionList::IsExcluded(Bead *bead1, Bead *bead2) {
    exclusion_t *excl;
    if(bead1->getMolecule() == bead2->getMolecule()) return false;
    if (bead2 < bead1) swap(bead1, bead2);
    if ((excl = GetExclusions(bead1))) {
        if(find(excl->_exclude.begin(), excl->_exclude.end(), bead2)
                != excl->_exclude.end()) return true;
    }
    return false;
}

std::ostream &operator<<(std::ostream &out, ExclusionList& exl)
{
    list<ExclusionList::exclusion_t*>::iterator ex;

    for(ex=exl._exclusions.begin();ex!=exl._exclusions.end();++ex) {
        list<Bead *>::iterator i;
        out << (int)((*ex)->_atom->getId()) + 1;
        for(i=(*ex)->_exclude.begin(); i!=(*ex)->_exclude.end(); ++i) {
            out << " " << ((*i)->getId()+1);
        }
        out << endl;
    }
    return out;
}

}}
<commit_msg>fixed Victor's new exclusion list scheme (fixes issue #165)<commit_after>/*
 * Copyright 2009-2011 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <algorithm>
#include <votca/csg/topology.h>
#include <votca/csg/exclusionlist.h>

namespace votca { namespace csg {

void ExclusionList::Clear(void)
{
    list< exclusion_t *>::iterator iter;

    for(iter=_exclusions.begin();iter!=_exclusions.end();++iter)
        delete *iter;
    _exclusions.clear();
}

void ExclusionList::CreateExclusions(Topology *top) {
	InteractionContainer &ic = top->BondedInteractions();
	InteractionContainer::iterator ia;

	for (ia = ic.begin(); ia != ic.end(); ++ia) {
		int beads_in_int = (*ia)->BeadCount();
		list<Bead *> l;

		for (int ibead = 0; ibead < beads_in_int; ibead ++) {
			int ii = (*ia)->getBeadId(ibead);
			l.push_back(top->getBead(ii));
		}
		ExcludeList(l);
	}
}

bool ExclusionList::IsExcluded(Bead *bead1, Bead *bead2) {
    exclusion_t *excl;
    if(bead1->getMolecule() != bead2->getMolecule()) return false;
    if (bead2 < bead1) swap(bead1, bead2);
    if ((excl = GetExclusions(bead1))) {
        if(find(excl->_exclude.begin(), excl->_exclude.end(), bead2)
                != excl->_exclude.end()) return true;
    }
    return false;
}

std::ostream &operator<<(std::ostream &out, ExclusionList& exl)
{
    list<ExclusionList::exclusion_t*>::iterator ex;

    for(ex=exl._exclusions.begin();ex!=exl._exclusions.end();++ex) {
        list<Bead *>::iterator i;
        out << (int)((*ex)->_atom->getId()) + 1;
        for(i=(*ex)->_exclude.begin(); i!=(*ex)->_exclude.end(); ++i) {
            out << " " << ((*i)->getId()+1);
        }
        out << endl;
    }
    return out;
}

}}
<|endoftext|>