text:
//
// Created by david on 28/12/2019.
//

#include "testbench.h"
#include <cmath>
#include <iostream>
#include <unordered_map>
#include <utility>
#include <vector>
#include <list>
#include <set>
#include <random>
#include <chrono>
#include <utils/Randoms.h>
#include <utils/BitSet.h>
#include <typing/TypeInfos.h>
#include <typing/iterator.h>
#include "typing/TypeInfo.h"
#include <boost/format.hpp>
#include <boost/any.hpp>

using std::cout, std::unordered_map, std::vector, std::set, std::list, std::string;

int getFIndex(unsigned long a) {
    for (int i = 0; i < 64; i++) {
        if (a & 1) return i;
        a = a >> 1;
    }
    return -1;
}

int getCIndex(unsigned long a) {
    return (int) log2(a);
}

unordered_map<unsigned long, int> init_map() {
    unordered_map<unsigned long, int> res;
    unsigned long a = 1;
    for (int i = 0; i < 64; i++) {
        res[a] = i;
        a = a << 1;
    }
    return res;
}

int getLIndex(unsigned long a) {
    static auto lookup_table = init_map();
    return lookup_table[a];
}

void algo() {
    const int COMPONENTS = 10000000;
    const int CLICKS = 1000;
    const int W = 1920;
    const int H = 1080;

    vector<BitSet> ys;
    vector<BitSet> xs;

    std::random_device dev;
    std::mt19937 rng(dev());
    std::uniform_int_distribution<std::mt19937::result_type> distx(0, W); // distribution in range [1, 6]
    std::uniform_int_distribution<std::mt19937::result_type> disty(0, H); // distribution in range [1, 6]
    std::uniform_int_distribution<std::mt19937::result_type> distw(10, 10); // distribution in range [1, 6]
    std::uniform_int_distribution<std::mt19937::result_type> disth(10, 10); // distribution in range [1, 6]

    cout << "Initializing sets\n";

    for (int ix = 0; ix <= W; ix++)
        xs.emplace_back(COMPONENTS);

    for (int iy = 0; iy <= H; iy++)
        ys.emplace_back(COMPONENTS);

    cout << "Populating sets\n";
    /*vector<Context *> contexts;
    for (int i = 0; i < COMPONENTS; i++) {
        contexts.push_back(new Context(Randoms::random_string()));
    }*/
    int area = 1;
    auto start = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < COMPONENTS; i++) {
        int x = distx(rng);
        int y = disty(rng);
        int w = distw(rng);
        int h = disth(rng);

        area += w + h;

        for (int ix = x; ix < x + w && ix < W; ix++)
            xs[ix].set(i);
        for (int iy = y; iy < y + h && iy < H; iy++)
            ys[iy].set(i);

    }

    auto finish = std::chrono::high_resolution_clock::now();

    std::cout << "Area: " << area << " Time/100px: "
              << std::chrono::duration_cast<std::chrono::microseconds>(finish - start).count() / (1000.0f * area / 100)
              << " in "
              << std::chrono::duration_cast<std::chrono::microseconds>(finish - start).count() / 1000.0f
              << " ms\n";

    int avg_fill = 0;
    for (int ix = 0; ix < W; ix++)
        avg_fill += xs[ix].count();
    for (int iy = 0; iy < H; iy++)
        avg_fill += ys[iy].count();

    cout << "avg_fill:" << avg_fill / (W + H) << "\n";

    vector<int> txs;
    vector<int> tys;

    for (int i = 0; i < CLICKS; i++) {
        txs.push_back(distx(rng));
        tys.push_back(disty(rng));
    }

    int intersections = 0;

    cout << "Intersecting sets\n";
    start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < CLICKS; i++) {
        intersections += xs[txs[i]].fintersect(ys[tys[i]]);
    }

    finish = std::chrono::high_resolution_clock::now();

    std::cout << "Intersections: " << intersections / (1.0f * CLICKS) << " in "
              << std::chrono::duration_cast<std::chrono::microseconds>(finish - start).count() / (1000.0f * CLICKS)
              << " ms\n";
}

void test_indexing() {
    int SAMPLES;
    std::cin >> SAMPLES;
    vector<unsigned long> l;

    std::random_device dev;
    std::mt19937 rng(dev());
    std::uniform_int_distribution<std::mt19937::result_type> dist6(0, 63); // distribution in range [1, 6]

    unsigned long one = 1;
    for (int i = 0; i < SAMPLES; i++)
        l.push_back(one << dist6(rng));

    // Record start time
    auto start = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < SAMPLES; i++) {
        if (getFIndex(l[i]) < 0)
            cout << "negative\n";
    }

    auto finish = std::chrono::high_resolution_clock::now();

    std::cout << "For: " << std::chrono::duration_cast<std::chrono::microseconds>(finish - start).count() / 1000.0f
              << " ms\n";

    start = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < SAMPLES; i++) {
        if (getCIndex(l[i]) < 0)
            cout << "negative\n";
    }

    finish = std::chrono::high_resolution_clock::now();

    std::cout << "Calculated: "
              << std::chrono::duration_cast<std::chrono::microseconds>(finish - start).count() / 1000.0f << " ms\n";

    start = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < SAMPLES; i++) {
        if (getLIndex(l[i]) < 0)
            cout << "negative\n";
    }

    finish = std::chrono::high_resolution_clock::now();

    std::cout << "Lookup: " << std::chrono::duration_cast<std::chrono::microseconds>(finish - start).count() / 1000.0f
              << " ms\n";

    start = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < SAMPLES; i++) {
        if (SAMPLES < 200) {
            if (getFIndex(l[i]) < 0)
                cout << "negative\n";
        } else {
            if (getCIndex(l[i]) < 0)
                cout << "negative\n";
        }
    }

    finish = std::chrono::high_resolution_clock::now();

    std::cout << "Best: " << std::chrono::duration_cast<std::chrono::microseconds>(finish - start).count() / 1000.0f
              << " ms\n";

}

void indirect_tb() {
    vector<int> original;
    vector<int> first;
    vector<int> second;
    vector<int> third;

    int N = 100000000;

    for (int i = 0; i < N; i++) {
        original.push_back(i);
        first.push_back(original[i]);
        second.push_back(first[i]);
        third.push_back(second[i]);
    }

    int total = 0;
    auto t0 = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < N; i++) {
        total += original[first[second[third[i]]]];

    }

    auto t1 = std::chrono::high_resolution_clock::now();

    cout << "Avg time:"
         << static_cast<int>(std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count()) / 1000
         << ",    ans: " << total << "\n";

    total = 0;
    t0 = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < N; i++) {
        total += original[first[i]];
    }

    t1 = std::chrono::high_resolution_clock::now();

    cout << "Avg time:"
         << static_cast<int>(std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count()) / 1000
         << ",    ans: " << total << "\n";

    total = 0;
    t0 = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < N; i++) {
        total += original[first[second[i]]];
    }

    t1 = std::chrono::high_resolution_clock::now();

    cout << "Avg time:"
         << static_cast<int>(std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count()) / 1000
         << ",    ans: " << total << "\n";

    total = 0;
    t0 = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < N; i++) {
        total += original[i];
    }

    t1 = std::chrono::high_resolution_clock::now();

    cout << "Avg time:"
         << static_cast<int>(std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count()) / 1000
         << ",    ans: " << total << "\n";

    //fatal_error();
}

void TB::run_windowing() {
    algo();

}

void TB::run_anyvector() {
    struct banana {
        int a;
        int b;
        int c;
    };
    using std::vector;
    using boost::any, boost::any_cast;

    vector<any> myvec;
    myvec.reserve(10);

    printf("\n first:  %p \n second: %p \n 10th:   %p \n", &myvec[0], &myvec[1], &myvec[2]);

    struct banana ban = {1, 2, 3};

    myvec[0] = (char) 5;
    myvec[1] = ban;
    myvec[2] = (double) 5.0;

    printf("\n first:  %p \n second: %p \n 10th:   %p \n", &myvec[0], &myvec[1], &myvec[2]);
    void *p = &myvec[1];
    printf("\n a: %d \n b: %p \n c: %p \n", any_cast<struct banana>(myvec[1]).c, &myvec[1], &myvec[2]);

}

void TB::deallocating() {
    using namespace std;
    const int size = 100000000;
    double *buffy = new double[size];

    for (int i = 0; i < size; i++)
        buffy[i] = i * 1.2;

    cout << "deallocate?\n";

    double sum = 0.0;
    for (int i = 0; i < size; i++)
        sum += buffy[i];
    cout << sum << endl;
    int a;
    cin >> a;

    void *p = buffy;

    delete[] p;
    cin >> a;
}

template<typename T, size_t offset>
T *access(void *pointy) {
    return (T *) ((char *) pointy + offset);
}

void TB::fancy_types() {
    void *mymem = new char[sizeof(int) + sizeof(double) + 10];
    auto myint = &access<int, 0>;
    auto mydouble = &access<double, sizeof(int)>;
    auto mystring = &access<char, sizeof(int) + sizeof(double)>;

    *myint(mymem) = 10;
    *mydouble(mymem) = 10.0 / 7;
    memset(mystring(mymem), 0, *myint(mymem));
    strcpy(mystring(mymem), "hello");

    cout << *myint(mymem) << " " << *mydouble(mymem) << " " << mystring(mymem);

}

namespace FancyTyping {
    template<typename... Types>
    size_t size_sum() {
        return (sizeof(Types)+...);
    }

    template<>
    size_t size_sum() {
        return 0;
    }

    template<typename T, typename... Types>
    T *access(void *mem) {
        return (T *) ((char *) mem + size_sum<Types...>());
    }

    template<void *mem, typename T, typename... Types>
    T *access() {
        return (T *) ((char *) mem + size_sum<Types...>());
    }

    template<typename... Types>
    void *allocate() {
        return new char[size_sum<Types...>()];
    }

    template<typename... Types>
    void copy(void *dest, void *src) {
        memcpy(dest, src, size_sum<Types...>());
    }
}

class FancyNode {
public:
    static constexpr auto create = &FancyTyping::allocate<int, double>;
    static constexpr auto copy = &FancyTyping::copy<int, double>;
    static constexpr auto age = &FancyTyping::access<int>;
    static constexpr auto kg = &FancyTyping::access<double, int>;

    void *mem;

    operator void *() {
        return this;
    }

    FancyNode() {
        mem = create();
    }

    FancyNode(void *mem) {
        this->mem = create();
        copy(this->mem, mem);
    }
};

void TB::fancy_access() {
    void *mem = FancyNode::create();
    *FancyNode::age(mem) = 11;
    *FancyNode::kg(mem) = 60.15 + *FancyNode::age(mem);

    cout << *FancyNode::age(mem) << " " << *FancyNode::kg(mem) << "\n";

    auto not_pointy = (FancyNode) mem;
    cout << *not_pointy.age(not_pointy) << " " << *not_pointy.kg(not_pointy) << "\n";
    cout << *not_pointy.age(not_pointy) << " " << *not_pointy.kg(not_pointy) << "\n";

    //FancyNode dupl1(not_pointy);
    FancyNode dupl2(mem);
/*
    //*dupl1.age() = 7;
    *dupl2.kg() = 30.2;

    //cout << *dupl1.age() << " " << *dupl1.kg() << "\n";
    cout << *dupl2.age() << " " << *dupl2.kg() << "\n";
    not_pointy._age(&not_pointy);
    */
}

class FancierNode {
public:

    void *mem;

    FancyTypes::TypeInfo *t;

    FancierNode(FancyTypes::TypeInfo &type) {
        this->t = &type;
        mem = t->create();
        t->initialize(mem);
    }

    template<typename A>
    A access() {
        return (A) mem;
    }

