<commit_before>#pragma once

#include <unordered_map>
#include <memory>
#include <type_traits>
#include <tuple>

namespace kgr {

template<typename... Types>
struct Dependency {
	using DependenciesTypes = std::tuple<Types...>;
};

using NoDependencies = Dependency<>;

struct Single {
	using ParentTypes = std::tuple<>;
};

template<typename T>
struct Service;

template<typename... Types>
struct Overrides : Single {
	using ParentTypes = std::tuple<Types...>;
};

namespace detail {

template<int ...>
struct seq { };

template<int N, int ...S>
struct seq_gen : seq_gen<N-1, N-1, S...> { };

template<int ...S>
struct seq_gen<0, S...> {
	using type = seq<S...>;
};

struct Holder {
	virtual ~Holder() {

	}
};

template<typename T>
struct InstanceHolder : Holder {
	InstanceHolder(std::shared_ptr<T> instance) : _instance{instance} {}

	std::shared_ptr<T> getInstance() const {
		return _instance;
	}

private:
	std::shared_ptr<T> _instance;
};

template<typename T, typename... Args>
struct CallbackHolder : Holder {
	CallbackHolder(std::function<std::shared_ptr<T>(Args...)> callback) : _callback{callback} {}

	std::function<std::shared_ptr<T>(Args...)> getCallback() const {
		return _callback;
	}

private:
	std::function<std::shared_ptr<T>(Args...)> _callback;
};

}

struct Container : std::enable_shared_from_this<Container> {
	template<typename T>
	void instance(std::shared_ptr<T> service) {
		static_assert(std::is_base_of<Single, Service<T>>::value, "instance only accept Single Service instance.");
		call_save_instance(service, typename detail::seq_gen<std::tuple_size<typename Service<T>::ParentTypes>::value>::type());
	}

	template<typename T>
	void instance() {
		static_assert(std::is_base_of<Single, Service<T>>::value, "instance only accept Single Service instance.");
		auto dependencies = dependency<typename Service<T>::DependenciesTypes>(typename detail::seq_gen<std::tuple_size<typename Service<T>::DependenciesTypes>::value>::type());
		auto service = make_service<T>(typename detail::seq_gen<std::tuple_size<typename Service<T>::DependenciesTypes>::value>::type(), dependencies);
		call_save_instance(service, typename detail::seq_gen<std::tuple_size<typename Service<T>::ParentTypes>::value>::type());
	}

	template<typename T>
	typename std::enable_if<(!std::is_abstract<T>::value && !std::is_base_of<Container, T>::value), std::shared_ptr<T>>::type service() {
		return get_service<T>();
	}

	template<typename T>
	typename std::enable_if<(std::is_same<T, Container>::value), std::shared_ptr<T>>::type service() {
		return shared_from_this();
	}

	template<typename T>
	typename std::enable_if<(std::is_base_of<Container, T>::value && !std::is_same<T, Container>::value), std::shared_ptr<T>>::type service() {
		auto service = std::dynamic_pointer_cast<T>(shared_from_this());
		if (service) {
			return service;
		} else {
			return nullptr;
		}
	}

	template<typename T>
	typename std::enable_if<std::is_abstract<T>::value, std::shared_ptr<T>>::type service() {
		auto it = _services.find(typeid(T).name());
		if (it != _services.end()) {
			auto holder = dynamic_cast<detail::InstanceHolder<T>*>(it->second.get());
			if (holder) {
				return holder->getInstance();
			}
		}
		return nullptr;
	}

	template<typename T, typename U>
	void callback(U callback) {
		static_assert(!std::is_base_of<Single, Service<T>>::value, "instance does not accept Single Service.");
		save_callback<T, typename Service<T>::DependenciesTypes>(typename detail::seq_gen<std::tuple_size<typename Service<T>::DependenciesTypes>::value>::type(), callback);
	}

	virtual void init(){}

private:
	template<typename T>
	typename std::enable_if<std::is_base_of<Single, Service<T>>::value, std::shared_ptr<T>>::type get_service() {
		auto it = _services.find(typeid(T).name());
		if (it == _services.end()) {
			auto dependencies = dependency<typename Service<T>::DependenciesTypes>(typename detail::seq_gen<std::tuple_size<typename Service<T>::DependenciesTypes>::value>::type());
			auto service = make_service<T, decltype(dependencies)>(typename detail::seq_gen<std::tuple_size<typename Service<T>::DependenciesTypes>::value>::type(), dependencies);
			call_save_instance(service, typename detail::seq_gen<std::tuple_size<typename Service<T>::ParentTypes>::value>::type());
			return service;
		} else {
			auto holder = dynamic_cast<detail::InstanceHolder<T>*>(it->second.get());
			if (holder) {
				return holder->getInstance();
			} else {
				return nullptr;
			}
		}
	}

	template<typename T>
	typename std::enable_if<!std::is_base_of<Single, Service<T>>::value, std::shared_ptr<T>>::type get_service() {
		auto dependencies = dependency<typename Service<T>::DependenciesTypes>(typename detail::seq_gen<std::tuple_size<typename Service<T>::DependenciesTypes>::value>::type());
		auto service = make_service<T, decltype(dependencies)>(typename detail::seq_gen<std::tuple_size<typename Service<T>::DependenciesTypes>::value>::type(), dependencies);

		return service;
	}

	template<typename T, int ...S>
	void call_save_instance(std::shared_ptr<T> service, detail::seq<S...>) {
		save_instance<T, typename std::tuple_element<S, typename Service<T>::ParentTypes>::type...>(service);
	}

	template<typename Tuple, int ...S>
	std::tuple<std::shared_ptr<typename std::tuple_element<S, Tuple>::type>...> dependency(detail::seq<S...>) {
		return std::make_tuple(service<typename std::tuple_element<S, Tuple>::type>()...);
	}

	template<typename T, typename Tuple, int ...S>
	std::shared_ptr<T> callback_make_service(detail::seq<S...> seq, Tuple dependencies) const {
		auto it = _callbacks.find(typeid(T).name());
		if (it != _callbacks.end()) {
			auto holder = dynamic_cast<detail::CallbackHolder<T, typename std::tuple_element<S, Tuple>::type...>*>(it->second.get());
			if (holder) {
				return holder->getCallback()(std::get<S>(dependencies)...);
			}
		}
		return nullptr;
	}

	template<typename T, typename Tuple, int ...S>
	std::shared_ptr<T> make_service(detail::seq<S...> seq, Tuple dependencies) const {
		auto service = callback_make_service<T, Tuple>(seq, dependencies);
		if (service) {
			return service;
		}
		return std::make_shared<T>(std::get<S>(dependencies)...);
	}

	template<typename T, typename ...Others>
	typename std::enable_if<(sizeof...(Others) > 0), void>::type save_instance(std::shared_ptr<T> service) {
		save_instance<T>(service);
		save_instance<Others...>(service);
	}

	template<typename T>
	void save_instance (std::shared_ptr<T> service) {
		_services[typeid(T).name()] = std::unique_ptr<detail::InstanceHolder<T>>(new detail::InstanceHolder<T>(service));
	}

	template<typename T, typename Tuple, int ...S, typename U>
	void save_callback (detail::seq<S...>, U callback) {
		_callbacks[typeid(T).name()] = std::unique_ptr<detail::CallbackHolder<T, std::shared_ptr<typename std::tuple_element<S, Tuple>::type>...>>(new detail::CallbackHolder<T, std::shared_ptr<typename std::tuple_element<S, Tuple>::type>...>(callback));
	}

	std::unordered_map<std::string, std::unique_ptr<detail::Holder>> _callbacks;
	std::unordered_map<std::string, std::unique_ptr<detail::Holder>> _services;
};

template<typename T = Container, typename ...Args>
std::shared_ptr<T> make_container(Args&& ...args) {
	static_assert(std::is_base_of<Container, T>::value, "make_container only accept container types.");
	auto container = std::make_shared<T>(std::forward<Args>(args)...);
	container->init();
	return container;
}

}
<commit_msg>Add comments to namespace ends<commit_after>#pragma once

#include <unordered_map>
#include <memory>
#include <type_traits>
#include <tuple>

namespace kgr {

template<typename... Types>
struct Dependency {
	using DependenciesTypes = std::tuple<Types...>;
};

using NoDependencies = Dependency<>;

struct Single {
	using ParentTypes = std::tuple<>;
};

template<typename T>
struct Service;

template<typename... Types>
struct Overrides : Single {
	using ParentTypes = std::tuple<Types...>;
};

namespace detail {

template<int ...>
struct seq { };

template<int N, int ...S>
struct seq_gen : seq_gen<N-1, N-1, S...> { };

template<int ...S>
struct seq_gen<0, S...> {
	using type = seq<S...>;
};

struct Holder {
	virtual ~Holder() {

	}
};

template<typename T>
struct InstanceHolder : Holder {
	InstanceHolder(std::shared_ptr<T> instance) : _instance{instance} {}

	std::shared_ptr<T> getInstance() const {
		return _instance;
	}

private:
	std::shared_ptr<T> _instance;
};

template<typename T, typename... Args>
struct CallbackHolder : Holder {
	CallbackHolder(std::function<std::shared_ptr<T>(Args...)> callback) : _callback{callback} {}

	std::function<std::shared_ptr<T>(Args...)> getCallback() const {
		return _callback;
	}

private:
	std::function<std::shared_ptr<T>(Args...)> _callback;
};

}  // namespace detail

struct Container : std::enable_shared_from_this<Container> {
	template<typename T>
	void instance(std::shared_ptr<T> service) {
		static_assert(std::is_base_of<Single, Service<T>>::value, "instance only accept Single Service instance.");
		call_save_instance(service, typename detail::seq_gen<std::tuple_size<typename Service<T>::ParentTypes>::value>::type());
	}

	template<typename T>
	void instance() {
		static_assert(std::is_base_of<Single, Service<T>>::value, "instance only accept Single Service instance.");
		auto dependencies = dependency<typename Service<T>::DependenciesTypes>(typename detail::seq_gen<std::tuple_size<typename Service<T>::DependenciesTypes>::value>::type());
		auto service = make_service<T>(typename detail::seq_gen<std::tuple_size<typename Service<T>::DependenciesTypes>::value>::type(), dependencies);
		call_save_instance(service, typename detail::seq_gen<std::tuple_size<typename Service<T>::ParentTypes>::value>::type());
	}

	template<typename T>
	typename std::enable_if<(!std::is_abstract<T>::value && !std::is_base_of<Container, T>::value), std::shared_ptr<T>>::type service() {
		return get_service<T>();
	}

	template<typename T>
	typename std::enable_if<(std::is_same<T, Container>::value), std::shared_ptr<T>>::type service() {
		return shared_from_this();
	}