    /*template<typename T, FancyTypes::t_iterator<T> f_iterator, FancyTypes::t_access<T> f_access, FancyTypes::TypeInfo &typeinfo>
    operator FancyTypes::TypeAccess<T, f_iterator, f_access, typeinfo>() {
        return (FancyTypes::TypeAccess<T, f_iterator, f_access, typeinfo>) mem;
    }*/

};

void TB::typeinfo() {
    using namespace FancyTypes;

#if 0
    FancierNode node(int_i);

    int_t myint = node;

    myint = 5;

    cout << "myint: " << myint << "\n";

    auto myotherint = (int_t) node;

    cout << "myotherint: " << myotherint << "\n";
    myotherint = 7;
    cout << "myint: " << myint << "\n";
#endif

    FancierNode node(uninfo_i);

    string_t st = string("hello");

    cout << st << "\n";

    uninfo_t info = node.mem;

    info = {"Bernadette", 4, 1, 3};
    uninfo_t info2 = {"Bernadette", 2, 1, 3};

    uninfo_t info3 = *info + *info2;

    vector<float> myfile(1000);

    for (int i = 0; i < 1000; i++)
        myfile[i] = i / 3.0f;

    for (int y = 0; y < 10; y++)
        for (int x = 0; x < 10; x++)
            cout << myfile[y * 10 + x] << " ";

    cout << "\n";
    iterator dim2(myfile, 10, 10, 3);

    for (int y = 0; y < 10; y++)
        for (int x = 0; x < 10; x++)
            cout << dim2(1, y, x) << " ";

    /*auto l = I(info).length;

    cout << info->length << " = " << l << "\n";*/
    cout << info.toString() << "\n";
    cout << info3.toString() << "\n";

    cout << "glm tests \n";

    vec3_t a({1.0, 0.5, 0.5});
    vec3_t b({1.0, 0.5, 1.33});

    vec3_t c = *a + *b;

    cout << c;

    cout << "\nDone.";
}

// Oh the lag..
/*
#define EVAL0(...) __VA_ARGS__
#define EVAL1(...) EVAL0(EVAL0(EVAL0(__VA_ARGS__)))
#define EVAL2(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__)))
#define EVAL3(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__)))
#define EVAL4(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__)))
#define EVAL(...)  EVAL4(EVAL4(EVAL4(__VA_ARGS__)))

#define MAP_END(...)
#define MAP_OUT
#define MAP_COMMA ,

#define MAP_GET_END2() 0, MAP_END
#define MAP_GET_END1(...) MAP_GET_END2
#define MAP_GET_END(...) MAP_GET_END1
#define MAP_NEXT0(test, next, ...) next MAP_OUT
#define MAP_NEXT1(test, next) MAP_NEXT0(test, next, 0)

#define MAP_NEXT(test, next)  MAP_NEXT1(MAP_GET_END test, next)

#define MAP0(f, x, peek, ...) f(x) MAP_NEXT(peek, MAP1)(f, peek, __VA_ARGS__)
#define MAP1(f, x, peek, ...) f(x) MAP_NEXT(peek, MAP0)(f, peek, __VA_ARGS__)

#define MAP_LIST_NEXT1(test, next) MAP_NEXT0(test, MAP_COMMA next, 0)
#define MAP_LIST_NEXT(test, next)  MAP_LIST_NEXT1(MAP_GET_END test, next)

#define MAP_LIST0(f, x, peek, ...) f(x) MAP_LIST_NEXT(peek, MAP_LIST1)(f, peek, __VA_ARGS__)
#define MAP_LIST1(f, x, peek, ...) f(x) MAP_LIST_NEXT(peek, MAP_LIST0)(f, peek, __VA_ARGS__)

#define MAP_2P0(f, x, y, peek, ...) f(x, y) MAP_NEXT(peek, MAP_2P1)(f, peek, __VA_ARGS__)
#define MAP_2P1(f, x, y, peek, ...) f(x, y) MAP_NEXT(peek, MAP_2P0)(f, peek, __VA_ARGS__)

#define MAP_2P_LIST0(f, x, y, peek, ...) f(x, y) MAP_LIST_NEXT(peek, MAP_2P_LIST1)(f, peek, __VA_ARGS__)
#define MAP_2P_LIST1(f, x, y, peek, ...) f(x, y) MAP_LIST_NEXT(peek, MAP_2P_LIST0)(f, peek, __VA_ARGS__)

#define MAP_2P(f, ...) EVAL(MAP_2P1(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))

#define MAP_2P_LIST(f, ...)  EVAL(MAP_2P_LIST1(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))

#define MAP(f, ...) EVAL(MAP1(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))

#define MAP_LIST(f, ...) EVAL(MAP_LIST1(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))

#define STRINGIFY(x) #x
#define CALL(x, y) printf(STRINGIFY(x))
*/

void TB::macro_parenthesis() {
    //MAP_2P_LIST(CALL, a, b, c, d);
}

template<typename T, template<typename...> typename Template>
struct is_specialization : std::false_type {
};

template<template<typename...> typename Template, typename... Args>
struct is_specialization<Template<Args...>, Template> : std::true_type {
};

//template <typename T, template <typename...> typename Template>
//using is_specialization_v = typename is_specialization<T, Template>::value;

template<int N, typename... Args>
struct nth_arg;

template<typename Head, typename... Rest>
struct nth_arg<0, Head, Rest...> {
    typedef Head type;
};

template<int N, typename Head, typename... Rest>
struct nth_arg<N, Head, Rest...> {
    typedef typename nth_arg<N - 1, Rest...>::type type;
};

template<typename S, template<typename...> typename T>
struct argument_extractor;

template<template<typename...> typename C, typename... Args>
struct argument_extractor<C<Args...>, C> {
    template<int N>
    using nth_arg = typename nth_arg<N, Args...>::type;
};

/*
inline typename std::enable_if<(not std::is_same<T, int>::value)
                               and (not std::is_same<T, float>::value), void>::type
*/
/*
template <template <typename> typename C, typename T>
constexpr inline typename std::enable_if<std::is_pointer<C<T>>::value, int>::type
gimme_info(){
    auto content = gimme_info<std::remove_pointer_t<C<T>>>();
    return 200 + content;
}

template <template <typename> typename C, typename T>
constexpr inline typename std::enable_if<not std::is_pointer<C<T>>::value, int>::type
gimme_info(){}
*/

template<typename, typename Condition=void>
struct gimme_info;

template<>
struct gimme_info<int> {
    static constexpr int value = 1;
};

template<>
struct gimme_info<float> {
    static constexpr int value = 2;
};

template<typename A, typename B, typename C>
struct mycomplexthing {
};

//std::enable_if_t<std::is_pointer<T>::value, int> = 0
template<typename T>
struct gimme_info<T, typename std::enable_if_t<std::is_pointer_v<T>>> {
    static constexpr int value = 10 * gimme_info<std::remove_pointer_t<T>>::value;
};

template<typename C>
struct gimme_info<C, typename std::enable_if_t<is_specialization<C, std::vector>::value>> {
    static constexpr int value =
            5 + 10 * gimme_info<typename argument_extractor<C, std::vector>::template nth_arg<0>>::value;
};

template<typename C>
struct gimme_info<C, typename std::enable_if_t<is_specialization<C, mycomplexthing>::value>> {
    static constexpr int value =
            (((gimme_info<typename argument_extractor<C, mycomplexthing>::template nth_arg<0>>::value) * 10
              + gimme_info<typename argument_extractor<C, mycomplexthing>::template nth_arg<1>>::value) * 10
             + gimme_info<typename argument_extractor<C, mycomplexthing>::template nth_arg<2>>::value) * 10 + 6;
};

/*
// Value of <T>
template <typename T>
constexpr inline typename std::enable_if<not std::is_pointer<T>::value, int>::type
gimme_info();

template <>
constexpr int gimme_info<int>(){
    return 1;
}

template <>
constexpr int gimme_info<float>(){
    return 2;
}

// Value of <T*>
template <typename T>
constexpr inline typename std::enable_if<std::is_pointer<T>::value, int>::type
gimme_info(){
    auto content = gimme_info<std::remove_pointer_t<T>>();
    return 10 + content;
}
*/
// Value of <C<T>>
//template <typename C, typename T>
//constexpr inline typename std::enable_if<not std::is_pointer<C<T>>::value, int>::type
//constexpr inline int
//gimme_info();

/*
template <template <typename...> typename C, typename T>
constexpr inline typename std::enable_if<(not std::is_pointer<C<T>>::value) and std::is_same<C<T>, vector<T>>::value, int>::type
gimme_info(){
    //auto content = gimme_info<T>();
    return 100;// + content;
}
*/
/*
template <typename C>
constexpr inline typename std::enable_if_t<is_specialization<C, std::vector>::value, int>
gimme_info(){
    auto content = gimme_info<argument_extractor<C, std::vector>::template nth_arg<1>>();
    return 100 + content;
}
*/
/*
template<typename T>
struct banana{
    template <typename C>
    banana(){

    }
}
 */

//template<typename C>
//using extract_args = argument_extractor<C>;

/*
template <template <typename> typename C, typename T>
constexpr inline typename std::enable_if<(not std::is_pointer<C<T>>::value) and std::is_same<C<T>, vector<T>>::value, int>::type
gimme_info(){
    auto content = gimme_info<T>();
    return 10 + content;
}
*/

void TB::templating() {
    using boost::format;
    cout << format("1 = %1%\n") % gimme_info<int>::value;
    cout << format("2 = %1%\n") % gimme_info<float>::value;
    cout << format("10 = %1%\n") % gimme_info<int *>::value;
    cout << format("10 = %1%\n") % gimme_info<float *>::value;
    //cout << format("err = %1%\n") % gimme_info<double>::value;
    //cout << format("err = %1%\n") % gimme_info<double*>::value;
    cout << format("15 = %1%\n") % gimme_info<vector<int>>::value;
    cout << format("25 = %1%\n") % gimme_info<vector<float>>::value;
    cout << format("105 = %1%\n") % gimme_info<vector<int *>>::value;
    cout << format("205 = %1%\n") % gimme_info<vector<float *>>::value;
    cout << format("150 = %1%\n") % gimme_info<vector<int> *>::value;
    cout << format("250 = %1%\n") % gimme_info<vector<float> *>::value;
    cout << format("1050 = %1%\n") % gimme_info<vector<int *> *>::value;
    cout << format("2050 = %1%\n") % gimme_info<vector<float *> *>::value;
    cout << format("115265 = %1%\n") % gimme_info<vector<mycomplexthing<int, vector<int>, float>>>::value;
}

void TB::birthday() {
    using namespace std;
    using boost::format;

    long double k = 3.141592653589793238462643383279502884L;

    long double best_error = k;
    uint64_t start = 7;
    for (uint64_t i = 1; i < 1000000; i++) {
        long double cn = k * i;
        long double err = 0.5L - abs(cn - floor(cn) - 0.5L);
        if (err < best_error) {
            best_error = err;
            cout << i << " " << err << "\n";
            cout << (i - 2) % 113 << "\n";
        }
    }
    glm::vec3(0, 0, 0);
}

void fun(int *&myptr) {
    cout << "Hello from &\n";
}

void fun(int *&&myptr) {
    cout << "Hello from &&\n";
}

void TB::movingpointers() {
    int *p = new int(5);

    fun(p);
    fun(std::move(p));

    fun(new int(5));
    fun(std::move(new int(5)));

    //I love successful tests
}

#define _A(k, a, b) k::a + k::b
#define _B(k, a, b) k::a * k::b

#define MCAT(a, b, c) a ## b ## C
#define A(a, b) MCAT(k, ::, a) + MCAT(k, ::, b)

#define C(k, m) m

struct mystruct_macro_order {
    constexpr static int k1 = 1;
    constexpr static int k2 = 2;
};

void TB::mystruct_macro_order() {
    //cout<<C(mystruct, C(mystruct, A(k1,k2)));
}

struct structuring_vector_struct {
    int a;
    int b;
    int c;
    int d;
    int e;
};

void TB::structuring_vector() {
    vector<int> v = {1, 2, 3, 4, 5};

    auto &s = *(structuring_vector_struct *) v.data();

    cout << s.a << s.b << s.c << s.d << s.e;
}

void isit(int *&lvalue) {
    cout << "nope\n";
}

void isit(int *&&rvalue) {
    cout << "yep\n";
}

template<typename T>
void isit_ref(T &&lr_ref) {
    // static_assert(std::is_same_v<std::remove_reference_t<T>, int *>,
    //         "This function does not support the specified type.");
    isit(std::forward<T>(lr_ref));
}

void TB::isRValue() {
    int *k = new int(3);
    isit(new int(5));
    isit(k);
    isit_ref(new int(10));
    isit_ref(k);
    //isit_ref(5);
}

struct scope_node {
    vector<void *> inputs;
    vector<void *> outputs;
};

struct scope_escape {

    typedef scope_escape this_t;
    scope_node *value;

    void link(size_t *what, scope_node *to, size_t where) {

    }

    enum class Inputs : size_t {
        a = 2, b, c
    };

    typedef struct {
        typedef size_t a;
        typedef int b;
        typedef double c;
    } Inputs_t;

    enum class Outputs : size_t {
        a = 2, b, c
    };

    typedef struct {
        typedef size_t a;
        typedef int b;
        typedef double c;
    } Outputs_t;

};

#define link_scope(dest, dest_where, src, src_where) \
dest.value->inputs[(size_t) decltype(dest)::Inputs::dest_where] = \
src.value->outputs[(size_t) decltype(src)::Outputs::src_where]

void TB::scope_escape_tb() {
    typedef int myint;
    scope_escape::this_t::this_t::Inputs_t::a a = (size_t) scope_escape::Inputs::a;
    cout << (myint) a;

    scope_escape n1, n2;
    typedef decltype(n1)::Inputs n1_ii;
    typedef decltype(n1)::Outputs n1_oi;
    typedef decltype(n2)::Inputs n2_ii;
    typedef decltype(n2)::Outputs n2_oi;

    auto x = new scope_escape::Outputs_t::b();

    //n1.value->inputs[n1.Inputs.a] = n2.value->outputs[n2.Outputs.b];
    //n1.value->inputs[(size_t) decltype(n1)::input_indexes::a] =
    //        n2.value->outputs[(size_t) decltype(n2)::input_indexes::b];

    link_scope(n1, a, n2, b);

}

struct SynSugar {
    int a;
    enum class idx : std::size_t {
        a, b, c, __end
    };
    int r[(size_t) idx::__end] = {1, 2, 3};

    SynSugar(int x) {
        a = x;
    }

    void operator()() {
        cout << "Hello world! " << (size_t) idx::a;
    }
};

void TB::pointy_parant() {
    SynSugar *a = new SynSugar(1);

    (*a)();
    SynSugar &b = *a;

    b();
}

template<size_t index, size_t... values>
struct ct_lut;

template<size_t cur, size_t... values>
struct ct_lut<0, cur, values...> {
    static constexpr size_t value = cur;
};

template<size_t index, size_t cur, size_t... values>
struct ct_lut<index, cur, values...> {
    static constexpr size_t value = ct_lut<index - 1, values...>::value;
};

struct abstract_banana {
    virtual void do_the_flop() = 0;
};

struct banana2 : abstract_banana {

    int k = 0;
    template<size_t N>
    static constexpr size_t lut = ct_lut<N, 1, 2, 3, 4, 5>::value;

    static constexpr size_t arr[5] = {1, 2, 3, 4, 5};
    static const size_t *arr2[3];

    static void print_bananas(bool &var) {
        cout << arr[0];
        var = false;
    }

    void do_the_flop() {
        cout << "|_";
    }

    banana2 &do_the_self_flop() {
        cout << "k: " << k << "\n";
        k++;
        return *this;
    }

    typedef struct {
        typedef float z;
        typedef int start;
        typedef int end;
    } Inputs_t;
};

typedef banana2 banana2;

void TB::lut() {
    bool IamTRUE = true;
    banana2::print_bananas(IamTRUE);
    cout << "I am false: " << IamTRUE;
    abstract_banana **arr = new abstract_banana *[2];
    arr[0] = new banana2();
    arr[0]->do_the_flop();

    banana2().do_the_self_flop().do_the_self_flop().do_the_self_flop();

    banana2::Inputs_t::end a = 2;
}

typedef void (*bad_lambda_func)(vector<int *> &inputs, vector<int *> &outputs, bool &return_control_flow);

bad_lambda_func gimme_good_func() {
    return [](vector<int *> &inputs, vector<int *> &outputs, bool &return_control_flow) {
        static int data = 5;
        cout << "Hello func!\n";
        cout << data++ << "\n";
        return_control_flow = true;
    };
}

void TB::bad_lambda() {
    bad_lambda_func func1 = gimme_good_func();
    bad_lambda_func func2 = gimme_good_func();

    bool ok = false;
    vector<int *> ins = {new int(2)};
    vector<int *> outs = {new int(3)};
    func1(ins, outs, ok);
    func2(ins, outs, ok);
    func1(ins, outs, ok);
    func2(ins, outs, ok);
    cout << "ok: " << ok << "\n";
};

template<typename T>
struct pika {
    T data;

    pika(const T &val) : data(val) {
        cout << "is it l? " << std::is_lvalue_reference_v<T> << "\n";
        cout << "is it r? " << std::is_rvalue_reference_v<T> << "\n";
//        cout << "ref\n";
        if (std::is_same_v<T, int>) {
            cout << "spec\n";
        } else {
            cout << "tmp\n";
        }
    }

    pika(const int *val) : data(val) {
        cout << "int*ss\n";
    }

    operator int *() {
        return new int(5);
    }

    int &gimme_data() &{
        return *new int(7);
    }

    int &&gimme_data() &&{
        return std::move(*new int(7));
    }
};

template<typename T>
void lr_info(T &data) {
    cout << "data is lvalue\n";
}

template<typename T>
void lr_info(T &&data) {
    cout << "data is rvalue\n";
}

void TB::pikapika() {
    auto grr = pika(string("a"));
    string x = "Hellooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n";
    auto grrr = pika(x);
    cout << x;
    auto nyaa = pika(5);
    auto nya = pika(new int(5));

    cout << *(int *) nya;

    lr_info(x);
    lr_info(new int(5));
    cout << "member tests:\n";
    lr_info(nya.gimme_data());
    lr_info(pika(new int(5)).gimme_data());
}

void dosth_opt(std::optional<bool *> dosth = {}) {
    if (dosth.has_value()) {
        if (*dosth != nullptr && **dosth == true)
            cout << "I received: true\n";
        else if (*dosth != nullptr && **dosth == false)
            cout << "I received: false\n";
        else
            cout << "What is this fakery\n";
    } else {
        cout << "Nothing mate \n";
    }
}

void TB::optional() {
    dosth_opt();
    dosth_opt(new bool(true));
    dosth_opt(new bool(false));
    dosth_opt(nullptr);
}

int cr_func(int &x) {
    return x + 5;
}

constexpr int cr_func(const int &x) {
    return x + 1;
}

void TB::cr_test() {
    cout << cr_func(5);
    int k = time(nullptr) % 3;
    cout << cr_func(k);
}

void TB::vector_init() {
    vector<int *> myvec = vector<int *>(5);

    myvec.push_back(new int(3));
    cout << "inserted at: " << myvec.size() - 1 << "\n";
    for (int i = 0; i < myvec.size(); i++) {
        if (myvec[i] != nullptr)
            cout << "[" << i << "]: " << *myvec[i] << "\n";
    }

    vector<int> z;
    //R.I.P. last ounce of consistency
    z.push_back(0);
    //z.push_back({1,2,3});
    z.insert(z.end(), 4);
    z.insert(z.end(), {5, 6, 7});
    z = {1, 2, 3};
    for (auto x : z) {
        cout << x << " ";
    }
}

template<typename T, typename Cond = void>
struct is_const_char_array : std::false_type {
};

template<typename T>
struct is_const_char_array<T,
        std::enable_if_t<std::is_array_v<std::remove_reference_t<T>> and
                         std::is_same_v<const char, std::remove_extent_t<std::remove_reference_t<T>>>
        >> : std::true_type {
};

template<typename T>
inline constexpr bool is_const_char_array_v = is_const_char_array<T>::value;

template<typename T, int N = 3>
struct fwd_tag {
};

template<typename T, int N = 0>
struct forwarder {
    typedef T type;
    static const int n = N;
};

template<typename T, int N>
struct forwarder<fwd_tag<T, N>> {
    typedef T type;
    static const int n = N;
};

template<typename T>
using forwarder_t = typename forwarder<T>::type;
template<typename T>
inline const int forwarder_n = forwarder<T>::n;

void TB::is_T() {
    const char (&var)[9] = "position";
    cout << std::is_array_v<std::remove_reference_t<decltype(var)>>;
    cout << std::is_lvalue_reference_v<decltype(var)>;
    cout << std::is_same_v<const char, std::remove_extent_t<std::remove_reference_t<decltype(var)>>>;
    cout << "\n...\n";
    cout << is_const_char_array_v<const char (&)[9]>;
    cout << is_const_char_array_v<const char>;
    cout << is_const_char_array_v<char *>;
    cout << is_const_char_array_v<char *&&>;
    cout << is_const_char_array_v<const char *>;
    cout << is_const_char_array_v<const char *[10]>;
    cout << is_const_char_array_v<const char[10]>;
    cout << is_const_char_array_v<const char[]>;
    cout << is_const_char_array_v<decltype("ana")>;
    cout << "\n...\n";
    cout << is_const_char_array_v<forwarder_t<const char (&)[9]>>;
    cout << is_const_char_array_v<forwarder_t<fwd_tag<const char (&)[9]>>>;
    cout << "\n n: " << forwarder_n<fwd_tag<const char (&)[9], 7>> << "\n";
    cout << "\n n: " << forwarder_n<fwd_tag<const char (&)[9]>> << "\n";
    cout << "\n n: " << forwarder_n<const char (&)[9]> << "\n";

    int data = 5;
    int *dataptr = &data;

    lr_info(&data);
    lr_info(dataptr);
}

template<typename T1>
struct two_con {
    bool value1, value2;

    two_con() {
        value1 = std::is_pointer_v<T1>;
    }

    template<typename _T = T1, typename std::enable_if_t<std::is_same_v<_T, int>, int> = 0>
    void do_the_int_thing() {
        cout << "the int thing\n";
    }
};

void TB::implicit_two_con() {
    vector<int> banana;

    //two_con<int*>().do_the_int_thing();
}

struct jail_struct {
    static constexpr char *name = "Bob";
    vector<int> years_left;

};

void TB::struct_scope_escape() {
    cout << jail_struct::name;
}

// my_template.h
template<typename T>
struct my_template {
    static int brain_size;

    my_template() {
        brain_size++;
    }
};

template<typename T>
int my_template<T>::brain_size = 0;

template<typename T>
struct my_templ {
    // Genius logic: define it in the same file -> "must be defined out of line" -> define it in a separate file
    // -> "undefined reference"
    // Solution: define it the same file BUT LOWER *big brain stuff*
    // Logical conclusion: The C++ Standard eats memes and sometimes they pass undigested
    inline static int instance = 0;