	template<typename T>
	typename std::enable_if<(std::is_base_of<Container, T>::value && !std::is_same<T, Container>::value), std::shared_ptr<T>>::type service() {
		auto service = std::dynamic_pointer_cast<T>(shared_from_this());
		if (service) {
			return service;
		} else {
			return nullptr;
		}
	}

	template<typename T>
	typename std::enable_if<std::is_abstract<T>::value, std::shared_ptr<T>>::type service() {
		auto it = _services.find(typeid(T).name());
		if (it != _services.end()) {
			auto holder = dynamic_cast<detail::InstanceHolder<T>*>(it->second.get());
			if (holder) {
				return holder->getInstance();
			}
		}
		return nullptr;
	}

	template<typename T, typename U>
	void callback(U callback) {
		static_assert(!std::is_base_of<Single, Service<T>>::value, "instance does not accept Single Service.");
		save_callback<T, typename Service<T>::DependenciesTypes>(typename detail::seq_gen<std::tuple_size<typename Service<T>::DependenciesTypes>::value>::type(), callback);
	}

	virtual void init(){}

private:
	template<typename T>
	typename std::enable_if<std::is_base_of<Single, Service<T>>::value, std::shared_ptr<T>>::type get_service() {
		auto it = _services.find(typeid(T).name());
		if (it == _services.end()) {
			auto dependencies = dependency<typename Service<T>::DependenciesTypes>(typename detail::seq_gen<std::tuple_size<typename Service<T>::DependenciesTypes>::value>::type());
			auto service = make_service<T, decltype(dependencies)>(typename detail::seq_gen<std::tuple_size<typename Service<T>::DependenciesTypes>::value>::type(), dependencies);
			call_save_instance(service, typename detail::seq_gen<std::tuple_size<typename Service<T>::ParentTypes>::value>::type());
			return service;
		} else {
			auto holder = dynamic_cast<detail::InstanceHolder<T>*>(it->second.get());
			if (holder) {
				return holder->getInstance();
			} else {
				return nullptr;
			}
		}
	}

	template<typename T>
	typename std::enable_if<!std::is_base_of<Single, Service<T>>::value, std::shared_ptr<T>>::type get_service() {
		auto dependencies = dependency<typename Service<T>::DependenciesTypes>(typename detail::seq_gen<std::tuple_size<typename Service<T>::DependenciesTypes>::value>::type());
		auto service = make_service<T, decltype(dependencies)>(typename detail::seq_gen<std::tuple_size<typename Service<T>::DependenciesTypes>::value>::type(), dependencies);

		return service;
	}

	template<typename T, int ...S>
	void call_save_instance(std::shared_ptr<T> service, detail::seq<S...>) {
		save_instance<T, typename std::tuple_element<S, typename Service<T>::ParentTypes>::type...>(service);
	}

	template<typename Tuple, int ...S>
	std::tuple<std::shared_ptr<typename std::tuple_element<S, Tuple>::type>...> dependency(detail::seq<S...>) {
		return std::make_tuple(service<typename std::tuple_element<S, Tuple>::type>()...);
	}

	template<typename T, typename Tuple, int ...S>
	std::shared_ptr<T> callback_make_service(detail::seq<S...> seq, Tuple dependencies) const {
		auto it = _callbacks.find(typeid(T).name());
		if (it != _callbacks.end()) {
			auto holder = dynamic_cast<detail::CallbackHolder<T, typename std::tuple_element<S, Tuple>::type...>*>(it->second.get());
			if (holder) {
				return holder->getCallback()(std::get<S>(dependencies)...);
			}
		}
		return nullptr;
	}

	template<typename T, typename Tuple, int ...S>
	std::shared_ptr<T> make_service(detail::seq<S...> seq, Tuple dependencies) const {
		auto service = callback_make_service<T, Tuple>(seq, dependencies);
		if (service) {
			return service;
		}
		return std::make_shared<T>(std::get<S>(dependencies)...);
	}

	template<typename T, typename ...Others>
	typename std::enable_if<(sizeof...(Others) > 0), void>::type save_instance(std::shared_ptr<T> service) {
		save_instance<T>(service);
		save_instance<Others...>(service);
	}

	template<typename T>
	void save_instance (std::shared_ptr<T> service) {
		_services[typeid(T).name()] = std::unique_ptr<detail::InstanceHolder<T>>(new detail::InstanceHolder<T>(service));
	}

	template<typename T, typename Tuple, int ...S, typename U>
	void save_callback (detail::seq<S...>, U callback) {
		_callbacks[typeid(T).name()] = std::unique_ptr<detail::CallbackHolder<T, std::shared_ptr<typename std::tuple_element<S, Tuple>::type>...>>(new detail::CallbackHolder<T, std::shared_ptr<typename std::tuple_element<S, Tuple>::type>...>(callback));
	}

	std::unordered_map<std::string, std::unique_ptr<detail::Holder>> _callbacks;
	std::unordered_map<std::string, std::unique_ptr<detail::Holder>> _services;
};

template<typename T = Container, typename ...Args>
std::shared_ptr<T> make_container(Args&& ...args) {
	static_assert(std::is_base_of<Container, T>::value, "make_container only accept container types.");
	auto container = std::make_shared<T>(std::forward<Args>(args)...);
	container->init();
	return container;
}

}  // namespace kgr

<|endoftext|>


<commit_before>#include "Window.h"
#include <iostream>

// Initializes the SDL window
bool Window::init(int width, int height)
{
    // init SDL
    SDL_Init(SDL_INIT_VIDEO);
    window = SDL_CreateWindow("Brick Breaker", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, 0);
    renderer = SDL_CreateRenderer(window, -1, 0);
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);

    return true;
}

void Window::cleanupAndExit()
{
    for (auto texture : textures)
        SDL_DestroyTexture(texture);

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

void Window::gameLoop()
{
    // TODO: move these out of here
    int xPos = 288;
    int yPos = 450;
    SDL_Texture* paddleTexture = loadTexture("paddle.bmp");
    bool moveLeft = false;
    bool moveRight = false;

    while (!quit)
    {
        // 10ms is an arbitrary value. Increasing the value will make the loop execute less often.
        SDL_Delay(10);
        SDL_PollEvent(&event);

        switch (event.type)
        {
            // if user clicks the red X
            case SDL_QUIT:
                quit = true;
                break;

            case SDL_KEYDOWN:
                switch (event.key.keysym.sym)
                {
                    case SDLK_LEFT:
                        moveLeft = true;
                        break;
                    case SDLK_RIGHT:
                        moveRight = true;
                        break;
                }
                break;

            case SDL_KEYUP:
                switch (event.key.keysym.sym)
                {
                case SDLK_LEFT:
                    moveLeft = false;
                    break;
                case SDLK_RIGHT:
                    moveRight = false;
                    break;
                }
                break;
        }

        if (moveLeft)
            xPos--;
        if (moveRight)
            xPos++;

        SDL_RenderClear(renderer);
        renderTexture(paddleTexture, xPos, yPos);
        SDL_RenderPresent(renderer);
    }
}

SDL_Texture* Window::loadTexture(const std::string& file)
{
    SDL_Texture* texture = NULL;
    SDL_Surface* img = SDL_LoadBMP(file.c_str());

    // if the texture fails to load
    if (!img)
    {
        std::cout << "Window::loadTexture error: " << SDL_GetError() << std::endl;
        return NULL;
    }

    texture = SDL_CreateTextureFromSurface(renderer, img);
    SDL_FreeSurface(img);

    if (!texture)
    {
        std::cout << "Window::loadTexture error: " << SDL_GetError() << std::endl;
        return NULL;
    }

    // keep track of each texture we have loaded so we can remove them when we're done
    textures.push_back(texture);
    return texture;
}

void Window::renderTexture(SDL_Texture* texture, int xPos, int yPos)
{
    SDL_Rect destination;
    destination.x = xPos;
    destination.y = yPos;

    // queries the texture and places its width and height into w and h in destination
    SDL_QueryTexture(texture, NULL, NULL, &destination.w, &destination.h);

    // actually renders the texture to the screen
    SDL_RenderCopy(renderer, texture, NULL, &destination);
}
<commit_msg>Makes paddle appear in the top let corner<commit_after>#include "Window.h"
#include <iostream>

// Initializes the SDL window
bool Window::init(int width, int height)
{
    // init SDL
    SDL_Init(SDL_INIT_VIDEO);
    window = SDL_CreateWindow("Brick Breaker", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, 0);
    renderer = SDL_CreateRenderer(window, -1, 0);
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);

    return true;
}