    my_templ() {
        cout << "This is the most brain dead undefined reference I've ever seen: << " << instance++ << " \n";
    }
};

//template<typename T>
//int my_templ<T>::instance = 0;

/*
template<typename T>
struct my_templ_macro_ready;
template<typename T>
int my_templ_macro_ready<T>::instance = 0;
template<typename T>
struct my_templ_macro_ready{
    static int instance;
    my_templ_macro_ready(){
        cout << "This is the most brain dead undefined reference I've ever seen: << " <<  instance++ << " \n";
    }
};
 */

void TB::template_inconsitencies() {
    my_templ<int> i1;
    my_templ<int> i2;
    my_templ<char> c1;
    my_templ<int> i3;
    my_templ<char> c2;
};

size_t tunc_2p_down(size_t x) {
    size_t res = x >> 1;
    res |= res >> 1;
    res |= res >> 2;
    res |= res >> 4;
    res |= res >> 8;
    res |= res >> 16;
    res |= res >> 32;
    return x & ~res;
}

void TB::trunc_pow2() {
    for (size_t i = 2; i < 2048;) {
        cout << (tunc_2p_down(i) >> 1) << " < " << i << "\n";
        i += tunc_2p_down(i) >> 1;
    }
}

void TB::dynamic_queue() {
    std::list<int> queue;
    queue.push_back(1);
    for (auto &cur : queue) {
        if (cur < 1000)
            queue.push_back(cur * 2);
        cout << cur << "\n";
    }
}

max_stars_repo_name: davidgtl/GraphKat

max_issues_repo_name: davidgtl/GraphKat

max_forks_repo_name: davidgtl/GraphKat


text:
//
// Copyright 2010 Christian Henning
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#ifndef BOOST_GIL_EXTENSION_IO_TARGA_OLD_HPP
#define BOOST_GIL_EXTENSION_IO_TARGA_OLD_HPP

#include <boost/gil/extension/io/targa.hpp>

namespace boost {
namespace gil {

/// \ingroup BMP_IO
/// \brief Returns the width and height of the BMP file at the specified
/// location. Throws std::ios_base::failure if the location does not correspond
/// to a valid BMP file
template <typename String>
inline point_t targa_read_dimensions(String const &filename) {
  using backend_t = typename get_reader_backend<String, targa_tag>::type;
  backend_t backend = read_image_info(filename, targa_tag());
  return {backend._info._width, backend._info._height};
}

/// \ingroup BMP_IO
/// \brief Loads the image specified by the given targa image file name into the
/// given view. Triggers a compile assert if the view color space and channel
/// depth are not supported by the BMP library or by the I/O extension. Throws
/// std::ios_base::failure if the file is not a valid BMP file, or if its color
/// space or channel depth are not compatible with the ones specified by View,
/// or if its dimensions don't match the ones of the view.
template <typename String, typename View>
inline void targa_read_view(const String &filename, const View &view) {
  read_view(filename, view, targa_tag());
}

/// \ingroup BMP_IO
/// \brief Allocates a new image whose dimensions are determined by the given
/// bmp image file, and loads the pixels into it. Triggers a compile assert if
/// the image color space or channel depth are not supported by the BMP library
/// or by the I/O extension. Throws std::ios_base::failure if the file is not a
/// valid BMP file, or if its color space or channel depth are not compatible
/// with the ones specified by Image
template <typename String, typename Image>
inline void targa_read_image(const String &filename, Image &img) {
  read_image(filename, img, targa_tag());
}

/// \ingroup BMP_IO
/// \brief Loads and color-converts the image specified by the given targa image
/// file name into the given view. Throws std::ios_base::failure if the file is
/// not a valid BMP file, or if its dimensions don't match the ones of the view.
template <typename String, typename View, typename CC>
inline void targa_read_and_convert_view(const String &filename,
                                        const View &view, CC cc) {
  read_and_convert_view(filename, view, cc, targa_tag());
}

/// \ingroup BMP_IO
/// \brief Loads and color-converts the image specified by the given targa image
/// file name into the given view. Throws std::ios_base::failure if the file is
/// not a valid BMP file, or if its dimensions don't match the ones of the view.
template <typename String, typename View>
inline void targa_read_and_convert_view(const String &filename,
                                        const View &view) {
  read_and_convert_view(filename, view, targa_tag());
}

/// \ingroup BMP_IO
/// \brief Allocates a new image whose dimensions are determined by the given
/// targa image file, loads and color-converts the pixels into it. Throws
/// std::ios_base::failure if the file is not a valid BMP file
template <typename String, typename Image, typename CC>
inline void targa_read_and_convert_image(const String &filename, Image &img,
                                         CC cc) {
  read_and_convert_image(filename, img, cc, targa_tag());
}

/// \ingroup BMP_IO
/// \brief Allocates a new image whose dimensions are determined by the given
/// targa image file, loads and color-converts the pixels into it. Throws
/// std::ios_base::failure if the file is not a valid BMP file
template <typename String, typename Image>
inline void targa_read_and_convert_image(const String filename, Image &img) {
  read_and_convert_image(filename, img, targa_tag());
}

/// \ingroup BMP_IO
/// \brief Saves the view to a targa file specified by the given targa image
/// file name. Triggers a compile assert if the view color space and channel
/// depth are not supported by the BMP library or by the I/O extension. Throws
/// std::ios_base::failure if it fails to create the file.
template <typename String, typename View>
inline void targa_write_view(const String &filename, const View &view) {
  write_view(filename, view, targa_tag());
}

} // namespace gil
} // namespace boost

#endif

ext: hpp

max_stars_repo_name: sdebionne/gil-reformated

max_issues_repo_name: sdebionne/gil-reformated

max_forks_repo_name: sdebionne/gil-reformated


text:
#include "foo.h"
#include "foo_py.h"

#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/python.hpp>
#include <gtest/gtest.h>

#include <string>
#include <iostream>

using boost::python::object;
using boost::python::handle;
using boost::python::borrowed;
using boost::python::error_already_set;

TEST(EmbPy, RunFromString) {
  Py_Initialize();
  try {
    PyRun_SimpleString(
      "a_foo = None\n"
      "\n"
      "def setup(a_foo_from_cxx):\n"
      "  print 'setup called with', a_foo_from_cxx\n"
      "  global a_foo\n"
      "  a_foo = a_foo_from_cxx\n"
      "\n"
      "def run():\n"
      "  a_foo.doSomething()\n"
      "\n"
      "print 'main module loaded'\n"
    );

    boost::shared_ptr<Foo> ptr_cc_object = boost::make_shared<Foo>("c++");

    inithello_();
    object main = object(handle<>(borrowed(PyImport_AddModule("__main__"))));

    // pass the reference to a_cxx_foo into python:
    object setup_function = main.attr("setup");
    setup_function(ptr_cc_object);

    // now run the python 'main' function
    object run_func = main.attr("run");
    run_func();
  } catch (error_already_set) {
    PyErr_Print();
  }

  Py_Finalize();
}

TEST(EmbPy, RunFromFile) {
  Py_Initialize();
  try {
    boost::shared_ptr<Foo> ptr_cc_object = boost::make_shared<Foo>("c++");

    object main = object(handle<>(borrowed(PyImport_AddModule("__main__"))));
    boost::python::object global_namespace(main.attr("__dict__"));
    boost::python::exec_file("./scripts/foo.py", global_namespace, global_namespace);

    // pass the reference to a_cxx_foo into python:
    object setup_function = main.attr("setup");
    setup_function(ptr_cc_object);

    // now run the python 'main' function
    object run_func = main.attr("run");
    run_func();
  } catch (error_already_set) {
    PyErr_Print();
  }

  Py_Finalize();
}

ext: cc


text:
/*=============================================================================
    Copyright (c) 2001-2014 Joel de Guzman

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_CALC8_ANNOTATION_HPP)
#define BOOST_SPIRIT_X3_CALC8_ANNOTATION_HPP

#include <map>
#include "ast.hpp"
#include <boost/spirit/home/x3/support/utility/lambda_visitor.hpp>

namespace client
{
    // tag used to get our error handler from the context
    struct error_handler_tag;
}

namespace client { namespace parser
{
    struct annotation_base
    {
        ////////////////////////////////////////////////////////////////////////
        //  The on_success handler links the AST to a vector of iterator
        //  positions for the purpose of subsequent semantic error handling
        //  when the program is being compiled. See x3::position_cache in
        //  x3/support/ast
        ////////////////////////////////////////////////////////////////////////

        template <typename Iterator, typename Context>
        inline void
        on_success(Iterator const& first, Iterator const& last
          , ast::operand& ast, Context const& context)
        {
            auto& error_handler = x3::get<error_handler_tag>(context).get();
            auto annotate = [&](auto& node)
            {
                error_handler.tag(node, first, last);
            };
            ast.apply_visitor(x3::make_lambda_visitor<void>(annotate));
        }

        template <typename T, typename Iterator, typename Context>
        inline void
        on_success(Iterator const& first, Iterator const& last
          , T& ast, Context const& context)
        {
            auto& error_handler = x3::get<error_handler_tag>(context).get();
            error_handler.tag(ast, first, last);
        }
    };
}}

#endif

max_stars_repo_name: Abce/boost


text:
#include <kv/Heine.hpp>
#include <kv/qAiry.hpp>
#include <kv/qBessel.hpp>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <kv/interval.hpp>

// define rounding operations for double
// if "rdouble.hpp" is not included, result of computation is not "verified"
#include <kv/rdouble.hpp>
typedef kv::interval<double> itv;
typedef kv::complex< kv::interval<double> > cp;
using namespace std;
namespace ub = boost::numeric::ublas;

int main()
{
  cout.precision(17);
  ub::vector< itv > x(30);
  int n=20;
  itv y,nu,q,xx;
  q="0.7";
  nu=1.5;
  y=20.;

  x(0)=y;

  for(int i=1;i<=n;i++){
    xx=mid(x(i-1));
    x(i)=xx-kv::HEratio(itv(xx),itv(nu),itv(q))*(1-q)*x(i-1)
      /(kv::HEratio(itv(x(i-1)),itv(nu),itv(q))-kv::HEratio(itv(q*x(i-1)),itv(nu),itv(q)));
    cout<<x(i)<<endl;
    //cout<<i<<endl;
    cout<<"value of HE inf"<<kv::Hahn_Exton(itv(x(i).lower()),itv(nu),itv(q))<<endl;
    cout<<"value of HE sup"<<kv::Hahn_Exton(itv(x(i).upper()),itv(nu),itv(q))<<endl;
    cout<<"value of HE mid"<<kv::Hahn_Exton(itv(mid(x(i))),itv(nu),itv(q))<<endl;
  }
 }
  // to be updated

max_stars_repo_name: Daisuke-Kanaizumi/q-special-functions

max_issues_repo_name: Daisuke-Kanaizumi/q-special-functions

max_forks_repo_name: Daisuke-Kanaizumi/q-special-functions


text:
// make sure the modern opengl headers are included before any others
#include <OpenGL/gl3.h>
#define __gl_h_
#include <igl/frustum.h>
#include <igl/read_triangle_mesh.h>
#include <igl/opengl/create_shader_program.h>
#include <Eigen/Core>
#include <GLUT/glut.h>
#include <string>

void init_render_to_texture(
  const size_t w, const size_t h, GLuint & tex, GLuint & dtex, GLuint & fbo)
{
  const auto & gen_tex = [](GLuint & tex)
  {
    // http://www.opengl.org/wiki/Framebuffer_Object_Examples#Quick_example.2C_render_to_texture_.282D.29
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  };
  // Generate texture for colors and attached to color component of framebuffer
  gen_tex(tex);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, w, h, 0, GL_BGRA, GL_FLOAT, NULL);
  glBindTexture(GL_TEXTURE_2D, 0);
  glGenFramebuffers(1, &fbo);
  glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  // Generate texture for depth and attached to depth component of framebuffer
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
  gen_tex(dtex);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, w, h, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, dtex, 0);
  // Clean up
  glBindFramebuffer(GL_FRAMEBUFFER, 0);
  glBindTexture(GL_TEXTURE_2D,0);
}

// For rendering a full-viewport quad, set tex-coord from position
std::string tex_v_shader = R"(
#version 330 core
in vec3 position;
out vec2 tex_coord;
void main()
{
  gl_Position = vec4(position,1.);
  tex_coord = vec2(0.5*(position.x+1), 0.5*(position.y+1));
}
)";
// Render directly from color or depth texture
std::string tex_f_shader = R"(
#version 330 core
in vec2 tex_coord;
out vec4 color;
uniform sampler2D color_texture;
uniform sampler2D depth_texture;
uniform bool show_depth;
void main()
{
  vec4 depth = texture(depth_texture,tex_coord);
  // Mask out background which is set to 1
  if(depth.r<1)
  {
    color = texture(color_texture,tex_coord);
    if(show_depth)
    {
      // Depth of background seems to be set to exactly 1.
      color.rgb = vec3(1,1,1)*(1.-depth.r)/0.006125;
    }
  }else
  {
    discard;
  }
}
)";

// Pass-through vertex shader with projection and model matrices
std::string scene_v_shader = R"(
#version 330 core
uniform mat4 proj;
uniform mat4 model;
in vec3 position;
void main()
{
  gl_Position = proj * model * vec4(position,1.);
}
)";
// Render if first pass or farther than closest frag on last pass
std::string scene_f_shader = R"(
#version 330 core
out vec4 color;
uniform bool first_pass;
uniform float width;
uniform float height;
uniform sampler2D depth_texture;
void main()
{
  color = vec4(0.8,0.4,0.0,0.75);
  color.rgb *= (1.-gl_FragCoord.z)/0.006125;
  if(!first_pass)
  {
    vec2 tex_coord = vec2(float(gl_FragCoord.x)/width,float(gl_FragCoord.y)/height);
    float max_depth = texture(depth_texture,tex_coord).r;
    if(gl_FragCoord.z <= max_depth)
    {
      discard;
    }
  }
}
)";

// shader id, vertex array object
GLuint scene_p_id=0,tex_p_id;
GLuint VAO,QVAO;
// Number of passes
#define k 4
GLuint tex_id[k],dtex_id[k],fbo_id[k];
// full width/height of window, width/height of viewports
int full_w=1440,full_h=480,w=full_w/(k+2),h=full_h/1;
// Mesh data: RowMajor is important to directly use in OpenGL
typedef Eigen::Matrix< float,Eigen::Dynamic,3,Eigen::RowMajor> MatrixV;
typedef Eigen::Matrix<GLuint,Eigen::Dynamic,3,Eigen::RowMajor> MatrixF;
MatrixV V,QV;
MatrixF F,QF;
int main(int argc, char * argv[])
{
  // Init glut and create window + OpenGL context
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_3_2_CORE_PROFILE|GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
  glutInitWindowSize(full_w,full_h);
  glutCreateWindow("test");
  // Compile shaders
  igl::opengl::create_shader_program(scene_v_shader,scene_f_shader,{},scene_p_id);
  igl::opengl::create_shader_program(tex_v_shader,tex_f_shader,{},tex_p_id);
  // Prepare VAOs
  const auto & vao = [](const MatrixV & V, const MatrixF & F, GLuint & VAO)
  {
    // Generate and attach buffers to vertex array
    glGenVertexArrays(1, &VAO);
    GLuint VBO, EBO;
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float)*V.size(), V.data(), GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*F.size(), F.data(), GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
  };

  // Read input mesh from file
  igl::read_triangle_mesh(argv[1],V,F);
  V.rowwise() -= V.colwise().mean();
  V /= (V.colwise().maxCoeff()-V.colwise().minCoeff()).maxCoeff();
  vao(V,F,VAO);
  // square
  const MatrixV QV = (MatrixV(4,3)<<-1,-1,0,1,-1,0,1,1,0,-1,1,0).finished();
  const MatrixF QF = (MatrixF(2,3)<< 0,1,2, 0,2,3).finished();
  vao(QV,QF,QVAO);

  // Main display routine
  glutDisplayFunc(
    []()
    {
      // Projection and modelview matrices
      Eigen::Matrix4f proj = Eigen::Matrix4f::Identity();
      float near = 0.01;
      float far = 3;
      float top = tan(35./360.*M_PI)*near;
      float right = top * (double)w/(double)h;
      igl::frustum(-right,right,-top,top,near,far,proj);
      Eigen::Affine3f model = Eigen::Affine3f::Identity();
      model.translate(Eigen::Vector3f(0,0,-1.5));
      // spin around
      static size_t count = 0;
      model.rotate(Eigen::AngleAxisf(M_PI/180.*count++,Eigen::Vector3f(0,1,0)));

      glEnable(GL_DEPTH_TEST);
      glViewport(0,0,w,h);
      // select program and attach uniforms
      glUseProgram(scene_p_id);
      GLint proj_loc = glGetUniformLocation(scene_p_id,"proj");
      glUniformMatrix4fv(proj_loc,1,GL_FALSE,proj.data());
      GLint model_loc = glGetUniformLocation(scene_p_id,"model");
      glUniformMatrix4fv(model_loc,1,GL_FALSE,model.matrix().data());
      glUniform1f(glGetUniformLocation(scene_p_id,"width"),w);
      glUniform1f(glGetUniformLocation(scene_p_id,"height"),h);
      glBindVertexArray(VAO);
      glDisable(GL_BLEND);
      for(int pass = 0;pass<k;pass++)
      {
        const bool first_pass = pass == 0;
        glUniform1i(glGetUniformLocation(scene_p_id,"first_pass"),first_pass);
        if(!first_pass)
        {
          glUniform1i(glGetUniformLocation(scene_p_id,"depth_texture"),0);
          glActiveTexture(GL_TEXTURE0 + 0);
          glBindTexture(GL_TEXTURE_2D, dtex_id[pass-1]);
        }
        glBindFramebuffer(GL_FRAMEBUFFER, fbo_id[pass]);
        glClearColor(0.0,0.4,0.7,0.);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glDrawElements(GL_TRIANGLES, F.size(), GL_UNSIGNED_INT, 0);
      }
      // clean up and set to render to screen
      glBindVertexArray(0);
      glBindFramebuffer(GL_FRAMEBUFFER, 0);
      glActiveTexture(GL_TEXTURE0 + 0);
      glBindTexture(GL_TEXTURE_2D,0);

      // Get read to draw quads
      glBindVertexArray(QVAO);
      glClearColor(0.0,0.4,0.7,0.);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glUseProgram(tex_p_id);
      // Draw result of each peel
      for(int pass = 0;pass<k;pass++)
      {
        GLint color_tex_loc = glGetUniformLocation(tex_p_id,"color_texture");
        glUniform1i(color_tex_loc, 0);
        glActiveTexture(GL_TEXTURE0 + 0);
        glBindTexture(GL_TEXTURE_2D, tex_id[pass]);
        GLint depth_tex_loc = glGetUniformLocation(tex_p_id,"depth_texture");
        glUniform1i(depth_tex_loc, 1);
        glActiveTexture(GL_TEXTURE0 + 1);
        glBindTexture(GL_TEXTURE_2D, dtex_id[pass]);
        glViewport(pass*w,0*h,w,h);
        glUniform1i(glGetUniformLocation(tex_p_id,"show_depth"),0);
        glDrawElements(GL_TRIANGLES,6, GL_UNSIGNED_INT, 0);
      }

      // Render final result as composite of all textures
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      glEnable(GL_BLEND);
      glDepthFunc(GL_ALWAYS);
      glViewport(k*w,0*h,w,h);
      glUniform1i(glGetUniformLocation(tex_p_id,"show_depth"),0);
      GLint color_tex_loc = glGetUniformLocation(tex_p_id,"color_texture");
      GLint depth_tex_loc = glGetUniformLocation(tex_p_id,"depth_texture");
      for(int pass = k-1;pass>=0;pass--)
      {
        glUniform1i(color_tex_loc, 0);
        glActiveTexture(GL_TEXTURE0 + 0);
        glBindTexture(GL_TEXTURE_2D, tex_id[pass]);
        glUniform1i(depth_tex_loc, 1);
        glActiveTexture(GL_TEXTURE0 + 1);
        glBindTexture(GL_TEXTURE_2D, dtex_id[pass]);
        glDrawElements(GL_TRIANGLES,6, GL_UNSIGNED_INT, 0);
      }
      glDepthFunc(GL_LESS);
      // Render scene using naive GL_BLEND transparency
      glUseProgram(scene_p_id);
      glBindVertexArray(VAO);
      glViewport((k+1)*w,0*h,w,h);
      glDrawElements(GL_TRIANGLES, F.size(), GL_UNSIGNED_INT, 0);
      glBindVertexArray(0);
      glDisable(GL_BLEND);

      glutSwapBuffers();
      glutPostRedisplay();
    }
    );
  glutReshapeFunc(
    [](int w,int h)
    {
      full_h=h;
      full_w=w;
      ::w=full_w/(k+2);
      ::h=full_h/(1);
      // (re)-initialize textures and buffers
      for(size_t i = 0;i<k;i++)
      {
        init_render_to_texture(::w,::h,tex_id[i],dtex_id[i],fbo_id[i]);
      }
    });
  glutMainLoop();
}

ext: cpp


text: #include <boost/qvm/all.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
/*
 * MIT License
 *
 * Copyright (c) 2017 Benjamin Zeller
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include <AtlasPack/TextureAtlasPacker>
#include <AtlasPack/textureatlas_p.h>
#include <AtlasPack/JobQueue>
#include <boost/filesystem.hpp>
#include <iostream>
#include <fstream>
#include <sstream>

namespace fs =  boost::filesystem;

namespace AtlasPack {

/**
 * \internal
 * Represents a Node in the packing tree algorithm,
 * can contain either child nodes or a image. The rect
 * variable is always set.
 */
struct Node {

    Node (Rect _rect = Rect())
        : rect(_rect){}

    std::shared_ptr<Node> left;
    std::shared_ptr<Node> right;

    Rect rect;
    Image img;
};

class TextureAtlasPackerPrivate {
    public:

    Node *insertImage (const Image &img, Node *node);
    bool collectNodes(TextureAtlasPrivate *atlas, std::shared_ptr<PaintDevice> painter, std::basic_ostream<char> *descStr,
                      Node *node, JobQueue<bool> *painterQueue, std::vector<std::future<bool> > &painterResults, std::string *err = nullptr);

    Node m_root;
};

/**
 * @brief TextureAtlasPrivate::insertImage
 * \returns the Node the Image was inserted into, nullptr if not enough space is available
 */