void Window::cleanupAndExit()
{
    for (auto texture : textures)
        SDL_DestroyTexture(texture);

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

void Window::gameLoop()
{
    // TODO: move these out of here
    int xPos = 0;
    int yPos = 0;
    SDL_Texture* paddleTexture = loadTexture("paddle.bmp");
    bool moveLeft = false;
    bool moveRight = false;

    while (!quit)
    {
        // 10ms is an arbitrary value. Increasing the value will make the loop execute less often.
        SDL_Delay(10);
        SDL_PollEvent(&event);

        switch (event.type)
        {
            // if user clicks the red X
            case SDL_QUIT:
                quit = true;
                break;

            case SDL_KEYDOWN:
                switch (event.key.keysym.sym)
                {
                    case SDLK_LEFT:
                        moveLeft = true;
                        break;
                    case SDLK_RIGHT:
                        moveRight = true;
                        break;
                }
                break;

            case SDL_KEYUP:
                switch (event.key.keysym.sym)
                {
                case SDLK_LEFT:
                    moveLeft = false;
                    break;
                case SDLK_RIGHT:
                    moveRight = false;
                    break;
                }
                break;
        }

        if (moveLeft)
            xPos--;
        if (moveRight)
            xPos++;

        SDL_RenderClear(renderer);
        renderTexture(paddleTexture, xPos, yPos);
        SDL_RenderPresent(renderer);
    }
}

SDL_Texture* Window::loadTexture(const std::string& file)
{
    SDL_Texture* texture = NULL;
    SDL_Surface* img = SDL_LoadBMP(file.c_str());

    // if the texture fails to load
    if (!img)
    {
        std::cout << "Window::loadTexture error: " << SDL_GetError() << std::endl;
        return NULL;
    }

    texture = SDL_CreateTextureFromSurface(renderer, img);
    SDL_FreeSurface(img);

    if (!texture)
    {
        std::cout << "Window::loadTexture error: " << SDL_GetError() << std::endl;
        return NULL;
    }

    // keep track of each texture we have loaded so we can remove them when we're done
    textures.push_back(texture);
    return texture;
}

void Window::renderTexture(SDL_Texture* texture, int xPos, int yPos)
{
    SDL_Rect destination;
    destination.x = xPos;
    destination.y = yPos;

    // queries the texture and places its width and height into w and h in destination
    SDL_QueryTexture(texture, NULL, NULL, &destination.w, &destination.h);

    // actually renders the texture to the screen
    SDL_RenderCopy(renderer, texture, NULL, &destination);
}
<|endoftext|>


<commit_before>#pragma once

#include <unordered_map>
#include <memory>
#include <type_traits>
#include <tuple>

namespace kgr {

template<typename... Types>
struct Dependency {
	using DependenciesTypes = std::tuple<Types...>;
};

using NoDependencies = Dependency<>;

struct Single {
	using ParentTypes = std::tuple<>;
};

template<typename T>
struct Service;

template<typename... Types>
struct Overrides : Single {
	using ParentTypes = std::tuple<Types...>;
};

namespace detail {

template<int ...>
struct seq { };

template<int N, int ...S>
struct seq_gen : seq_gen<N-1, N-1, S...> { };

template<int ...S>
struct seq_gen<0, S...> {
	using type = seq<S...>;
};

template <typename Tuple>
using tuple_seq = typename seq_gen<std::tuple_size<Tuple>::value>::type;

template <bool B, typename T>
using enable_if_t = typename std::enable_if<B, T>::type;

struct Holder {
	virtual ~Holder() {

	}
};

template<typename T>
struct InstanceHolder : Holder {
	InstanceHolder(std::shared_ptr<T> instance) : _instance{instance} {}

	std::shared_ptr<T> getInstance() const {
		return _instance;
	}

private:
	std::shared_ptr<T> _instance;
};

template<typename T, typename... Args>
struct CallbackHolder : Holder {
	using callback_t = std::function<std::shared_ptr<T>(Args...)>;

	CallbackHolder(callback_t callback) : _callback{callback} {}

	callback_t getCallback() const {
		return _callback;
	}
private:
	callback_t _callback;
};

}  // namespace detail

struct Container : std::enable_shared_from_this<Container> {
	template<typename T>
	void instance(std::shared_ptr<T> service) {
		static_assert(std::is_base_of<Single, Service<T>>::value, "instance only accept Single Service instance.");
		call_save_instance(service, detail::tuple_seq<typename Service<T>::ParentTypes>{});
	}

	template<typename T>
	void instance() {
		static_assert(std::is_base_of<Single, Service<T>>::value, "instance only accept Single Service instance.");
		using DependenciesTypes = typename Service<T>::DependenciesTypes;
		auto dependencies = dependency<DependenciesTypes>(detail::tuple_seq<DependenciesTypes>{});
		instance(make_service<T>(detail::tuple_seq<DependenciesTypes>{}, dependencies));
	}

	template<typename T>
	detail::enable_if_t<(!std::is_abstract<T>::value && !std::is_base_of<Container, T>::value), std::shared_ptr<T>> service() {
		return get_service<T>();
	}

	template<typename T>
	detail::enable_if_t<(std::is_same<T, Container>::value), std::shared_ptr<T>> service() {
		return shared_from_this();
	}

	template<typename T>
	detail::enable_if_t<(std::is_base_of<Container, T>::value && !std::is_same<T, Container>::value), std::shared_ptr<T>> service() {
		return std::dynamic_pointer_cast<T>(shared_from_this());
	}

	template<typename T>
	detail::enable_if_t<std::is_abstract<T>::value, std::shared_ptr<T>> service() {
		auto it = _services.find(typeid(T).name());
		if (it != _services.end()) {
			auto holder = dynamic_cast<detail::InstanceHolder<T>*>(it->second.get());
			if (holder) {
				return holder->getInstance();
			}
		}
		return nullptr;
	}

	template<typename T, typename U>
	void callback(U callback) {
		static_assert(!std::is_base_of<Single, Service<T>>::value, "instance does not accept Single Service.");
		using DependenciesTypes = typename Service<T>::DependenciesTypes;
		save_callback<T, DependenciesTypes>(detail::tuple_seq<DependenciesTypes>{}, callback);
	}

	virtual void init(){}

private:
	using HolderPtr = std::unique_ptr<detail::Holder>;
	using Holders   = std::unordered_map<std::string, HolderPtr>;

	template<typename T>
	detail::enable_if_t<std::is_base_of<Single, Service<T>>::value, std::shared_ptr<T>> get_service() {
		using DependenciesTypes = typename Service<T>::DependenciesTypes;
		auto it = _services.find(typeid(T).name());
		if (it == _services.end()) {
			auto dependencies = dependency<DependenciesTypes>(detail::tuple_seq<DependenciesTypes>{});
			auto service = make_service<T>(detail::tuple_seq<DependenciesTypes>{}, dependencies);
			instance(service);
			return service;
		} else {
			auto holder = dynamic_cast<detail::InstanceHolder<T>*>(it->second.get());
			if (holder) {
				return holder->getInstance();
			} else {
				return nullptr;
			}
		}
	}

	template<typename T>
	detail::enable_if_t<!std::is_base_of<Single, Service<T>>::value, std::shared_ptr<T>> get_service() {
		using DependenciesTypes = typename Service<T>::DependenciesTypes;
		auto dependencies = dependency<DependenciesTypes>(detail::tuple_seq<DependenciesTypes>{});
		auto service = make_service<T>(detail::tuple_seq<DependenciesTypes>{}, dependencies);

		return service;
	}

	template<typename T, int ...S>
	void call_save_instance(std::shared_ptr<T> service, detail::seq<S...>) {
		save_instance<T, typename std::tuple_element<S, typename Service<T>::ParentTypes>::type...>(service);
	}

	template<typename Tuple, int ...S>
	std::tuple<std::shared_ptr<typename std::tuple_element<S, Tuple>::type>...> dependency(detail::seq<S...>) {
		return std::make_tuple(service<typename std::tuple_element<S, Tuple>::type>()...);
	}

	template<typename T, typename Tuple, int ...S>
	std::shared_ptr<T> callback_make_service(detail::seq<S...> seq, Tuple dependencies) const {
		auto it = _callbacks.find(typeid(T).name());
		if (it != _callbacks.end()) {
			auto holder = dynamic_cast<detail::CallbackHolder<T, typename std::tuple_element<S, Tuple>::type...>*>(it->second.get());
			if (holder) {
				return holder->getCallback()(std::get<S>(dependencies)...);
			}
		}
		return nullptr;
	}

	template<typename T, typename Tuple, int ...S>
	std::shared_ptr<T> make_service(detail::seq<S...> seq, Tuple dependencies) const {
		auto service = callback_make_service<T, Tuple>(seq, dependencies);
		if (service) {
			return service;
		}
		return std::make_shared<T>(std::get<S>(dependencies)...);
	}

	template<typename T, typename ...Others>
	detail::enable_if_t<(sizeof...(Others) > 0), void> save_instance(std::shared_ptr<T> service) {
		save_instance<T>(service);
		save_instance<Others...>(service);
	}

	template<typename T>
	void save_instance (std::shared_ptr<T> service) {
		_services[typeid(T).name()] = std::unique_ptr<detail::InstanceHolder<T>>(new detail::InstanceHolder<T>(service));
	}

	template<typename T, typename Tuple, int ...S, typename U>
	void save_callback (detail::seq<S...>, U callback) {
		_callbacks[typeid(T).name()] = std::unique_ptr<detail::CallbackHolder<T, std::shared_ptr<typename std::tuple_element<S, Tuple>::type>...>>(new detail::CallbackHolder<T, std::shared_ptr<typename std::tuple_element<S, Tuple>::type>...>(callback));
	}

	Holders _callbacks;
	Holders _services;
};

template<typename T = Container, typename ...Args>
std::shared_ptr<T> make_container(Args&& ...args) {
	static_assert(std::is_base_of<Container, T>::value, "make_container only accept container types.");
	auto container = std::make_shared<T>(std::forward<Args>(args)...);
	container->init();
	return container;
}

}  // namespace kgr

<commit_msg>Add explicit to holder ctrs<commit_after>#pragma once

#include <unordered_map>
#include <memory>
#include <type_traits>
#include <tuple>

namespace kgr {

template<typename... Types>
struct Dependency {
	using DependenciesTypes = std::tuple<Types...>;
};

using NoDependencies = Dependency<>;

struct Single {
	using ParentTypes = std::tuple<>;
};

template<typename T>
struct Service;

template<typename... Types>
struct Overrides : Single {
	using ParentTypes = std::tuple<Types...>;
};

namespace detail {

template<int ...>
struct seq { };

template<int N, int ...S>
struct seq_gen : seq_gen<N-1, N-1, S...> { };

template<int ...S>
struct seq_gen<0, S...> {
	using type = seq<S...>;
};

template <typename Tuple>
using tuple_seq = typename seq_gen<std::tuple_size<Tuple>::value>::type;

template <bool B, typename T>
using enable_if_t = typename std::enable_if<B, T>::type;

struct Holder {
	virtual ~Holder() {

	}
};

template<typename T>
struct InstanceHolder : Holder {
	explicit InstanceHolder(std::shared_ptr<T> instance) : _instance{instance} {}

	std::shared_ptr<T> getInstance() const {
		return _instance;
	}

private:
	std::shared_ptr<T> _instance;
};

template<typename T, typename... Args>
struct CallbackHolder : Holder {
	using callback_t = std::function<std::shared_ptr<T>(Args...)>;

	explicit CallbackHolder(callback_t callback) : _callback{callback} {}

	callback_t getCallback() const {
		return _callback;
	}
private:
	callback_t _callback;
};

}  // namespace detail

struct Container : std::enable_shared_from_this<Container> {
	template<typename T>
	void instance(std::shared_ptr<T> service) {
		static_assert(std::is_base_of<Single, Service<T>>::value, "instance only accept Single Service instance.");
		call_save_instance(service, detail::tuple_seq<typename Service<T>::ParentTypes>{});
	}

	template<typename T>
	void instance() {
		static_assert(std::is_base_of<Single, Service<T>>::value, "instance only accept Single Service instance.");
		using DependenciesTypes = typename Service<T>::DependenciesTypes;
		auto dependencies = dependency<DependenciesTypes>(detail::tuple_seq<DependenciesTypes>{});
		instance(make_service<T>(detail::tuple_seq<DependenciesTypes>{}, dependencies));
	}

	template<typename T>
	detail::enable_if_t<(!std::is_abstract<T>::value && !std::is_base_of<Container, T>::value), std::shared_ptr<T>> service() {
		return get_service<T>();
	}

	template<typename T>
	detail::enable_if_t<(std::is_same<T, Container>::value), std::shared_ptr<T>> service() {
		return shared_from_this();
	}

	template<typename T>
	detail::enable_if_t<(std::is_base_of<Container, T>::value && !std::is_same<T, Container>::value), std::shared_ptr<T>> service() {
		return std::dynamic_pointer_cast<T>(shared_from_this());
	}

	template<typename T>
	detail::enable_if_t<std::is_abstract<T>::value, std::shared_ptr<T>> service() {
		auto it = _services.find(typeid(T).name());
		if (it != _services.end()) {
			auto holder = dynamic_cast<detail::InstanceHolder<T>*>(it->second.get());
			if (holder) {
				return holder->getInstance();
			}
		}
		return nullptr;
	}

	template<typename T, typename U>
	void callback(U callback) {
		static_assert(!std::is_base_of<Single, Service<T>>::value, "instance does not accept Single Service.");
		using DependenciesTypes = typename Service<T>::DependenciesTypes;
		save_callback<T, DependenciesTypes>(detail::tuple_seq<DependenciesTypes>{}, callback);
	}

	virtual void init(){}

private:
	using HolderPtr = std::unique_ptr<detail::Holder>;
	using Holders   = std::unordered_map<std::string, HolderPtr>;

	template<typename T>
	detail::enable_if_t<std::is_base_of<Single, Service<T>>::value, std::shared_ptr<T>> get_service() {
		using DependenciesTypes = typename Service<T>::DependenciesTypes;
		auto it = _services.find(typeid(T).name());
		if (it == _services.end()) {
			auto dependencies = dependency<DependenciesTypes>(detail::tuple_seq<DependenciesTypes>{});
			auto service = make_service<T>(detail::tuple_seq<DependenciesTypes>{}, dependencies);
			instance(service);
			return service;
		} else {
			auto holder = dynamic_cast<detail::InstanceHolder<T>*>(it->second.get());
			if (holder) {
				return holder->getInstance();
			} else {
				return nullptr;
			}
		}
	}

	template<typename T>
	detail::enable_if_t<!std::is_base_of<Single, Service<T>>::value, std::shared_ptr<T>> get_service() {
		using DependenciesTypes = typename Service<T>::DependenciesTypes;
		auto dependencies = dependency<DependenciesTypes>(detail::tuple_seq<DependenciesTypes>{});
		auto service = make_service<T>(detail::tuple_seq<DependenciesTypes>{}, dependencies);

		return service;
	}

	template<typename T, int ...S>
	void call_save_instance(std::shared_ptr<T> service, detail::seq<S...>) {
		save_instance<T, typename std::tuple_element<S, typename Service<T>::ParentTypes>::type...>(service);
	}

	template<typename Tuple, int ...S>
	std::tuple<std::shared_ptr<typename std::tuple_element<S, Tuple>::type>...> dependency(detail::seq<S...>) {
		return std::make_tuple(service<typename std::tuple_element<S, Tuple>::type>()...);
	}

	template<typename T, typename Tuple, int ...S>
	std::shared_ptr<T> callback_make_service(detail::seq<S...> seq, Tuple dependencies) const {
		auto it = _callbacks.find(typeid(T).name());
		if (it != _callbacks.end()) {
			auto holder = dynamic_cast<detail::CallbackHolder<T, typename std::tuple_element<S, Tuple>::type...>*>(it->second.get());
			if (holder) {
				return holder->getCallback()(std::get<S>(dependencies)...);
			}
		}
		return nullptr;
	}

	template<typename T, typename Tuple, int ...S>
	std::shared_ptr<T> make_service(detail::seq<S...> seq, Tuple dependencies) const {
		auto service = callback_make_service<T, Tuple>(seq, dependencies);
		if (service) {
			return service;
		}
		return std::make_shared<T>(std::get<S>(dependencies)...);
	}

	template<typename T, typename ...Others>
	detail::enable_if_t<(sizeof...(Others) > 0), void> save_instance(std::shared_ptr<T> service) {
		save_instance<T>(service);
		save_instance<Others...>(service);
	}

	template<typename T>
	void save_instance (std::shared_ptr<T> service) {
		_services[typeid(T).name()] = HolderPtr{new detail::InstanceHolder<T>(service)};
	}

	template<typename T, typename Tuple, int ...S, typename U>
	void save_callback (detail::seq<S...>, U callback) {
		_callbacks[typeid(T).name()] = HolderPtr{new detail::CallbackHolder<T, std::shared_ptr<typename std::tuple_element<S, Tuple>::type>...>(callback)};
	}

	Holders _callbacks;
	Holders _services;
};

template<typename T = Container, typename ...Args>
std::shared_ptr<T> make_container(Args&& ...args) {
	static_assert(std::is_base_of<Container, T>::value, "make_container only accept container types.");
	auto container = std::make_shared<T>(std::forward<Args>(args)...);
	container->init();
	return container;
}

}  // namespace kgr

<|endoftext|>


<commit_before><commit_msg>dump to extra file<commit_after><|endoftext|>


<commit_before><commit_msg>Add incremental map partitioner tests. Finally closes #714<commit_after><|endoftext|>


<commit_before>/*
 * NeoPixelWiFiEventHandler.cpp
 *
 *  Created on: Mar 1, 2017
 *      Author: kolban
 */
#include <stdio.h>
#include "NeoPixelWiFiEventHandler.h"

NeoPixelWiFiEventHandler::NeoPixelWiFiEventHandler(gpio_num_t gpioPin) {
	this->gpioPin = gpioPin;
	ws2812 = new WS2812(gpioPin, 8);
}

NeoPixelWiFiEventHandler::~NeoPixelWiFiEventHandler() {
	delete ws2812;
}

esp_err_t NeoPixelWiFiEventHandler::apStart() {
	printf("XXX apStart\n");
	ws2812->setPixel(0, 0, 00, 64);
	ws2812->show();
	return ESP_OK;
}

esp_err_t NeoPixelWiFiEventHandler::staConnected(system_event_sta_connected_t info) {
	printf("XXX staConnected\n");
	ws2812->setPixel(0, 57, 89, 66);
	ws2812->show();
	return ESP_OK;
}

esp_err_t NeoPixelWiFiEventHandler::staDisconnected(system_event_sta_disconnected_t info) {
	printf("XXX staDisconnected\n");
	ws2812->setPixel(0, 64, 0, 0);
	ws2812->show();
	return ESP_OK;
}

esp_err_t NeoPixelWiFiEventHandler::staStart() {
	printf("XXX staStart\n");
	ws2812->setPixel(0, 64, 64, 0);
	ws2812->show();
	return ESP_OK;
}

esp_err_t NeoPixelWiFiEventHandler::staGotIp(system_event_sta_got_ip_t info) {
	printf("XXX staGotIp\n");
	ws2812->setPixel(0, 0, 64, 0);
	ws2812->show();
	return ESP_OK;
}

esp_err_t NeoPixelWiFiEventHandler::wifiReady() {
	printf("XXX wifiReady\n");
	ws2812->setPixel(0, 64, 64, 0);
	ws2812->show();
	return ESP_OK;
}
<commit_msg>Sanitize Neopixel logging<commit_after>/*
 * NeoPixelWiFiEventHandler.cpp
 *
 *  Created on: Mar 1, 2017
 *      Author: kolban
 */
#include <stdio.h>
#include <esp_log.h>
#include "NeoPixelWiFiEventHandler.h"

static const char* LOG_TAG = "NeoPixelWiFiEventHandler";

NeoPixelWiFiEventHandler::NeoPixelWiFiEventHandler(gpio_num_t gpioPin) {
	this->gpioPin = gpioPin;
	ws2812 = new WS2812(gpioPin, 8);
}

NeoPixelWiFiEventHandler::~NeoPixelWiFiEventHandler() {
	delete ws2812;
}

esp_err_t NeoPixelWiFiEventHandler::apStart() {
	ESP_LOGD(LOG_TAG, "XXX apStart");
	ws2812->setPixel(0, 0, 00, 64);
	ws2812->show();
	return ESP_OK;
}

esp_err_t NeoPixelWiFiEventHandler::staConnected(system_event_sta_connected_t info) {
	ESP_LOGD(LOG_TAG, "XXX staConnected");
	ws2812->setPixel(0, 57, 89, 66);
	ws2812->show();
	return ESP_OK;
}

esp_err_t NeoPixelWiFiEventHandler::staDisconnected(system_event_sta_disconnected_t info) {
	ESP_LOGD(LOG_TAG, "XXX staDisconnected");
	ws2812->setPixel(0, 64, 0, 0);
	ws2812->show();
	return ESP_OK;
}

esp_err_t NeoPixelWiFiEventHandler::staStart() {
	ESP_LOGD(LOG_TAG, "XXX staStart");
	ws2812->setPixel(0, 64, 64, 0);
	ws2812->show();
	return ESP_OK;
}

esp_err_t NeoPixelWiFiEventHandler::staGotIp(system_event_sta_got_ip_t info) {
	ESP_LOGD(LOG_TAG, "XXX staGotIp");
	ws2812->setPixel(0, 0, 64, 0);
	ws2812->show();
	return ESP_OK;
}

esp_err_t NeoPixelWiFiEventHandler::wifiReady() {
	ESP_LOGD(LOG_TAG, "XXX wifiReady");
	ws2812->setPixel(0, 64, 64, 0);
	ws2812->show();
	return ESP_OK;
}
<|endoftext|>


<commit_before>#ifndef NFL_GMP_HPP
#define NFL_GMP_HPP

#include "nfl/poly.hpp"

namespace nfl {

template <class T, size_t Degree, size_t NbModuli>
typename poly<T, Degree, NbModuli>::GMP poly<T, Degree, NbModuli>::gmp;

/*
 * Constructors
 */
template <class T, size_t Degree, size_t NbModuli>
poly<T, Degree, NbModuli>::poly(mpz_t const& v) {
  set_mpz(v);
}

template <class T, size_t Degree, size_t NbModuli>
poly<T, Degree, NbModuli>::poly(mpz_class const& v) {
  set_mpz({v}, (size_t)1);
}

template <class T, size_t Degree, size_t NbModuli>
poly<T, Degree, NbModuli>::poly(std::initializer_list<mpz_class> const& values, size_t length) {
  set_mpz(values, length);
}

template <class T, size_t Degree, size_t NbModuli>
poly<T, Degree, NbModuli>::poly(mpz_t* const& values, size_t length) {
  set_mpz(values, length);
}

template <class T, size_t Degree, size_t NbModuli>
poly<T, Degree, NbModuli>::poly(mpz_class* const& values, size_t length) {
  set_mpz(values, length);
}

template <class T, size_t Degree, size_t NbModuli>
void poly<T, Degree, NbModuli>::set_mpz(mpz_t const& v) {
  set_mpz({mpz_class(v)}, (size_t)1);
}

template <class T, size_t Degree, size_t NbModuli>
void poly<T, Degree, NbModuli>::set_mpz(mpz_class const& v) {
  set_mpz({v}, (size_t)1);
}

/*
 * set_mpz's functions
 */
template <class T, size_t Degree, size_t NbModuli>
void poly<T, Degree, NbModuli>::set_mpz(mpz_t* const& values, size_t length) {
  std::vector<mpz_class> v;
  for (size_t i = 0; i < length; i++) {
    v.push_back(mpz_class(values[i]));
  }
  set_mpz(v.begin(), v.end(), length);
}

template <class T, size_t Degree, size_t NbModuli>
void poly<T, Degree, NbModuli>::set_mpz(mpz_class* const& values, size_t length) {
  std::vector<mpz_class> v;
  for (size_t i = 0; i < length; i++) {
    v.push_back(values[i]);
  }
  set_mpz(v.begin(), v.end(), length);
}

template <class T, size_t Degree, size_t NbModuli>
void poly<T, Degree, NbModuli>::set_mpz(
    std::initializer_list<mpz_class> const& values, size_t length) {
  set_mpz(values.begin(), values.end(), length);
}

template <class T, size_t Degree, size_t NbModuli>
template <class It>
void poly<T, Degree, NbModuli>::set_mpz(It first, It last, size_t length) {
  // CRITICAL: the object must be 32-bytes aligned to avoid vectorization issues
  assert((unsigned long)(this->_data) % 32 == 0);

  auto* iter = begin();
  auto viter = first;

  size_t size = (!length) ? std::distance(first, last) : length;
  // If the initializer has no more values than the polynomial degree use them
  // to initialize the associated coefficients for each sub-modulus
  if (size <= degree || size == degree * nmoduli) {
    for (size_t cm = 0; cm < nmoduli; ++cm) {
      if (size != degree * nmoduli) {
        viter = first;
      }
      for (size_t i = 0; i < degree; i++) {
        if (viter < last) {
          *iter++ = mpz_fdiv_ui(viter->get_mpz_t(), params<T>::P[cm]);
          viter++;
        } else
          *iter++ = 0;
      }
    }
  } else {
    throw std::runtime_error(
        "gmp.hpp: CRITICAL, initializer of size above degree but different "
        "from nmoduli*degree");
  }
}

template <class T, size_t Degree, size_t NbModuli>
poly<T, Degree, NbModuli>::GMP::GMP() {
  // Compute product of moduli
  mpz_init_set_ui(moduli_product, 1);
  for (size_t i = 0; i < nmoduli; i++) {
    mpz_mul_ui(moduli_product, moduli_product, params<T>::P[i]);
  }

  bits_in_moduli_product = mpz_sizeinbase(moduli_product, 2);

  // Compute Shoup value for optimized reduction modulo "moduli_product"
  mpz_t one;
  mpz_init_set_ui(one, 1);
  mpz_init(modulus_shoup);
  mpz_mul_2exp(modulus_shoup, one, bits_in_moduli_product +
                                       sizeof(T) * CHAR_BIT +
                                       params<T>::logkMaxNbModuli + 1);
  mpz_tdiv_q(modulus_shoup, modulus_shoup, moduli_product);

  // Compute the lifting coefficients
  mpz_t quotient;
  mpz_init(quotient);
  lifting_integers = (mpz_t*)malloc(nmoduli * sizeof(mpz_t));

  for (size_t i = 0; i < nmoduli; i++) {
    // Current modulus
    mpz_t current_modulus;
    mpz_init_set_ui(current_modulus, params<T>::P[i]);

    // compute the product of primes except the current one
    mpz_divexact(quotient, moduli_product, current_modulus);

    // Compute the inverse of the product
    mpz_init(lifting_integers[i]);
    mpz_invert(lifting_integers[i], quotient, current_modulus);

    // Multiply by the quotient
    mpz_mul(lifting_integers[i], lifting_integers[i], quotient);
    mpz_clear(current_modulus);
  }

  // Clear
  mpz_clear(one);
  mpz_clear(quotient);
}

template <class T, size_t Degree, size_t NbModuli>
poly<T, Degree, NbModuli>::GMP::~GMP() {
  for (size_t i = 0; i < nmoduli; i++) {
    mpz_clear(lifting_integers[i]);
  }
  free(lifting_integers);
  mpz_clear(modulus_shoup);
  mpz_clear(moduli_product);
}

template <class T, size_t Degree, size_t NbModuli>
mpz_t* poly<T, Degree, NbModuli>::GMP::poly2mpz(poly const& op) {
  // Assign and init
  mpz_t* poly_mpz = new mpz_t[degree];
  for (size_t i = 0; i < degree; i++) {
    mpz_init(poly_mpz[i]);
  }

  // Fill
  poly2mpz(poly_mpz, op);

  return poly_mpz;
}

template <class T, size_t Degree, size_t NbModuli>
void poly<T, Degree, NbModuli>::GMP::poly2mpz(mpz_t* rop, poly const& op) {
  mpz_t tmp;
  mpz_init2(tmp, (bits_in_moduli_product << 2));
  for (size_t i = 0; i < degree; i++) {
    mpz_set_ui(rop[i], 0);
    for (size_t cm = 0; cm < nmoduli; cm++) {
      if (op(cm, i) != 0) {
        mpz_mul_ui(tmp, lifting_integers[cm], op(cm, i));
      }
      mpz_add(rop[i], rop[i], tmp);
    }
    // Modular reduction using Shoup
    mpz_mul(tmp, rop[i], modulus_shoup);
    mpz_tdiv_q_2exp(tmp, tmp, bits_in_moduli_product + sizeof(T) * CHAR_BIT +
                                  params<T>::logkMaxNbModuli + 1);
    mpz_mul(tmp, tmp, moduli_product);
    mpz_sub(rop[i], rop[i], tmp);
    if (mpz_cmp(rop[i], moduli_product) >= 0) {
      mpz_sub(rop[i], rop[i], moduli_product);
    }
  }
  mpz_clear(tmp);
}

template <class T, size_t Degree, size_t NbModuli>
void poly<T, Degree, NbModuli>::GMP::mpz2poly(poly<T, Degree, NbModuli>& rop,
                                              mpz_t* const& poly_mpz) {
  // rop.set_mpz(poly_mpz, degree);
  for (size_t cm = 0; cm < nmoduli; cm++) {
    for (size_t i = 0; i < degree; i++) {
      rop(cm, i) = mpz_fdiv_ui(poly_mpz[i], params<T>::P[cm]);
    }
  }
}
}

#endif<commit_msg>Minor<commit_after>#ifndef NFL_GMP_HPP
#define NFL_GMP_HPP

#include "nfl/poly.hpp"

namespace nfl {

template <class T, size_t Degree, size_t NbModuli>
typename poly<T, Degree, NbModuli>::GMP poly<T, Degree, NbModuli>::gmp;

/*
 * Constructors
 */
template <class T, size_t Degree, size_t NbModuli>
poly<T, Degree, NbModuli>::poly(mpz_t const& v) {
  set_mpz(v);
}

template <class T, size_t Degree, size_t NbModuli>
poly<T, Degree, NbModuli>::poly(mpz_class const& v) {
  set_mpz({v}, (size_t)1);
}

template <class T, size_t Degree, size_t NbModuli>
poly<T, Degree, NbModuli>::poly(std::initializer_list<mpz_class> const& values, size_t length) {
  set_mpz(values, length);
}

template <class T, size_t Degree, size_t NbModuli>
poly<T, Degree, NbModuli>::poly(mpz_t* const& values, size_t length) {
  set_mpz(values, length);
}

template <class T, size_t Degree, size_t NbModuli>
poly<T, Degree, NbModuli>::poly(mpz_class* const& values, size_t length) {
  set_mpz(values, length);
}

template <class T, size_t Degree, size_t NbModuli>
void poly<T, Degree, NbModuli>::set_mpz(mpz_t const& v) {
  set_mpz({mpz_class(v)}, (size_t)1);
}

template <class T, size_t Degree, size_t NbModuli>
void poly<T, Degree, NbModuli>::set_mpz(mpz_class const& v) {
  set_mpz({v}, (size_t)1);
}

/*
 * set_mpz's functions
 */
template <class T, size_t Degree, size_t NbModuli>
void poly<T, Degree, NbModuli>::set_mpz(mpz_t* const& values, size_t length) {
  std::vector<mpz_class> v;
  for (size_t i = 0; i < length; i++) {
    v.push_back(mpz_class(values[i]));
  }
  set_mpz(v.begin(), v.end(), length);
}

template <class T, size_t Degree, size_t NbModuli>
void poly<T, Degree, NbModuli>::set_mpz(mpz_class* const& values, size_t length) {
  std::vector<mpz_class> v;
  for (size_t i = 0; i < length; i++) {
    v.push_back(values[i]);
  }
  set_mpz(v.begin(), v.end(), length);
}

template <class T, size_t Degree, size_t NbModuli>
void poly<T, Degree, NbModuli>::set_mpz(
    std::initializer_list<mpz_class> const& values, size_t length) {
  set_mpz(values.begin(), values.end(), length);
}

template <class T, size_t Degree, size_t NbModuli>
template <class It>
void poly<T, Degree, NbModuli>::set_mpz(It first, It last, size_t length) {
  // CRITICAL: the object must be 32-bytes aligned to avoid vectorization issues
  assert((unsigned long)(this->_data) % 32 == 0);

  auto* iter = begin();
  auto viter = first;

  size_t size = (!length) ? std::distance(first, last) : length;
  // If the initializer has no more values than the polynomial degree use them
  // to initialize the associated coefficients for each sub-modulus
  if (size <= degree || size == degree * nmoduli) {
    for (size_t cm = 0; cm < nmoduli; ++cm) {
      if (size != degree * nmoduli) {
        viter = first;
      }
      for (size_t i = 0; i < degree; i++) {
        if (viter < last) {
          *iter++ = mpz_fdiv_ui(viter->get_mpz_t(), params<T>::P[cm]);
          viter++;
        } else
          *iter++ = 0;
      }
    }
  } else {
    throw std::runtime_error(
        "gmp.hpp: CRITICAL, initializer of size above degree but different "
        "from nmoduli*degree");
  }
}

template <class T, size_t Degree, size_t NbModuli>
poly<T, Degree, NbModuli>::GMP::GMP() {
  // Compute product of moduli
  mpz_init_set_ui(moduli_product, 1);
  for (size_t i = 0; i < nmoduli; i++) {
    mpz_mul_ui(moduli_product, moduli_product, params<T>::P[i]);
  }

  bits_in_moduli_product = mpz_sizeinbase(moduli_product, 2);

  // Compute Shoup value for optimized reduction modulo "moduli_product"
  mpz_t one;
  mpz_init_set_ui(one, 1);
  mpz_init(modulus_shoup);
  mpz_mul_2exp(modulus_shoup, one, bits_in_moduli_product +
                                       sizeof(T) * CHAR_BIT +
                                       params<T>::logkMaxNbModuli + 1);
  mpz_tdiv_q(modulus_shoup, modulus_shoup, moduli_product);

  // Compute the lifting coefficients
  mpz_t quotient;
  mpz_init(quotient);
  lifting_integers = (mpz_t*)malloc(nmoduli * sizeof(mpz_t));

  for (size_t i = 0; i < nmoduli; i++) {
    // Current modulus
    mpz_t current_modulus;
    mpz_init_set_ui(current_modulus, params<T>::P[i]);

    // compute the product of primes except the current one
    mpz_divexact(quotient, moduli_product, current_modulus);

    // Compute the inverse of the product
    mpz_init(lifting_integers[i]);
    mpz_invert(lifting_integers[i], quotient, current_modulus);

    // Multiply by the quotient
    mpz_mul(lifting_integers[i], lifting_integers[i], quotient);
    mpz_clear(current_modulus);
  }

  // Clear
  mpz_clear(one);
  mpz_clear(quotient);
}

template <class T, size_t Degree, size_t NbModuli>
poly<T, Degree, NbModuli>::GMP::~GMP() {
  for (size_t i = 0; i < nmoduli; i++) {
    mpz_clear(lifting_integers[i]);
  }
  free(lifting_integers);
  mpz_clear(modulus_shoup);
  mpz_clear(moduli_product);
}

/**
 * Functions to convert a poly into an array of mpz_t, and back
 *
 * The mpz_t array is allocated with new[]
 */

template <class T, size_t Degree, size_t NbModuli>
mpz_t* poly<T, Degree, NbModuli>::GMP::poly2mpz(poly const& op) {
  // Assign and init
  mpz_t* poly_mpz = new mpz_t[degree];
  for (size_t i = 0; i < degree; i++) {
    mpz_init(poly_mpz[i]);
  }

  // Fill
  poly2mpz(poly_mpz, op);

  return poly_mpz;
}

template <class T, size_t Degree, size_t NbModuli>
void poly<T, Degree, NbModuli>::GMP::poly2mpz(mpz_t* rop, poly const& op) {
  mpz_t tmp;
  mpz_init2(tmp, (bits_in_moduli_product << 2));
  for (size_t i = 0; i < degree; i++) {
    mpz_set_ui(rop[i], 0);
    for (size_t cm = 0; cm < nmoduli; cm++) {
      if (op(cm, i) != 0) {
        mpz_mul_ui(tmp, lifting_integers[cm], op(cm, i));
      }
      mpz_add(rop[i], rop[i], tmp);
    }
    // Modular reduction using Shoup
    mpz_mul(tmp, rop[i], modulus_shoup);
    mpz_tdiv_q_2exp(tmp, tmp, bits_in_moduli_product + sizeof(T) * CHAR_BIT +
                                  params<T>::logkMaxNbModuli + 1);
    mpz_mul(tmp, tmp, moduli_product);
    mpz_sub(rop[i], rop[i], tmp);
    if (mpz_cmp(rop[i], moduli_product) >= 0) {
      mpz_sub(rop[i], rop[i], moduli_product);
    }
  }
  mpz_clear(tmp);
}

template <class T, size_t Degree, size_t NbModuli>
void poly<T, Degree, NbModuli>::GMP::mpz2poly(poly<T, Degree, NbModuli>& rop,
                                              mpz_t* const& poly_mpz) {
  for (size_t cm = 0; cm < nmoduli; cm++) {
    for (size_t i = 0; i < degree; i++) {
      rop(cm, i) = mpz_fdiv_ui(poly_mpz[i], params<T>::P[cm]);
    }
  }
}
}

#endif<|endoftext|>


<commit_before>// Extended Euclid
int x, y, d;
void extgcd(int a, int b) {
  if (!b) { x = 1; y = 0; d = a; return; }
  extgcd(b, a%b);
  int x1 = y, y1 = x-(a/b)*y;
  x = x1, y = y1;
}
<commit_msg>Reduced size of extended euclid algorithm.<commit_after>// Extended Euclid: gcd(a, b) = x*a + y*b
void extgcd(int a, int b, int &x, int &y, int &d) {
  if (b) extgcd(b, a%b, y, x, d), y -= x*(a/b);
  else x = 1, y = 0, d = a;
}
<|endoftext|>


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

#ifndef _OSL_DIAGNOSE_H_
#include "osl/diagnose.h"
#endif
#ifndef _OSL_INTERLCK_H_
#include "osl/interlck.h"
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_
#include "com/sun/star/uno/Sequence.h"
#endif
#ifndef _TYPELIB_TYPEDESCRIPTION_H_
#include "typelib/typedescription.h"
#endif
#ifndef _UNO_DATA_H_
#include "uno/data.h"
#endif
#ifndef _COM_SUN_STAR_UNO_GENFUNC_HXX_
#include "com/sun/star/uno/genfunc.hxx"
#endif
#ifndef INCLUDED_CPPU_UNOTYPE_HXX
#include "cppu/unotype.hxx"
#endif

namespace com
{
namespace sun
{
namespace star
{
namespace uno
{

//______________________________________________________________________________
template< class E >
typelib_TypeDescriptionReference * Sequence< E >::s_pType = 0;

//______________________________________________________________________________
template< class E >
inline Sequence< E >::Sequence() SAL_THROW( () )
{
    const Type & rType = ::cppu::getTypeFavourUnsigned( this );
    ::uno_type_sequence_construct(
        &_pSequence, rType.getTypeLibType(),
        0, 0, (uno_AcquireFunc)cpp_acquire );
    // no bad_alloc, because empty sequence is statically allocated in cppu
}

//______________________________________________________________________________
template< class E >
inline Sequence< E >::Sequence( const Sequence< E > & rSeq ) SAL_THROW( () )
{
    ::osl_incrementInterlockedCount( &rSeq._pSequence->nRefCount );
    _pSequence = rSeq._pSequence;
}

//______________________________________________________________________________
template< class E >
inline Sequence< E >::Sequence(
    uno_Sequence * pSequence, __sal_NoAcquire ) SAL_THROW( () )
        : _pSequence( pSequence )
{
}

//______________________________________________________________________________
template< class E >
inline Sequence< E >::Sequence( const E * pElements, sal_Int32 len )
{
    const Type & rType = ::cppu::getTypeFavourUnsigned( this );
#if ! defined EXCEPTIONS_OFF
    sal_Bool success =
#endif
    ::uno_type_sequence_construct(
        &_pSequence, rType.getTypeLibType(),
        const_cast< E * >( pElements ), len, (uno_AcquireFunc)cpp_acquire );
#if ! defined EXCEPTIONS_OFF
    if (! success)
        throw ::std::bad_alloc();
#endif
}

//______________________________________________________________________________
template< class E >
inline Sequence< E >::Sequence( sal_Int32 len )
{
    const Type & rType = ::cppu::getTypeFavourUnsigned( this );
#if ! defined EXCEPTIONS_OFF
    sal_Bool success =
#endif
    ::uno_type_sequence_construct(
        &_pSequence, rType.getTypeLibType(),
        0, len, (uno_AcquireFunc)cpp_acquire );
#if ! defined EXCEPTIONS_OFF
    if (! success)
        throw ::std::bad_alloc();
#endif
}

//______________________________________________________________________________
template< class E >
inline Sequence< E >::~Sequence() SAL_THROW( () )
{
    const Type & rType = ::cppu::getTypeFavourUnsigned( this );
    ::uno_type_destructData(
        this, rType.getTypeLibType(), (uno_ReleaseFunc)cpp_release );
}

//______________________________________________________________________________
template< class E >
inline Sequence< E > & Sequence< E >::operator = ( const Sequence< E > & rSeq ) SAL_THROW( () )
{
    const Type & rType = ::cppu::getTypeFavourUnsigned( this );
    ::uno_type_sequence_assign(
        &_pSequence, rSeq._pSequence, rType.getTypeLibType(), (uno_ReleaseFunc)cpp_release );
    return *this;
}

//______________________________________________________________________________
template< class E >
inline sal_Bool Sequence< E >::operator == ( const Sequence< E > & rSeq ) const
    SAL_THROW( () )
{
    if (_pSequence == rSeq._pSequence)
        return sal_True;
    const Type & rType = ::cppu::getTypeFavourUnsigned( this );
    return ::uno_type_equalData(
        const_cast< Sequence< E > * >( this ), rType.getTypeLibType(),
        const_cast< Sequence< E > * >( &rSeq ), rType.getTypeLibType(),
        (uno_QueryInterfaceFunc)cpp_queryInterface,
        (uno_ReleaseFunc)cpp_release );
}

//______________________________________________________________________________
template< class E >
inline sal_Bool Sequence< E >::operator != ( const Sequence< E > & rSeq ) const
    SAL_THROW( () )
{
    return (! operator == ( rSeq ));
}

//______________________________________________________________________________
template< class E >
inline E * Sequence< E >::getArray()
{
    const Type & rType = ::cppu::getTypeFavourUnsigned( this );
#if ! defined EXCEPTIONS_OFF
    sal_Bool success =
#endif
    ::uno_type_sequence_reference2One(
        &_pSequence, rType.getTypeLibType(),
        (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release );
#if ! defined EXCEPTIONS_OFF
    if (! success)
        throw ::std::bad_alloc();
#endif
    return reinterpret_cast< E * >( _pSequence->elements );
}

//______________________________________________________________________________
template< class E >
inline E & Sequence< E >::operator [] ( sal_Int32 nIndex )
{
    OSL_ENSURE(
        nIndex >= 0 && nIndex < getLength(),
        "### illegal index of sequence!" );
    return getArray()[ nIndex ];
}

//______________________________________________________________________________
template< class E >
inline const E & Sequence< E >::operator [] ( sal_Int32 nIndex ) const
    SAL_THROW( () )
{
    OSL_ENSURE(
        nIndex >= 0 && nIndex < getLength(),
        "### illegal index of sequence!" );
    return reinterpret_cast< const E * >( _pSequence->elements )[ nIndex ];
}

//______________________________________________________________________________
template< class E >
inline void Sequence< E >::realloc( sal_Int32 nSize )
{
    const Type & rType = ::cppu::getTypeFavourUnsigned( this );
#if !defined EXCEPTIONS_OFF
    sal_Bool success =
#endif
    ::uno_type_sequence_realloc(
        &_pSequence, rType.getTypeLibType(), nSize,
        (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release );
#if !defined EXCEPTIONS_OFF
    if (!success)
        throw ::std::bad_alloc();
#endif
}

//------------------------------------------------------------------------------
inline ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL toUnoSequence(
    const ::rtl::ByteSequence & rByteSequence ) SAL_THROW( () )
{
    return ::com::sun::star::uno::Sequence< sal_Int8 >(
        * reinterpret_cast< const ::com::sun::star::uno::Sequence< sal_Int8 > * >( &rByteSequence ) );
}

}
}
}
}

namespace cppu {

template< typename T > inline ::com::sun::star::uno::Type const &
getTypeFavourUnsigned(::com::sun::star::uno::Sequence< T > const *) {
    if (::com::sun::star::uno::Sequence< T >::s_pType == 0) {
        ::typelib_static_sequence_type_init(
            &::com::sun::star::uno::Sequence< T >::s_pType,
            (::cppu::getTypeFavourUnsigned(
                static_cast<
                typename ::com::sun::star::uno::Sequence< T >::ElementType * >(
                    0)).
             getTypeLibType()));
    }
    return detail::getTypeFromTypeDescriptionReference(
        &::com::sun::star::uno::Sequence< T >::s_pType);
}

template< typename T > inline ::com::sun::star::uno::Type const &
getTypeFavourChar(::com::sun::star::uno::Sequence< T > const *) {
    //TODO  On certain platforms with weak memory models, the following code can
    // result in some threads observing that td points to garbage:
    static typelib_TypeDescriptionReference * td = 0;
    if (td == 0) {
        ::typelib_static_sequence_type_init(
            &td,
            (::cppu::getTypeFavourChar(
                static_cast<
                typename ::com::sun::star::uno::Sequence< T >::ElementType * >(
                    0)).
             getTypeLibType()));
    }
    return detail::getTypeFromTypeDescriptionReference(&td);
}

}

// generic sequence template
template< class E >
inline const ::com::sun::star::uno::Type &
SAL_CALL getCppuType( const ::com::sun::star::uno::Sequence< E > * )
    SAL_THROW( () )
{
    return ::cppu::getTypeFavourUnsigned(
        static_cast< ::com::sun::star::uno::Sequence< E > * >(0));
}

// generic sequence template for given element type (e.g. C++ arrays)
template< class E >
inline const ::com::sun::star::uno::Type &
SAL_CALL getCppuSequenceType( const ::com::sun::star::uno::Type & rElementType )
    SAL_THROW( () )
{
    if (! ::com::sun::star::uno::Sequence< E >::s_pType)
    {
        ::typelib_static_sequence_type_init(
            & ::com::sun::star::uno::Sequence< E >::s_pType,
            rElementType.getTypeLibType() );
    }
    return * reinterpret_cast< const ::com::sun::star::uno::Type * >(
        & ::com::sun::star::uno::Sequence< E >::s_pType );
}

#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))
static typelib_TypeDescriptionReference * s_pType_com_sun_star_uno_Sequence_Char = 0;
#endif

// char sequence
inline const ::com::sun::star::uno::Type &
SAL_CALL getCharSequenceCppuType() SAL_THROW( () )
{
#if !( defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))
    static typelib_TypeDescriptionReference * s_pType_com_sun_star_uno_Sequence_Char = 0;
#endif
    if (! s_pType_com_sun_star_uno_Sequence_Char)
    {
        const ::com::sun::star::uno::Type & rElementType = ::getCharCppuType();
        ::typelib_static_sequence_type_init(
            & s_pType_com_sun_star_uno_Sequence_Char,
            rElementType.getTypeLibType() );
    }
    return * reinterpret_cast< const ::com::sun::star::uno::Type * >(
        & s_pType_com_sun_star_uno_Sequence_Char );
}

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

#include "osl/diagnose.h"
#include "osl/interlck.h"
#include "com/sun/star/uno/Sequence.h"
#include "typelib/typedescription.h"
#include "uno/data.h"
#include "com/sun/star/uno/genfunc.hxx"
#include "cppu/unotype.hxx"

namespace com
{
namespace sun
{
namespace star
{
namespace uno
{

//______________________________________________________________________________
template< class E >
typelib_TypeDescriptionReference * Sequence< E >::s_pType = 0;

//______________________________________________________________________________
template< class E >
inline Sequence< E >::Sequence() SAL_THROW( () )
{
    const Type & rType = ::cppu::getTypeFavourUnsigned( this );
    ::uno_type_sequence_construct(
        &_pSequence, rType.getTypeLibType(),
        0, 0, (uno_AcquireFunc)cpp_acquire );
    // no bad_alloc, because empty sequence is statically allocated in cppu
}

//______________________________________________________________________________
template< class E >
inline Sequence< E >::Sequence( const Sequence< E > & rSeq ) SAL_THROW( () )
{
    ::osl_incrementInterlockedCount( &rSeq._pSequence->nRefCount );
    _pSequence = rSeq._pSequence;
}

//______________________________________________________________________________
template< class E >
inline Sequence< E >::Sequence(
    uno_Sequence * pSequence, __sal_NoAcquire ) SAL_THROW( () )
        : _pSequence( pSequence )
{
}

//______________________________________________________________________________
template< class E >
inline Sequence< E >::Sequence( const E * pElements, sal_Int32 len )
{
    const Type & rType = ::cppu::getTypeFavourUnsigned( this );
#if ! defined EXCEPTIONS_OFF
    sal_Bool success =
#endif
    ::uno_type_sequence_construct(
        &_pSequence, rType.getTypeLibType(),
        const_cast< E * >( pElements ), len, (uno_AcquireFunc)cpp_acquire );
#if ! defined EXCEPTIONS_OFF
    if (! success)
        throw ::std::bad_alloc();
#endif
}

//______________________________________________________________________________
template< class E >
inline Sequence< E >::Sequence( sal_Int32 len )
{
    const Type & rType = ::cppu::getTypeFavourUnsigned( this );
#if ! defined EXCEPTIONS_OFF
    sal_Bool success =
#endif
    ::uno_type_sequence_construct(
        &_pSequence, rType.getTypeLibType(),
        0, len, (uno_AcquireFunc)cpp_acquire );
#if ! defined EXCEPTIONS_OFF
    if (! success)
        throw ::std::bad_alloc();
#endif
}

//______________________________________________________________________________
template< class E >
inline Sequence< E >::~Sequence() SAL_THROW( () )
{
    const Type & rType = ::cppu::getTypeFavourUnsigned( this );
    ::uno_type_destructData(
        this, rType.getTypeLibType(), (uno_ReleaseFunc)cpp_release );
}

//______________________________________________________________________________
template< class E >
inline Sequence< E > & Sequence< E >::operator = ( const Sequence< E > & rSeq ) SAL_THROW( () )
{
    const Type & rType = ::cppu::getTypeFavourUnsigned( this );
    ::uno_type_sequence_assign(
        &_pSequence, rSeq._pSequence, rType.getTypeLibType(), (uno_ReleaseFunc)cpp_release );
    return *this;
}

//______________________________________________________________________________
template< class E >
inline sal_Bool Sequence< E >::operator == ( const Sequence< E > & rSeq ) const
    SAL_THROW( () )
{
    if (_pSequence == rSeq._pSequence)
        return sal_True;
    const Type & rType = ::cppu::getTypeFavourUnsigned( this );
    return ::uno_type_equalData(
        const_cast< Sequence< E > * >( this ), rType.getTypeLibType(),
        const_cast< Sequence< E > * >( &rSeq ), rType.getTypeLibType(),
        (uno_QueryInterfaceFunc)cpp_queryInterface,
        (uno_ReleaseFunc)cpp_release );
}

//______________________________________________________________________________
template< class E >
inline sal_Bool Sequence< E >::operator != ( const Sequence< E > & rSeq ) const
    SAL_THROW( () )
{
    return (! operator == ( rSeq ));
}

//______________________________________________________________________________
template< class E >
inline E * Sequence< E >::getArray()
{
    const Type & rType = ::cppu::getTypeFavourUnsigned( this );
#if ! defined EXCEPTIONS_OFF
    sal_Bool success =
#endif
    ::uno_type_sequence_reference2One(
        &_pSequence, rType.getTypeLibType(),
        (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release );
#if ! defined EXCEPTIONS_OFF
    if (! success)
        throw ::std::bad_alloc();
#endif
    return reinterpret_cast< E * >( _pSequence->elements );
}

//______________________________________________________________________________
template< class E >
inline E & Sequence< E >::operator [] ( sal_Int32 nIndex )
{
    OSL_ENSURE(
        nIndex >= 0 && nIndex < getLength(),
        "### illegal index of sequence!" );
    return getArray()[ nIndex ];
}

//______________________________________________________________________________
template< class E >
inline const E & Sequence< E >::operator [] ( sal_Int32 nIndex ) const
    SAL_THROW( () )
{
    OSL_ENSURE(
        nIndex >= 0 && nIndex < getLength(),
        "### illegal index of sequence!" );
    return reinterpret_cast< const E * >( _pSequence->elements )[ nIndex ];
}

//______________________________________________________________________________
template< class E >
inline void Sequence< E >::realloc( sal_Int32 nSize )
{
    const Type & rType = ::cppu::getTypeFavourUnsigned( this );
#if !defined EXCEPTIONS_OFF
    sal_Bool success =
#endif
    ::uno_type_sequence_realloc(
        &_pSequence, rType.getTypeLibType(), nSize,
        (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release );
#if !defined EXCEPTIONS_OFF
    if (!success)
        throw ::std::bad_alloc();
#endif
}

//------------------------------------------------------------------------------
inline ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL toUnoSequence(
    const ::rtl::ByteSequence & rByteSequence ) SAL_THROW( () )
{
    return ::com::sun::star::uno::Sequence< sal_Int8 >(
        * reinterpret_cast< const ::com::sun::star::uno::Sequence< sal_Int8 > * >( &rByteSequence ) );
}

}
}
}
}

namespace cppu {

template< typename T > inline ::com::sun::star::uno::Type const &
getTypeFavourUnsigned(::com::sun::star::uno::Sequence< T > const *) {
    if (::com::sun::star::uno::Sequence< T >::s_pType == 0) {
        ::typelib_static_sequence_type_init(
            &::com::sun::star::uno::Sequence< T >::s_pType,
            (::cppu::getTypeFavourUnsigned(
                static_cast<
                typename ::com::sun::star::uno::Sequence< T >::ElementType * >(
                    0)).
             getTypeLibType()));
    }
    return detail::getTypeFromTypeDescriptionReference(
        &::com::sun::star::uno::Sequence< T >::s_pType);
}

template< typename T > inline ::com::sun::star::uno::Type const &
getTypeFavourChar(::com::sun::star::uno::Sequence< T > const *) {
    //TODO  On certain platforms with weak memory models, the following code can
    // result in some threads observing that td points to garbage:
    static typelib_TypeDescriptionReference * td = 0;
    if (td == 0) {
        ::typelib_static_sequence_type_init(
            &td,
            (::cppu::getTypeFavourChar(
                static_cast<
                typename ::com::sun::star::uno::Sequence< T >::ElementType * >(
                    0)).
             getTypeLibType()));
    }
    return detail::getTypeFromTypeDescriptionReference(&td);
}

}

// generic sequence template
template< class E >
inline const ::com::sun::star::uno::Type &
SAL_CALL getCppuType( const ::com::sun::star::uno::Sequence< E > * )
    SAL_THROW( () )
{
    return ::cppu::getTypeFavourUnsigned(
        static_cast< ::com::sun::star::uno::Sequence< E > * >(0));
}

// generic sequence template for given element type (e.g. C++ arrays)
template< class E >
inline const ::com::sun::star::uno::Type &
SAL_CALL getCppuSequenceType( const ::com::sun::star::uno::Type & rElementType )
    SAL_THROW( () )
{
    if (! ::com::sun::star::uno::Sequence< E >::s_pType)
    {
        ::typelib_static_sequence_type_init(
            & ::com::sun::star::uno::Sequence< E >::s_pType,
            rElementType.getTypeLibType() );
    }
    return * reinterpret_cast< const ::com::sun::star::uno::Type * >(
        & ::com::sun::star::uno::Sequence< E >::s_pType );
}

#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))
static typelib_TypeDescriptionReference * s_pType_com_sun_star_uno_Sequence_Char = 0;
#endif

// char sequence
inline const ::com::sun::star::uno::Type &
SAL_CALL getCharSequenceCppuType() SAL_THROW( () )
{
#if !( defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))
    static typelib_TypeDescriptionReference * s_pType_com_sun_star_uno_Sequence_Char = 0;
#endif
    if (! s_pType_com_sun_star_uno_Sequence_Char)
    {
        const ::com::sun::star::uno::Type & rElementType = ::getCharCppuType();
        ::typelib_static_sequence_type_init(
            & s_pType_com_sun_star_uno_Sequence_Char,
            rElementType.getTypeLibType() );
    }
    return * reinterpret_cast< const ::com::sun::star::uno::Type * >(
        & s_pType_com_sun_star_uno_Sequence_Char );
}

#endif
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <time.h>
#include <math.h>

#include "../module_headers/module.h"
#include "../module_headers/function_module.h"
#include "math_function_module.h"

const unsigned int COUNT_MATH_FUNCTIONS = 13;

#define ADD_MATH_FUNCTION(FUNCTION_NAME, COUNT_PARAMS, GIVE_EXCEPTION) \
	math_functions[function_id] = new FunctionData; \
	math_functions[function_id]->command_index = function_id + 1; \
	math_functions[function_id]->count_params = COUNT_PARAMS; \
	math_functions[function_id]->give_exception = GIVE_EXCEPTION; \
	math_functions[function_id]->name = FUNCTION_NAME; \
	function_id++;

#define DEFINE_ALL_FUNCTIONS \
	ADD_MATH_FUNCTION("pow",  2, false) \
	ADD_MATH_FUNCTION("abs",  1, false) \
	ADD_MATH_FUNCTION("sqrt", 1, true) \
	ADD_MATH_FUNCTION("rand", 2, true) \
	ADD_MATH_FUNCTION("sin",  1, false) \
	ADD_MATH_FUNCTION("cos",  1, false) \
	ADD_MATH_FUNCTION("tan",  1, false) \
	ADD_MATH_FUNCTION("asin", 1, true) \
	ADD_MATH_FUNCTION("acos", 1, true) \
	ADD_MATH_FUNCTION("atan", 1, false) \
	ADD_MATH_FUNCTION("exp",  1, false) \
	ADD_MATH_FUNCTION("log",  1, true) \
	ADD_MATH_FUNCTION("log10",1, true)

const char* MathFunctionModule::getUID() {
    return "Math_Functions_dll";
};

FunctionData**  MathFunctionModule::getFunctions(unsigned int *count_functions) {
    *count_functions = COUNT_MATH_FUNCTIONS;
    return math_functions;
};

MathFunctionModule::MathFunctionModule() {
    srand(time(NULL));

	math_functions = new FunctionData*[COUNT_MATH_FUNCTIONS];
	system_value function_id = 0;
    DEFINE_ALL_FUNCTIONS
};

void MathFunctionModule::destroy() {
	for (unsigned int j = 0; j < COUNT_MATH_FUNCTIONS; ++j) {
        delete math_functions[j];
    }
    delete[] math_functions;
    delete this;
};

FunctionResult* MathFunctionModule::executeFunction(system_value functionId, variable_value *args) {
	if ((functionId < 1) || (functionId > COUNT_MATH_FUNCTIONS)) {
        return NULL;
    }

	bool throw_exception = false;
	variable_value rez = 0;

    switch (functionId) {
		case 1: {
			rez = pow(*args, *(args + 1));
			break;
		}
		case 2: {
			rez = abs(*args);
			break;
		}
		case 3: {
			if (*args < 0) {
				throw_exception = true;
			} else {
				rez = sqrt(*args);
			}
			break;
		}
		case 4: {
			if (*args <= 0) {
				throw_exception = true;
			} else {
				rez = (variable_value)(rand() % ((int)(*args)) + ((int)(*(args + 1))));
			}
			break;
		}
		case 5: {
			rez = sin(*args);
			break;
		}
		case 6: {
			rez = cos(*args);
			break;
		}
		case 7: {
			rez = tan(*args);
			break;
		}
		case 8: {
			if ((*args < -1) && (*args > 1)) {
				throw_exception = true;
			} else {
				rez = asin(*args);
			}
			break;
		}
		case 9: {
			if ((*args < -1) && (*args > 1)) {
				throw_exception = true;
			} else {
				rez = acos(*args);
			}
			break;
		}
		case 10: {
			rez = atan(*args);
			break;
		}
		case 11: {
			rez = exp(*args);
			break;
		}
		case 12: {
			if (*args <= 0) {
				throw_exception = true;
			} else {
				rez = log(*args);
			}
			break;
		}
		case 13: {
			if (*args <= 0) {
				throw_exception = true;
			} else {
				rez = log10(*args);
			}
			break;
		}
    }

    if (throw_exception) {
		return new FunctionResult(0);
	} else {
		return new FunctionResult(1, rez);
	}
};

__declspec(dllexport) FunctionModule* getFunctionModuleObject() {
    return new MathFunctionModule();
};
<commit_msg>Some optimizations.<commit_after>#include <stdlib.h>
#include <exception>
#include <time.h>
#include <math.h>

#include "../module_headers/module.h"
#include "../module_headers/function_module.h"
#include "math_function_module.h"

const unsigned int COUNT_MATH_FUNCTIONS = 13;

#define ADD_MATH_FUNCTION(FUNCTION_NAME, COUNT_PARAMS, GIVE_EXCEPTION) \
	math_functions[function_id] = new FunctionData; \
	math_functions[function_id]->command_index = function_id + 1; \
	math_functions[function_id]->count_params = COUNT_PARAMS; \
	math_functions[function_id]->give_exception = GIVE_EXCEPTION; \
	math_functions[function_id]->name = FUNCTION_NAME; \
	function_id++;

#define DEFINE_ALL_FUNCTIONS \
	ADD_MATH_FUNCTION("pow",  2, false) \
	ADD_MATH_FUNCTION("abs",  1, false) \
	ADD_MATH_FUNCTION("sqrt", 1, true) \
	ADD_MATH_FUNCTION("rand", 2, true) \
	ADD_MATH_FUNCTION("sin",  1, false) \
	ADD_MATH_FUNCTION("cos",  1, false) \
	ADD_MATH_FUNCTION("tan",  1, false) \
	ADD_MATH_FUNCTION("asin", 1, true) \
	ADD_MATH_FUNCTION("acos", 1, true) \
	ADD_MATH_FUNCTION("atan", 1, false) \
	ADD_MATH_FUNCTION("exp",  1, false) \
	ADD_MATH_FUNCTION("log",  1, true) \
	ADD_MATH_FUNCTION("log10",1, true)

const char* MathFunctionModule::getUID() {
    return "Math_Functions_dll";
};

FunctionData**  MathFunctionModule::getFunctions(unsigned int *count_functions) {
    *count_functions = COUNT_MATH_FUNCTIONS;
    return math_functions;
};

MathFunctionModule::MathFunctionModule() {
    srand(time(NULL));

	math_functions = new FunctionData*[COUNT_MATH_FUNCTIONS];
	system_value function_id = 0;
    DEFINE_ALL_FUNCTIONS
};

void MathFunctionModule::destroy() {
	for (unsigned int j = 0; j < COUNT_MATH_FUNCTIONS; ++j) {
        delete math_functions[j];
    }
    delete[] math_functions;
    delete this;
};

FunctionResult* MathFunctionModule::executeFunction(system_value functionId, variable_value *args) {
	if ((functionId < 1) || (functionId > COUNT_MATH_FUNCTIONS)) {
        return NULL;
    }

	try {
		variable_value rez = 0;
		switch (functionId) {
			case 1: {
				rez = pow(*args, *(args + 1));
				break;
			}
			case 2: {
				rez = abs(*args);
				break;
			}
			case 3: {
				if (*args < 0) {
					throw std::exception();
				}
				rez = sqrt(*args);
				break;
			}
			case 4: {
				if (*args <= 0) {
					throw std::exception();
				}
				rez = (variable_value)(rand() % ((int)(*args)) + ((int)(*(args + 1))));
				break;
			}
			case 5: {
				rez = sin(*args);
				break;
			}
			case 6: {
				rez = cos(*args);
				break;
			}
			case 7: {
				rez = tan(*args);
				break;
			}
			case 8: {
				if ((*args < -1) && (*args > 1)) {
					throw std::exception();
				}
				rez = asin(*args);
				break;
			}
			case 9: {
				if ((*args < -1) && (*args > 1)) {
					throw std::exception();
				}
				rez = acos(*args);
				break;
			}
			case 10: {
				rez = atan(*args);
				break;
			}
			case 11: {
				rez = exp(*args);
				break;
			}
			case 12: {
				if (*args <= 0) {
					throw std::exception();
				}
				rez = log(*args);
				break;
			}
			case 13: {
				if (*args <= 0) {
					throw std::exception();
				}
				rez = log10(*args);
				break;
			}
		}
		return new FunctionResult(1, rez);
	} catch (...) {
		return new FunctionResult(0);
	}
};

__declspec(dllexport) FunctionModule* getFunctionModuleObject() {
    return new MathFunctionModule();
};
<|endoftext|>