Node *TextureAtlasPackerPrivate::insertImage(const Image &img, Node *node)
{
    //if we have children, we are not a leaf
    if (node->left || node->right) {
        //first inside left:
        Node *newNode = insertImage(img, node->left.get());
        if (newNode)
            return newNode;

        //no space in left, insert right
        return insertImage(img, node->right.get());
    } else {
        //this path is entered if we found a leaf node

        //first check if the space is already filled
        if (node->img.isValid())
            return nullptr;

        Pos  nodePos  = node->rect.topLeft;
        Size nodeSize = node->rect.size;

        //check if there is enough room
        if (nodeSize.height < img.height()
                || nodeSize.width < img.width()) {
            //node too small
            return nullptr;
        }

        //check if we found a perfect fit
        if (nodeSize.height == img.height()
                && nodeSize.width == img.width()) {
            //perfect fit, store the image
            node->img = img;
            return node;
        }

        //At this poing the node is splitted up
        //we will split in a way that we always end up with the biggest possible
        //empty rectangle
        size_t remainWidth  = nodeSize.width - img.width();
        size_t remainHeight = nodeSize.height - img.height();

        if (remainWidth > remainHeight) {
            node->left  = std::make_shared<Node>(Rect(nodePos,
                                                      Size(img.width(), nodeSize.height)));

            node->right = std::make_shared<Node>(Rect(Pos(nodePos.x+img.width(), nodePos.y),
                                                      Size(nodeSize.width - img.width(), nodeSize.height)));
        } else {
            node->left  = std::make_shared<Node>(Rect(nodePos,
                                                      Size(nodeSize.width, img.height())));

            node->right = std::make_shared<Node>(Rect(Pos(nodePos.x, nodePos.y + img.height()),
                                                      Size(nodeSize.width, nodeSize.height - img.height())));
        }

        //now insert into leftmost Node
        return insertImage(img, node->left.get());
    }
}

/**
 * @internal
 * @brief TextureAtlasPackerPrivate::collectNodes
 * Iterates over the full tree, filling the \a atlas and painting the images using the \a painter as well as writing
 * the image rectangle and filenmame into the output stream given by \a descStr.
 * If a error occurs and \a err is set, a error message is put there.
 */
bool TextureAtlasPackerPrivate::collectNodes(TextureAtlasPrivate *atlas, std::shared_ptr<PaintDevice> painter,
                                             std::basic_ostream<char> *descStr, Node *node,
                                             JobQueue<bool> *painterQueue, std::vector<std::future<bool>> &painterResults,
                                             std::string *err)
{
    bool collected = false;
    if(node->img.isValid()) {
        collected = true;

        // we found a Image node, lets fill the information into the given structures
        Texture t(node->rect.topLeft, node->img);
        atlas->m_textures[node->img.path()] = t;

        // Renders the node into the atlas image, called from a async thread
        auto fun = [](std::shared_ptr<PaintDevice> painter, Node *node){
            // paint the texture into the cache image
            if(!painter->paintImageFromFile(node->rect.topLeft, node->img.path())) {
                std::cout<<"Failed to paint image "<<node->img.path();
                return false;
            }
            return true;
        };

        // push the future results into a vector, so we can check if we had errors after all tasks are done
        painterResults.push_back(painterQueue->addTask(std::bind(fun, painter, node)));

        // the description file is written as a CSV file
        // @NOTE possible room for improvement, make the description file structure modular,
        // to make it easy to use another format
        (*descStr) << node->img.path() <<","
                   << t.pos.x<<","
                   << t.pos.y<<","
                   << t.image.width()<<","
                   << t.image.height()<<"\n";

    }

    if (collected && (node->left || node->right )) {
        //this should never happen, if it does at least print a warning about it
        if(collected) std::cerr<<"Node has leafs AND image?"<<std::endl;
    }

    //recursively iterate through the child nodes, start with the left node again
    if(node->left) {
        if (!collectNodes(atlas, painter, descStr, node->left.get(), painterQueue, painterResults, err))
            return false;
    }

    if(node->right){
        if (!collectNodes(atlas, painter, descStr, node->right.get(), painterQueue, painterResults, err))
            return false;
    }

    return true;
}

/**
 * @class TextureAtlasPacker::TextureAtlasPacker
 * Implements a packing algorithm to pack images into a bigger texture, called
 * a \a AtlasPack::TextureAtlas. This can speed up image loading in applications that make use
 * of a lot of small image files.
 *
 * This implementation makes use of the lightmap packing algorithm that can be found at http://blackpawn.com/texts/lightmaps/default.html
 */

TextureAtlasPacker::TextureAtlasPacker(Size atlasSize)
    : p(new TextureAtlasPackerPrivate())
{
    p->m_root.rect = Rect(Pos(0,0), atlasSize);
}

TextureAtlasPacker::~TextureAtlasPacker()
{
    if (p) delete p;
}

/*!
 * \brief TextureAtlasPacker::size
 * Returns the current geometrical size of the texture atlas.
 */
Size TextureAtlasPacker::size() const
{
    return p->m_root.rect.size;
}

/*!
 * \brief TextureAtlasPacker::insertImage
 * Tried to insert the \sa AtlasPack::Image given by \a img into the atlas.
 * The internal algorithm will split the atlas rectangle into smaller portions
 * until the image fits.
 * Returns \a true on success, or \a false in case the atlas does not have enough remaining space.
 */
bool TextureAtlasPacker::insertImage(const Image &img)
{
    return p->insertImage(img, &p->m_root) != nullptr;
}

/**
 * \brief TextureAtlasPacker::compile
 * Compiles the current in memory state of the TextureAtlas into a description and
 * image file and stores them on disk. Expects \a basePath to point at a user writeable directory,
 * the last part of \a basePath will be used to form the texture atlas description file and image file names.
 *
 * \note This can take a lot of time for a big list of images, however the implementation does run with multiple
 *       threads to speed the process up.
 */
TextureAtlas TextureAtlasPacker::compile(const std::string &basePath, Backend *backend, std::string *error) const
{

    try {

        //the basepath is used to create the filenames for the 2 output files
        fs::path descFileName(basePath + ".atlas");
        fs::path textureFile(basePath + ".png");

        JobQueue<bool> jobs;

        //check if the output directory exists
        if (!fs::exists(descFileName.parent_path())
                || !fs::is_directory(descFileName.parent_path())) {
            if (error)
                *error = "Basepath is not a directory or does not exist";
            return TextureAtlas();
        }

        //create atlas description text file
        std::ofstream descFile(descFileName.string(), std::ios::trunc | std::ios::out);
        if(!descFile.is_open()) {
            if (error) {
                std::stringstream s;
                s << "Could not create atlas index file "<<descFileName.string()<<" "<<strerror(errno);
                *error = s.str();
            }
            return TextureAtlas();
        }

        //get new painter instance from the backend
        auto painter = backend->createPaintDevice(p->m_root.rect.size);

        std::unique_ptr<TextureAtlasPrivate> priv = std::make_unique<TextureAtlasPrivate>();
        std::vector<std::future<bool> > paintResults;

        //recursively collect all nodes, write them to the desc file and give paint tasks to the
        //JobQueue to run asynchronously
        if(!p->collectNodes(priv.get(), painter, &descFile, &p->m_root, &jobs, paintResults, error))
            return TextureAtlas();

        //wait until all painters are done
        jobs.waitForAllRunningTasks();

        //check if we have errors in some of the painters, no need
        //to print which one here, because the painters will print a error message on their
        //own if required
        for (std::future<bool> &res : paintResults) {
            if (!res.get()) {
                std::cout<<"Some images failed to paint";
                return TextureAtlas();
            }
        }

        //finally save the result to a file
        if(!painter->exportToFile(textureFile.string())) {
            if (error) *error = "Failed to export Texture to file";
            return TextureAtlas();
        }

        descFile.close();
        return TextureAtlas(priv.release());

    } catch (const fs::filesystem_error& ex) {
        std::cerr << "Filesystem error while compiling the texture atlas: "<<ex.what() << std::endl;
	}
	catch (const std::exception &ex) {
        std::cerr << "Catched an exception when compiling the texture atlas."<<ex.what()<< std::endl;
    }
	catch (...) {
		std::cerr << "Catched an unknown exception when compiling the texture atlas." << std::endl;
	}

    return TextureAtlas();
}

}

max_stars_repo_name: bzeller/atlaspack

max_issues_repo_name: bzeller/atlaspack

max_forks_repo_name: bzeller/atlaspack


text:
#include "nearest_neighbor_brute_force.h"
#include "point_AABBTree_squared_distance.h"
#include "CloudPoint.h"
#include "Object.h"
#include "AABBTree.h"
#include "warnings.h"
#include "VectorXb.h"
#include "tictoc.h"
#include "visualize_aabbtree.h"
#include <igl/read_triangle_mesh.h>
#include <Eigen/Core>
#include <iostream>
#include <string> // std::stoi
#include <iomanip> // std::setw
#include <memory> // std::shared_ptr

int main(int argc, char * argv[])
{
  /////////////////////////////////////////////////////////////////////////////
  // POINT CLOUD DISTANCE QUERY
  /////////////////////////////////////////////////////////////////////////////
  std::cout<<"# Point Cloud Distance Queries"<<std::endl;
  // Prepare a random list of points in our set and random queries
  Eigen::MatrixXd points =
    Eigen::MatrixXd::Random(argc>1?std::stoi(argv[1]):100000,3);
  Eigen::MatrixXd queries =
    Eigen::MatrixXd::Random(argc>2?std::stoi(argv[2]):10000,3);

  std::cout<<"    |points|: "<< points.rows()<<std::endl;
  std::cout<<"  |querires|: "<<queries.rows()<<std::endl<<std::endl;
  // Brute Force
  tic(); // Start the clock!
  Eigen::VectorXd bf_sqrD(queries.rows());
  Eigen::VectorXi bf_I   (queries.rows());
  // Loop over queries
  for(int i = 0;i < queries.rows(); i++)
  {
    nearest_neighbor_brute_force(points,queries.row(i),bf_I(i),bf_sqrD(i));
  }
  std::cout<<"  | Method      | Time in seconds |"<<std::endl;
  std::cout<<"  |:------------|----------------:|"<<std::endl;
  std::cout<<"  | brute force | " << FLOAT15 << toc() << " |"<<std::endl;

  tic();
  // Build a tree
  std::vector<std::shared_ptr<Object> > point_indices;
  // Put a reference to each point in a boxable object
  point_indices.reserve(points.rows());
  for(int i = 0;i<points.rows();i++)
  {
    point_indices.emplace_back(std::make_shared<CloudPoint>(points,i));
  }
  // Build tree
  std::shared_ptr<AABBTree> root = std::make_shared<AABBTree>(point_indices);
  std::cout<<"  | build tree  | " << FLOAT15 << toc() << " |"<<std::endl;

  tic();
  Eigen::VectorXd tree_sqrD(queries.rows());
  Eigen::VectorXi tree_I   (queries.rows());
  // Loop over queries
  for(int i = 0;i < queries.rows(); i++)
  {
    Eigen::RowVector3d query = queries.row(i);
    std::shared_ptr<Object> closest_object;
    const double inf = std::numeric_limits<double>::infinity();
    point_AABBTree_squared_distance(
      query,root,0,inf,tree_sqrD(i),closest_object);
    if(closest_object)
    {
      tree_I(i) = std::static_pointer_cast<CloudPoint>(closest_object)->i;
    }else
    {
      tree_I(i) = -1;
    }
  }
  std::cout<<"  | use tree    | " << FLOAT15 << toc() << " |"<<std::endl;

  // Check that solutions match.
  for(int i = 0;i < queries.rows(); i++)
  {
    WARN_IF_NOT_EQUAL(bf_I,tree_I,i);
    WARN_IF_NOT_APPROX(bf_sqrD,tree_sqrD,i);
  }
  visualize_aabbtree(points,root);

}


text:
#include <Eigen/Core>

#include <numpy_eigen/boost_python_headers.hpp>
Eigen::Matrix<boost::int64_t, 5, Eigen::Dynamic> test_long_5_D(const Eigen::Matrix<boost::int64_t, 5, Eigen::Dynamic> & M)
{
	return M;
}
void export_long_5_D()
{
	boost::python::def("test_long_5_D",test_long_5_D);
}

max_stars_repo_name: PushyamiKaveti/kalibr

max_issues_repo_name: PushyamiKaveti/kalibr

max_forks_repo_name: PushyamiKaveti/kalibr


text:
#define TAOJSON
#include "format.h"

#include <mutex>
using namespace std;
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
using namespace boost;
using namespace boost::filesystem;
#include "drumlin/jsonconfig.h"
using namespace drumlin;
#include "writer.h"
#include "log.h"
#include "pleg.h"
using namespace Pleg;

namespace Pleg {

namespace Files {

std::recursive_mutex files_mutex;

RecordedRange::RecordedRange(Relevance const&rel,posix_time::ptime _start)
    :relevance(rel),start(_start),step(posix_time::milliseconds(0)),finish(start),ticks(0)
{
    if(rel.getSource()){
        step = posix_time::milliseconds(rel.getSource()->getTau());
    }
}

RecordedRange::RecordedRange(RecordedRange &rhs)
    :relevance(rhs.relevance),start(rhs.start),step(rhs.step),finish(rhs.finish),ticks(rhs.ticks)
{

}

RecordedRange::RecordedRange(RecordedRange &&rhs)
    :relevance(rhs.relevance),start(rhs.start),step(rhs.step),finish(rhs.finish),ticks(rhs.ticks)
{

}

void RecordedRange::toJson(json::value *json)const
{
    json::object_t &obj(json->get_object());
    json::value rel(json::empty_object);
    relevance.toJson(&rel);
    obj.insert({"relevance",rel});
    obj.insert({"start",lexical_cast<string>(start)});
    obj.insert({"finish",lexical_cast<string>(finish)});
    obj.insert({"step",posix_time::to_simple_string(step)});
    obj.insert({"ticks",ticks});
}

bool operator ==(RecordedRange const& range,Relevance const& rel)
{
    return range.relevance == rel;
}

void Format::getStatus(json::value *status)const
{
    FILESLOCK;

    json::object_t &obj(status->get_object());

    json::value pat(json::empty_object);
    json::object_t &patterns(pat.get_object());
    for(Relevance const& rel : pattern){
        json::value _rel(json::empty_object);
        rel.toJson(&_rel);
        patterns.insert({rel.getSourceName(),_rel});
    }
    obj.insert({"pattern",pat});

    json::value cur(json::empty_object);
    json::object_t &working(cur.get_object());
    for(RecordedRange const* range : current_records){
        json::value _range(json::empty_object);
        range->toJson(&_range);
        working.insert({range->relevance.getSourceName(),_range});
    }
    obj.insert({"working",cur});
}

void Format::toJson(json::value *json)const
{
    FILESLOCK;

    json::object_t &obj(json->get_object());
    getStatus(json);

    json::value rec(json::empty_object);
    json::object_t &_records(rec.get_object());
    int i=0;
    for(RecordedRange const& range : records){
        json::value _range(json::empty_object);
        range.toJson(&_range);
        _records.insert({lexical_cast<string>(++i),_range});
    }
    obj.insert({"records",rec});
}

RecordedRange *Format::newRecord(const Buffers::Buffer *buffer)
{
    std::lock_guard<std::recursive_mutex> l(files_mutex);
    records.push_front(RecordedRange(buffer->getRelevanceRef(),buffer->getTimestampRef()));
    RecordedRange *range(&records.front());
    current_records.push_back(range);
    return range;
}

void Format::recordBuffer(const Buffers::Buffer *buffer)
{
    FILESLOCK;
    posix_time::ptime then(buffer->getTimestampRef());
    posix_time::ptime last;
    if(pattern.end()==std::find(pattern.begin(),pattern.end(),buffer->getRelevanceRef())){
        throw new Exception("Irrelevant buffer to record");
    } //TODO remove sanity check
    record_type::iterator record_it(std::find_if(records.begin(),records.end(),[buffer](RecordedRange const& range){
        return range == buffer->getRelevanceRef();
    }));
    RecordedRange *record;
    if(record_it == records.end()) {
        record = newRecord(buffer);
    }else{
        record = &(*record_it);
        last = record->finish;
        if(record->finish + record->step*2 < then){
            current_records.remove(record);
            record = newRecord(buffer);
        }
    }
    record->step = then - last;
    record->finish = then;
    record->ticks++;
}

} // namespace Files

} // namespace Pleg

max_stars_repo_name: cephalicmarble/pleg

max_issues_repo_name: cephalicmarble/pleg

max_forks_repo_name: cephalicmarble/pleg


text:
#ifdef ELLE_WINDOWS // Fix missing ::hypot.
# include <cmath>
#endif

#include <boost/python.hpp>

#include <elle/log/Logger.hh>
#include <elle/log/Send.hh>
#include <elle/log/SysLogger.hh>
#include <elle/log/TextLogger.hh>
#include <elle/memory.hh>

using boost::python::class_;
using boost::python::def;
using boost::python::enum_;

// Pacify -Wmissing-declarations
extern "C"
{
  PyObject* PyInit__log();
}

class TextLogger: public elle::log::TextLogger
{
public:
  TextLogger():
    elle::log::TextLogger(std::cerr)
  {}
};

static
void
set_logger(boost::python::object& object)
{
  elle::generic_unique_ptr<elle::log::Logger> logger(
    boost::python::extract<elle::log::Logger*>(object),
    [] (elle::log::Logger*)
    {
      /* The logger will be deleted by python itself upon exit */
    });
  boost::python::incref(object.ptr());
  elle::log::logger(std::move(logger));
}

class Send: public elle::log::detail::Send
{
public:
  Send(elle::log::Logger::Level level,
       elle::log::Logger::Type type,
       std::string const& component,
       std::string const& file,
       unsigned int line,
       std::string const& function,
       std::string const& message):
    elle::log::detail::Send(
      level,
      type,
      false,
      component,
      file.c_str(),
      line,
      function.c_str(),
      boost::algorithm::replace_all_copy(message, "%", "%%").c_str())
  {}

  void
  enter()
  {
    this->_indent();
  }

  void
  exit(boost::python::object const&,
       boost::python::object const&,
       boost::python::object const&)
  {
    this->_unindent();
  }
};

BOOST_PYTHON_MODULE(_log)
{
  enum_<elle::log::Logger::Level>("level")
    .value("none", elle::log::Logger::Level::none)
    .value("log", elle::log::Logger::Level::log)
    .value("trace", elle::log::Logger::Level::trace)
    .value("debug", elle::log::Logger::Level::debug)
    .value("dump", elle::log::Logger::Level::dump)
    ;
  enum_<elle::log::Logger::Type>("type")
    .value("info", elle::log::Logger::Type::info)
    .value("warning", elle::log::Logger::Type::warning)
    .value("error", elle::log::Logger::Type::error)
    ;
  class_<elle::log::Logger,
         boost::noncopyable>
    ("Logger", boost::python::no_init)
    //.def("message", &elle::log::Logger::message)
    ;
  class_<TextLogger,
         boost::python::bases<elle::log::Logger>,
         boost::noncopyable>
    ("TextLogger", boost::python::init<>())
    ;
  class_<elle::log::SysLogger,
         boost::python::bases<elle::log::Logger>,
         boost::noncopyable>
    ("SysLogger", boost::python::init<std::string const&>())
    ;
  def("set_logger", &set_logger);
  class_<Send,
         boost::noncopyable>
    ("Send", boost::python::init<
     elle::log::Logger::Level,
     elle::log::Logger::Type,
     std::string const&,
     std::string const&,
     unsigned int,
     std::string const&,
     std::string const&>())
    .def("__enter__", &Send::enter)
    .def("__exit__", &Send::exit)
    ;
}


text:
// Copyright 2022 PingCAP, Ltd.
//
// 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 <Common/TiFlashMetrics.h>
#include <Encryption/MockKeyManager.h>
#include <IO/ChecksumBuffer.h>
#include <Poco/Path.h>
#include <Server/DTTool/DTTool.h>
#include <Server/RaftConfigParser.h>
#include <Storages/DeltaMerge/DMChecksumConfig.h>
#include <Storages/DeltaMerge/DMContext.h>
#include <Storages/DeltaMerge/DeltaMergeStore.h>
#include <Storages/DeltaMerge/File/DMFile.h>
#include <Storages/DeltaMerge/File/DMFileBlockInputStream.h>
#include <Storages/DeltaMerge/File/DMFileBlockOutputStream.h>
#include <Storages/DeltaMerge/StoragePool.h>
#include <Storages/FormatVersion.h>
#include <Storages/PathPool.h>
#include <Storages/Transaction/TMTContext.h>
#include <pingcap/Config.h>

#include <boost/program_options.hpp>
#include <chrono>
#include <iostream>
#include <random>
#include <utility>
namespace bpo = boost::program_options;

namespace DTTool::Bench
{
// clang-format off
static constexpr char BENCH_HELP[] =
    "Usage: bench [args]\n"
    "Available Arguments:\n"
    "  --help        Print help message and exit.\n"
    "  --version     DTFile version. [default: 2] [available: 1, 2]\n"
    "  --algorithm   Checksum algorithm. [default: xxh3] [available: xxh3, city128, crc32, crc64, none]\n"
    "  --frame       Checksum frame length. [default: " TO_STRING(TIFLASH_DEFAULT_CHECKSUM_FRAME_SIZE) "]\n"
    "  --column      Column number. [default: 100]\n"
    "  --size        Column size.   [default: 1000]\n"
    "  --field       Field length limit. [default: 1024]\n"
    "  --random      Random seed. (optional)\n"
    "  --encryption  Enable encryption.\n"
    "  --repeat      Repeat times. [default: 5]\n"
    "  --workdir     Directory to create temporary data storage. [default: /tmp/test]";
// clang-format on

using namespace DB::DM;
using namespace DB;
std::unique_ptr<Context> global_context = nullptr;

ColumnDefinesPtr getDefaultColumns()
{
    // Return [handle, ver, del] column defines
    ColumnDefinesPtr columns = std::make_shared<ColumnDefines>();
    columns->emplace_back(getExtraHandleColumnDefine(/*is_common_handle=*/false));
    columns->emplace_back(getVersionColumnDefine());
    columns->emplace_back(getTagColumnDefine());
    return columns;
}

ColumnDefinesPtr createColumnDefines(size_t column_number)
{
    auto primitive = getDefaultColumns();
    auto int_num = column_number / 2;
    auto str_num = column_number - int_num;
    for (size_t i = 0; i < int_num; ++i)
    {
        primitive->emplace_back(
            ColumnDefine{static_cast<ColId>(3 + i), fmt::format("int_{}", i), DB::DataTypeFactory::instance().get("Int64")});
    }
    for (size_t i = 0; i < str_num; ++i)
    {
        primitive->emplace_back(
            ColumnDefine{static_cast<ColId>(3 + int_num + i), fmt::format("str_{}", i), DB::DataTypeFactory::instance().get("String")});
    }
    return primitive;
}

String createRandomString(std::size_t limit, std::mt19937_64 & eng, size_t & acc)
{
    std::uniform_int_distribution<char> dist('a', 'z');
    std::string buffer((eng() % limit) + 1, 0);
    for (auto & i : buffer)
    {
        i = dist(eng);
    }
    acc += buffer.size();
    return buffer;
}

DB::Block createBlock(size_t column_number, size_t start, size_t row_number, std::size_t limit, std::mt19937_64 & eng, size_t & acc)
{
    using namespace DB;
    auto int_num = column_number / 2;
    auto str_num = column_number - int_num;
    Block block;
    //PK
    {
        ColumnWithTypeAndName pk_col(nullptr, EXTRA_HANDLE_COLUMN_INT_TYPE, "id", EXTRA_HANDLE_COLUMN_ID);
        IColumn::MutablePtr m_col = pk_col.type->createColumn();
        for (size_t i = 0; i < row_number; i++)
        {
            Field field = static_cast<DB::Int64>(start + i);
            m_col->insert(field);
            acc += 8;
        }
        pk_col.column = std::move(m_col);
        block.insert(std::move(pk_col));
    }
    // Version
    {
        ColumnWithTypeAndName version_col({}, VERSION_COLUMN_TYPE, VERSION_COLUMN_NAME, VERSION_COLUMN_ID);
        IColumn::MutablePtr m_col = version_col.type->createColumn();
        for (size_t i = 0; i < row_number; ++i)
        {
            Field field = static_cast<DB::UInt64>((start + i) * 10);
            m_col->insert(field);
            acc += 8;
        }
        version_col.column = std::move(m_col);
        block.insert(std::move(version_col));
    }

    //Tag
    {
        ColumnWithTypeAndName tag_col(nullptr, TAG_COLUMN_TYPE, TAG_COLUMN_NAME, TAG_COLUMN_ID);
        IColumn::MutablePtr m_col = tag_col.type->createColumn();
        auto & column_data = typeid_cast<ColumnVector<UInt8> &>(*m_col).getData();
        column_data.resize(row_number);
        for (size_t i = 0; i < row_number; ++i)
        {
            column_data[i] = eng() & 1;
            acc += 1;
        }
        tag_col.column = std::move(m_col);
        block.insert(std::move(tag_col));
    }

    std::uniform_int_distribution<Int64> dist;
    for (size_t i = 0; i < int_num; ++i)
    {
        ColumnWithTypeAndName int_col(
            nullptr,
            DB::DataTypeFactory::instance().get("Int64"),
            fmt::format("int_{}", i),
            static_cast<ColId>(3 + i));
        IColumn::MutablePtr m_col = int_col.type->createColumn();
        auto & column_data = typeid_cast<ColumnVector<Int64> &>(*m_col).getData();
        column_data.resize(row_number);
        for (size_t j = 0; j < row_number; ++j)
        {
            column_data[j] = dist(eng);
            acc += 8;
        }
        int_col.column = std::move(m_col);
        block.insert(std::move(int_col));
    }

    for (size_t i = 0; i < str_num; ++i)
    {
        ColumnWithTypeAndName str_col(
            nullptr,
            DB::DataTypeFactory::instance().get("String"),
            fmt::format("str_{}", i),
            static_cast<ColId>(3 + int_num + i));
        IColumn::MutablePtr m_col = str_col.type->createColumn();
        for (size_t j = 0; j < row_number; j++)
        {
            Field field = createRandomString(limit, eng, acc);
            m_col->insert(field);
        }
        str_col.column = std::move(m_col);
        block.insert(std::move(str_col));
    }

    return block;
}

int benchEntry(const std::vector<std::string> & opts)
{
    bpo::options_description options{"Delta Merge IO Bench"};
    bpo::variables_map vm;
    bpo::positional_options_description positional;
    bool encryption;
    // clang-format off
    options.add_options()
        ("help", "show help")
        ("version", bpo::value<size_t>()->default_value(2))
        ("algorithm", bpo::value<std::string>()->default_value("xxh3"))
        ("frame", bpo::value<size_t>()->default_value(TIFLASH_DEFAULT_CHECKSUM_FRAME_SIZE))
        ("column", bpo::value<size_t>()->default_value(100))
        ("size", bpo::value<size_t>()->default_value(1000))
        ("field", bpo::value<size_t>()->default_value(1024))
        ("random", bpo::value<size_t>())
        ("repeat", bpo::value<size_t>()->default_value(5))
        ("encryption", bpo::bool_switch(&encryption))
        ("workdir", bpo::value<String>()->default_value("/tmp"));
    // clang-format on

    bpo::store(bpo::command_line_parser(opts)
                   .options(options)
                   .style(bpo::command_line_style::unix_style | bpo::command_line_style::allow_long_disguise)
                   .run(),
               vm);

    bpo::notify(vm);

    if (vm.count("help") != 0)
    {
        std::cout << BENCH_HELP << std::endl;
        return 0;
    }

    try
    {
        auto version = vm["version"].as<size_t>();
        if (version < 1 || version > 2)
        {
            std::cerr << "invalid dtfile version: " << version << std::endl;
            return -EINVAL;
        }
        auto algorithm_config = vm["algorithm"].as<std::string>();
        DB::ChecksumAlgo algorithm;
        if (algorithm_config == "xxh3")
        {
            algorithm = DB::ChecksumAlgo::XXH3;
        }
        else if (algorithm_config == "crc32")
        {
            algorithm = DB::ChecksumAlgo::CRC32;
        }
        else if (algorithm_config == "crc64")
        {
            algorithm = DB::ChecksumAlgo::CRC64;
        }
        else if (algorithm_config == "city128")
        {
            algorithm = DB::ChecksumAlgo::City128;
        }
        else if (algorithm_config == "none")
        {
            algorithm = DB::ChecksumAlgo::None;
        }
        else
        {
            std::cerr << "invalid algorithm: " << algorithm_config << std::endl;
            return -EINVAL;
        }
        auto frame = vm["frame"].as<size_t>();
        auto column = vm["column"].as<size_t>();
        auto size = vm["size"].as<size_t>();
        auto field = vm["field"].as<size_t>();
        auto repeat = vm["repeat"].as<size_t>();
        size_t random;
        if (vm.count("random"))
        {
            random = vm["random"].as<size_t>();
        }
        else
        {
            random = std::random_device{}();
        }
        auto workdir = vm["workdir"].as<std::string>() + "/.tmp";
        auto env = detail::ImitativeEnv{workdir, encryption};
        // env is up, use logger from now on
        SCOPE_EXIT({
            if (Poco::File file(workdir); file.exists())
            {
                file.remove(true);
            }
        });
        static constexpr char SUMMARY_TEMPLATE_V1[] = "version:    {}\n"
                                                      "column:     {}\n"
                                                      "size:       {}\n"
                                                      "field:      {}\n"
                                                      "random:     {}\n"
                                                      "encryption: {}\n"
                                                      "workdir:    {}";

        static constexpr char SUMMARY_TEMPLATE_V2[] = "version:    {}\n"
                                                      "column:     {}\n"
                                                      "size:       {}\n"
                                                      "field:      {}\n"
                                                      "random:     {}\n"
                                                      "workdir:    {}\n"
                                                      "frame:      {}\n"
                                                      "encryption: {}\n"
                                                      "algorithm:  {}";
        DB::DM::DMConfigurationOpt opt = std::nullopt;
        auto * logger = &Poco::Logger::get("DTTool::Bench");
        if (version == 1)
        {
            LOG_FMT_INFO(logger, SUMMARY_TEMPLATE_V1, version, column, size, field, random, encryption, workdir);
            DB::STORAGE_FORMAT_CURRENT = DB::STORAGE_FORMAT_V2;
        }
        else
        {
            LOG_FMT_INFO(logger, SUMMARY_TEMPLATE_V2, version, column, size, field, random, workdir, frame, encryption, algorithm_config);
            opt.emplace(std::map<std::string, std::string>{}, frame, algorithm);
            DB::STORAGE_FORMAT_CURRENT = DB::STORAGE_FORMAT_V3;
        }

        // start initialization
        size_t effective_size = 0;
        auto engine = std::mt19937_64{random};
        auto defines = DTTool::Bench::createColumnDefines(column);
        std::vector<DB::Block> blocks;
        std::vector<DB::DM::DMFileBlockOutputStream::BlockProperty> properties;
        for (size_t i = 0, count = 1; i < size; count++)
        {
            auto block_size = engine() % (size - i) + 1;
            LOG_FMT_INFO(logger, "generating block with size: {}", block_size);
            blocks.push_back(DTTool::Bench::createBlock(column, i, block_size, field, engine, effective_size));
            i += block_size;
            DB::DM::DMFileBlockOutputStream::BlockProperty property{};
            property.gc_hint_version = count;
            property.effective_num_rows = block_size;
            properties.push_back(property);
        }
        LOG_FMT_INFO(logger, "effective_size: {}", effective_size);
        LOG_FMT_INFO(logger, "start writing");
        size_t write_records = 0;
        auto settings = DB::Settings();
        auto db_context = env.getContext();
        auto path_pool = std::make_unique<DB::StoragePathPool>(db_context->getPathPool().withTable("test", "t1", false));
        auto storage_pool = std::make_unique<DB::DM::StoragePool>("test.t1", /*table_id*/ 1, *path_pool, *db_context, db_context->getSettingsRef());
        auto dm_settings = DB::DM::DeltaMergeStore::Settings{};
        auto dm_context = std::make_unique<DB::DM::DMContext>( //
            *db_context,
            *path_pool,
            *storage_pool,
            /*hash_salt*/ 0,
            0,
            dm_settings.not_compress_columns,
            false,
            1,
            db_context->getSettingsRef());
        DB::DM::DMFilePtr dmfile = nullptr;

        // Write
        for (size_t i = 0; i < repeat; ++i)
        {
            using namespace std::chrono;
            dmfile = DB::DM::DMFile::create(1, workdir, false, opt);
            auto start = high_resolution_clock::now();
            {
                auto stream = DB::DM::DMFileBlockOutputStream(*db_context, dmfile, *defines);
                stream.writePrefix();
                for (size_t j = 0; j < blocks.size(); ++j)
                {
                    stream.write(blocks[j], properties[j]);
                }
                stream.writeSuffix();
            }
            auto end = high_resolution_clock::now();
            auto duration = duration_cast<nanoseconds>(end - start).count();
            write_records += duration;
            LOG_FMT_INFO(logger, "attemp {} finished in {} ns", i, duration);
        }

        LOG_FMT_INFO(logger, "average write time: {} ns", (static_cast<double>(write_records) / static_cast<double>(repeat)));
        LOG_FMT_INFO(
            logger,
            "throughput (MB/s): {}",
            (static_cast<double>(effective_size) * 1'000'000'000 * static_cast<double>(repeat) / static_cast<double>(write_records) / 1024 / 1024));

        // Read
        LOG_FMT_INFO(logger, "start reading");
        size_t read_records = 0;
        for (size_t i = 0; i < repeat; ++i)
        {
            using namespace std::chrono;

            auto start = high_resolution_clock::now();
            {
                auto builder = DB::DM::DMFileBlockInputStreamBuilder(*db_context);
                auto stream = builder.setColumnCache(std::make_shared<DB::DM::ColumnCache>()).build(dmfile, *defines, {DB::DM::RowKeyRange::newAll(false, 1)});
                for (size_t j = 0; j < blocks.size(); ++j)
                {
                    TIFLASH_NO_OPTIMIZE(stream->read());
                }
                stream->readSuffix();
            }
            auto end = high_resolution_clock::now();
            auto duration = duration_cast<nanoseconds>(end - start).count();
            read_records += duration;
            LOG_FMT_INFO(logger, "attemp {} finished in {} ns", i, duration);
        }

        LOG_FMT_INFO(logger, "average read time: {} ns", (static_cast<double>(read_records) / static_cast<double>(repeat)));
        LOG_FMT_INFO(
            logger,
            "throughput (MB/s): {}",
            (static_cast<double>(effective_size) * 1'000'000'000 * static_cast<double>(repeat) / static_cast<double>(read_records) / 1024 / 1024));
    }
    catch (const boost::wrapexcept<boost::bad_any_cast> & e)
    {
        std::cerr << BENCH_HELP << std::endl; // no env available here
        return -EINVAL;
    }

    return 0;
}

} // namespace DTTool::Bench

max_stars_repo_name: solotzg/tiflash

max_issues_repo_name: solotzg/tiflash

max_forks_repo_name: solotzg/tiflash