<commit_before>#include <cstdio>
#include <cstdint>
#include <cstring>
#include <vector>
#include <algorithm>

#include <sys/time.h>

static inline int ascii_std(const uint8_t *data, int len)
{
    return !std::any_of(data, data+len, [] (int8_t b) { return b < 0; });
}

static inline int ascii_u64(const uint8_t *data, int len)
{
   uint8_t orall = 0;

    if (len >= 16) {
        union {
            uint64_t u64;
            uint8_t u8[8];
        } orr;

        uint64_t or1 = 0, or2 = 0;
        const uint8_t *data2 = data+8;

        while (len >= 16) {
            or1 |= *(const uint64_t *)data;
            or2 |= *(const uint64_t *)data2;
            data += 16;
            data2 += 16;
            len -= 16;
        }

        orr.u64 = or1 | or2;
        for (int i = 0; i < 8; ++i)
            orall |= orr.u8[i];
    }

    while (len--)
        orall |= *data++;

    return orall < 0x80;
}

#if defined(__x86_64__)
#include <x86intrin.h>

static inline int ascii_simd(const uint8_t *data, int len)
{
    if (len >= 32) {
        const uint8_t *data1 = data, *data2 = data+16;

        __m128i or1 = _mm_set1_epi8(0), or2 = or1;

        while (len >= 32) {
            __m128i input1 = _mm_lddqu_si128((const __m128i *)data1);
            __m128i input2 = _mm_lddqu_si128((const __m128i *)data2);

            or1 = _mm_or_si128(or1, input1);
            or2 = _mm_or_si128(or2, input2);

            data1 += 32;
            data2 += 32;
            len -= 32;
        }

        or1 = _mm_or_si128(or1, or2);
        if (_mm_movemask_epi8(_mm_cmplt_epi8(or1, _mm_set1_epi8(0))))
            return 0;

        data = data1;
    }

    return ascii_u64(data, len);
}

#elif defined(__aarch64__)
#include <arm_neon.h>

static inline int ascii_simd(const uint8_t *data, int len)
{
    if (len >= 32) {
        const uint8_t *data1 = data, *data2 = data+16;

        uint8x16_t or1 = vdupq_n_u8(0), or2 = or1;

        while (len >= 32) {
            const uint8x16_t input1 = vld1q_u8(data1);
            const uint8x16_t input2 = vld1q_u8(data2);

            or1 = vorrq_u8(or1, input1);
            or2 = vorrq_u8(or2, input2);

            data1 += 32;
            data2 += 32;
            len -= 32;
        }

        or1 = vorrq_u8(or1, or2);
        if (vmaxvq_u8(or1) >= 0x80)
            return 0;

        data = data1;
    }

    return ascii_u64(data, len);
}

#endif

struct ftab {
    const char *name;
    int (*func)(const uint8_t *data, int len);
};

static const std::vector<ftab> _f = {
    {
        .name = "std",
        .func = ascii_std,
    }, {
        .name = "u64",
        .func = ascii_u64,
    }, {
        .name = "simd",
        .func = ascii_simd,
    },
};

static void load_test_buf(uint8_t *data, int len)
{
    uint8_t v = 0;

    for (int i = 0; i < len; ++i) {
        data[i] = v++;
        v &= 0x7F;
    }
}

static void bench(const struct ftab &f, const uint8_t *data, int len)
{
    const int loops = 1024*1024*1024/len;
    int ret = 1;
    double time, size;
    struct timeval tv1, tv2;

    fprintf(stderr, "bench %s (%d bytes)... ", f.name, len);
    gettimeofday(&tv1, 0);
    for (int i = 0; i < loops; ++i)
        ret &= f.func(data, len);
    gettimeofday(&tv2, 0);
    printf("%s ", ret?"pass":"FAIL");

    time = tv2.tv_usec - tv1.tv_usec;
    time = time / 1000000 + tv2.tv_sec - tv1.tv_sec;
    size = ((double)len * loops) / (1024*1024);
    printf("%.2f MB/s\n", size / time);
}

static void test(const struct ftab &f, uint8_t *data, int len)
{
    int error = 0;

    fprintf(stderr, "test %s (%d bytes)... ", f.name, len);

    /* positive */
    error |= !f.func(data, len);

    /* negative */
    for (int i = 0; i < len; ++i) {
        data[i] += 0x80;
        error |= f.func(data, len);
        data[i] -= 0x80;
    }

    printf("%s\n", error ? "FAIL" : "pass");
}

/* ./ascii [test|bench] [alg] */
int main(int argc, const char *argv[])
{
    int do_test = 1, do_bench = 1;
    const char *alg = NULL;

    if (argc > 1) {
        do_bench &= !!strcmp(argv[1], "test");
        do_test &= !!strcmp(argv[1], "bench");
    }

    if (do_bench && argc > 2)
        alg = argv[2];

    const std::vector<int> size = { 9, 16+1, 32-1, 128+1, 1024+15,
                                    16*1024+1, 64*1024+15 };

    int max_size = *std::max_element(size.begin(), size.end());
    uint8_t *_data = new uint8_t[max_size+1];
    uint8_t *data = _data+1;    /* Unalign buffer address */

    load_test_buf(data, max_size);

    if (do_test) {
        printf("==================== Test ====================\n");
        for (int sz : size) {
            for (auto &f : _f) {
                test(f, data, sz);
            }
        }
    }

    if (do_bench) {
        printf("==================== Bench ====================\n");
        for (int sz : size) {
            for (auto &f : _f) {
                if (!alg || strcmp(alg, f.name) == 0)
                    bench(f, data, sz);
            }
            printf("-----------------------------------------------\n");
        }
    }

    delete _data;
    return 0;
}
<commit_msg>ascii.cpp: minor refinement<commit_after>#include <cstdio>
#include <cstdint>
#include <cstring>
#include <vector>
#include <algorithm>

#include <sys/time.h>

static inline int ascii_std(const uint8_t *data, int len)
{
    return !std::any_of(data, data+len, [] (int8_t b) { return b < 0; });
}

static inline int ascii_u64(const uint8_t *data, int len)
{
    uint8_t orall = 0;

    if (len >= 16) {
        union {
            uint64_t u64;
            uint32_t u32[2];
            uint16_t u16[4];
            uint8_t u8[8];
        } orr;

        uint64_t or1 = 0, or2 = 0;
        const uint8_t *data2 = data+8;

        while (len >= 16) {
            or1 |= *(const uint64_t *)data;
            or2 |= *(const uint64_t *)data2;
            data += 16;
            data2 += 16;
            len -= 16;
        }

        orr.u64 = or1 | or2;
        orr.u32[0] |= orr.u32[1];
        orr.u16[0] |= orr.u16[1];
        orall = orr.u8[0] | orr.u8[1];
    }

    while (len--)
        orall |= *data++;

    return orall < 0x80;
}

#if defined(__x86_64__)
#include <x86intrin.h>

static inline int ascii_simd(const uint8_t *data, int len)
{
    if (len >= 32) {
        const uint8_t *data2 = data+16;

        __m128i or1 = _mm_set1_epi8(0), or2 = or1;

        while (len >= 32) {
            __m128i input1 = _mm_lddqu_si128((const __m128i *)data);
            __m128i input2 = _mm_lddqu_si128((const __m128i *)data2);

            or1 = _mm_or_si128(or1, input1);
            or2 = _mm_or_si128(or2, input2);

            data += 32;
            data2 += 32;
            len -= 32;
        }

        or1 = _mm_or_si128(or1, or2);
        if (_mm_movemask_epi8(_mm_cmplt_epi8(or1, _mm_set1_epi8(0))))
            return 0;
    }

    return ascii_u64(data, len);
}

#elif defined(__aarch64__)
#include <arm_neon.h>

static inline int ascii_simd(const uint8_t *data, int len)
{
    if (len >= 32) {
        const uint8_t *data2 = data+16;

        uint8x16_t or1 = vdupq_n_u8(0), or2 = or1;

        while (len >= 32) {
            const uint8x16_t input1 = vld1q_u8(data);
            const uint8x16_t input2 = vld1q_u8(data2);

            or1 = vorrq_u8(or1, input1);
            or2 = vorrq_u8(or2, input2);

            data += 32;
            data2 += 32;
            len -= 32;
        }

        or1 = vorrq_u8(or1, or2);
        if (vmaxvq_u8(or1) >= 0x80)
            return 0;
    }

    return ascii_u64(data, len);
}

#endif

struct ftab {
    const char *name;
    int (*func)(const uint8_t *data, int len);
};

static const std::vector<ftab> _f = {
    {
        .name = "std",
        .func = ascii_std,
    }, {
        .name = "u64",
        .func = ascii_u64,
    }, {
        .name = "simd",
        .func = ascii_simd,
    },
};

static void load_test_buf(uint8_t *data, int len)
{
    uint8_t v = 0;

    for (int i = 0; i < len; ++i) {
        data[i] = v++;
        v &= 0x7F;
    }
}

static void bench(const struct ftab &f, const uint8_t *data, int len)
{
    const int loops = 1024*1024*1024/len;
    int ret = 1;
    double time, size;
    struct timeval tv1, tv2;

    fprintf(stderr, "bench %s (%d bytes)... ", f.name, len);
    gettimeofday(&tv1, 0);
    for (int i = 0; i < loops; ++i)
        ret &= f.func(data, len);
    gettimeofday(&tv2, 0);
    printf("%s ", ret?"pass":"FAIL");

    time = tv2.tv_usec - tv1.tv_usec;
    time = time / 1000000 + tv2.tv_sec - tv1.tv_sec;
    size = ((double)len * loops) / (1024*1024);
    printf("%.2f MB/s\n", size / time);
}

static void test(const struct ftab &f, uint8_t *data, int len)
{
    int error = 0;

    fprintf(stderr, "test %s (%d bytes)... ", f.name, len);

    /* positive */
    error |= !f.func(data, len);

    /* negative */
    for (int i = 0; i < len; ++i) {
        data[i] += 0x80;
        error |= f.func(data, len);
        data[i] -= 0x80;
    }

    printf("%s\n", error ? "FAIL" : "pass");
}

/* ./ascii [test|bench] [alg] */
int main(int argc, const char *argv[])
{
    int do_test = 1, do_bench = 1;
    const char *alg = NULL;

    if (argc > 1) {
        do_bench &= !!strcmp(argv[1], "test");
        do_test &= !!strcmp(argv[1], "bench");
    }

    if (do_bench && argc > 2)
        alg = argv[2];

    const std::vector<int> size = { 9, 16+1, 32-1, 128+1, 1024+15,
                                    16*1024+1, 64*1024+15 };

    int max_size = *std::max_element(size.begin(), size.end());
    uint8_t *_data = new uint8_t[max_size+1];
    uint8_t *data = _data+1;    /* Unalign buffer address */

    load_test_buf(data, max_size);

    if (do_test) {
        printf("==================== Test ====================\n");
        for (int sz : size) {
            for (auto &f : _f) {
                test(f, data, sz);
            }
        }
    }

    if (do_bench) {
        printf("==================== Bench ====================\n");
        for (int sz : size) {
            for (auto &f : _f) {
                if (!alg || strcmp(alg, f.name) == 0)
                    bench(f, data, sz);
            }
            printf("-----------------------------------------------\n");
        }
    }

    delete _data;
    return 0;
}
<|endoftext|>


<commit_before>#include "Enemy.h"
#include "SDL.h"
#include "InputHandler.h"

Enemy::Enemy(const LoaderParams* pParams) : SDLGameObject(pParams) { }

void Enemy::draw()
{
	SDLGameObject::draw(); //now we use SDLGameObject
}

//Update function for Enemy object
void Enemy::update()
{
	m_velocity.setX(0);
	m_velocity.setY(0);

	handleInput();	//handles the input from joystick [2nd controller]

	m_currentFrame = int(((SDL_GetTicks() / 100) % 6));

	SDLGameObject::update();
}

void Enemy::clean()
{
	//blank clean() function
}

//Enemy class uses the Second Joystick
void Enemy::handleInput()
{
	//check if a second controller is available and use it for enemy object
	if ((TheInputHandler::Instance()->joysticksInitialised()) && (SDL_NumJoysticks() > 1))
	{
		if ((TheInputHandler::Instance()->xvalue(1, 1) > 0) || (TheInputHandler::Instance()->xvalue(1, 1) < 0))
		{
			m_velocity.setX((float)1 * TheInputHandler::Instance()->xvalue(0, 1));
		}

		if ((TheInputHandler::Instance()->yvalue(1, 1) > 0) || (TheInputHandler::Instance()->yvalue(1, 1) < 0))
		{
			m_velocity.setY((float)1 * TheInputHandler::Instance()->yvalue(0, 1));
		}

		if ((TheInputHandler::Instance()->xvalue(1, 2) > 0) || (TheInputHandler::Instance()->xvalue(1, 2) < 0))
		{
			m_velocity.setX((float)1 * TheInputHandler::Instance()->xvalue(0, 2));
		}

		if ((TheInputHandler::Instance()->yvalue(1, 2) > 0) || (TheInputHandler::Instance()->yvalue(1, 2) < 0))
		{
			m_velocity.setY((float)1 * TheInputHandler::Instance()->yvalue(0, 2));
		}
	}
}<commit_msg>Enemy now also attains acceleration when Y is pressed along with analog movement<commit_after>#include "Enemy.h"
#include "SDL.h"
#include "InputHandler.h"

Enemy::Enemy(const LoaderParams* pParams) : SDLGameObject(pParams) { }

void Enemy::draw()
{
	SDLGameObject::draw(); //now we use SDLGameObject
}

//Update function for Enemy object
void Enemy::update()
{
	m_velocity.setX(0);
	m_velocity.setY(0);

	handleInput();	//handles the input from joystick [2nd controller]

	m_currentFrame = int(((SDL_GetTicks() / 100) % 6));

	SDLGameObject::update();
}

void Enemy::clean()
{
	//blank clean() function
}

//Enemy class uses the Second Joystick
void Enemy::handleInput()
{
	//check if a second controller is available and use it for enemy object
	if ((TheInputHandler::Instance()->joysticksInitialised()) && (SDL_NumJoysticks() > 1))
	{
		//for analog sticks of the second joystick
		if ((TheInputHandler::Instance()->xvalue(1, 1) > 0) || (TheInputHandler::Instance()->xvalue(1, 1) < 0))
		{
			m_velocity.setX((float)1 * TheInputHandler::Instance()->xvalue(1, 1));
			if (TheInputHandler::Instance()->getButtonState(0, 3))	//Button 3(Yellow)
			{
				//give the player some acceleration
				m_acceleration.setX(2 * TheInputHandler::Instance()->xvalue(1, 1));
			}
		}

		if ((TheInputHandler::Instance()->yvalue(1, 1) > 0) || (TheInputHandler::Instance()->yvalue(1, 1) < 0))
		{
			m_velocity.setY((float)1 * TheInputHandler::Instance()->yvalue(1, 1));

			//if we are moving the player with analog stick while pressing Y
			//it will get an acceleration of 2 in that direction
			if (TheInputHandler::Instance()->getButtonState(1, 3))	//Button 3(Yellow)
			{
				//give the player some acceleration
				m_acceleration.setY(2 * TheInputHandler::Instance()->yvalue(1, 1));
			}
		}

		if ((TheInputHandler::Instance()->xvalue(1, 2) > 0) || (TheInputHandler::Instance()->xvalue(1, 2) < 0))
		{
			m_velocity.setX((float)1 * TheInputHandler::Instance()->xvalue(1, 2));
			if (TheInputHandler::Instance()->getButtonState(1, 3))	//Button 3(Yellow)
			{
				//give the player some acceleration
				m_acceleration.setX(2 * TheInputHandler::Instance()->xvalue(1, 1));
			}
		}

		if ((TheInputHandler::Instance()->yvalue(1, 2) > 0) || (TheInputHandler::Instance()->yvalue(1, 2) < 0))
		{
			m_velocity.setY((float)1 * TheInputHandler::Instance()->yvalue(1, 2));
			if (TheInputHandler::Instance()->getButtonState(1, 3))	//Button 3(Yellow)
			{
				//give the player some acceleration
				m_acceleration.setY(2 * TheInputHandler::Instance()->yvalue(1, 1));
			}
		}
	}
}<|endoftext|>


<commit_before>/*
 Hume Library Version 0.4.2
 */

#include "Image.h"

namespace hm
{
	Image::Image()
	{

	}

	Image::Image(std::string filename, SDL_Renderer* renderer)
	{
		open(filename, renderer);
	}

	Image::~Image()
	{

	}

	void Image::open(std::string filename, SDL_Renderer* renderer)
	{
		// Unload a previous image.
		if(texture != nullptr)
		{
			SDL_DestroyTexture(texture);
			texture = nullptr;
		}

		SDL_Surface* surface = IMG_Load(filename.c_str());

		// Check if it was loaded.
		if(surface == NULL)
		{
			hm::Logger::log("Failed to open " + filename + ": " + IMG_GetError() + ".", hm::ERROR);
			return;
		}

		// Color key surface
		Uint32 key = SDL_MapRGB(surface->format, 0xFF, 0x00, 0xFF);
		SDL_SetColorKey(surface, SDL_TRUE, key);

		// Convert to texture.
		texture = SDL_CreateTextureFromSurface(renderer, surface);
		SDL_FreeSurface(surface);
		surface = nullptr;
		if(texture == nullptr)
		{
			hm::Logger::log("Failed to convert surface of " + filename + " to texture.", hm::ERROR);
			return;
		}

		// Get dimensions.
		SDL_QueryTexture(texture, nullptr, nullptr, &info.w, &info.h);

		return;
	}

	void Image::close()
	{
		if(texture != nullptr)
			SDL_DestroyTexture(texture);
		texture = nullptr;
		return;
	}

	void Image::setColorKey(Uint8 r, Uint8 g, Uint8 b)
	{
		color_key = { r, g, b, 0 };
		return;
	}
}
<commit_msg>Refactor with close function call.<commit_after>/*
 Hume Library Version 0.4.2
 */

#include "Image.h"

namespace hm
{
	Image::Image()
	{

	}

	Image::Image(std::string filename, SDL_Renderer* renderer)
	{
		open(filename, renderer);
	}

	Image::~Image()
	{

	}

	void Image::open(std::string filename, SDL_Renderer* renderer)
	{
		// Unload a previous image.
		if(texture != nullptr)
			close();

		SDL_Surface* surface = IMG_Load(filename.c_str());

		// Check if it was loaded.
		if(surface == NULL)
		{
			hm::Logger::log("Failed to open " + filename + ": " + IMG_GetError() + ".", hm::ERROR);
			return;
		}

		// Color key surface
		Uint32 key = SDL_MapRGB(surface->format, 0xFF, 0x00, 0xFF);
		SDL_SetColorKey(surface, SDL_TRUE, key);

		// Convert to texture.
		texture = SDL_CreateTextureFromSurface(renderer, surface);
		SDL_FreeSurface(surface);
		surface = nullptr;
		if(texture == nullptr)
		{
			hm::Logger::log("Failed to convert surface of " + filename + " to texture.", hm::ERROR);
			return;
		}

		// Get dimensions.
		SDL_QueryTexture(texture, nullptr, nullptr, &info.w, &info.h);

		return;
	}

	void Image::close()
	{
		if(texture != nullptr)
			SDL_DestroyTexture(texture);
		texture = nullptr;
		return;
	}

	void Image::setColorKey(Uint8 r, Uint8 g, Uint8 b)
	{
		color_key = { r, g, b, 0 };
		return;
	}
}
<|endoftext|>


<commit_before>#ifndef IMAP__H__
#define IMAP__H__

#include "zip.hpp"

#include <utility>
#include <type_traits>

namespace iter {

    // implementation details, users never invoke these directly
    namespace detail
    {
        template <typename F, typename Tuple, bool Done, int Total, int... N>
        struct call_impl
        {
            static auto call(F f, Tuple && t) -> decltype(f(t))
            {
                return call_impl<F,
                    Tuple,
                    Total == 1 + sizeof...(N),
                    Total,
                    N...,
                    sizeof...(N)>::call(f, std::forward<Tuple>(t));
            }
        };

        template <typename F, typename Tuple, int Total, int... N>
        struct call_impl<F, Tuple, true, Total, N...>
        {
            static auto call(F f, Tuple && t) -> decltype(f(t))
            {
                return f(std::get<N>(std::forward<Tuple>(t))...);
            }
        };

        // user invokes this
        template <typename F, typename Tuple>
        auto call(F f, Tuple && t) -> decltype(f(t))
        {
            typedef typename std::decay<Tuple>::type ttype;
            return call_impl<F,
                Tuple,
                0 == std::tuple_size<ttype>::value,
                std::tuple_size<ttype>::value>::call(f,std::forward<Tuple>(t));
        }
    }

    //Forward declarations of IMap and imap
    template <typename MapFunc, typename... Containers>
    class IMap;

    template <typename MapFunc, typename... Containers>
    IMap<MapFunc, Containers...> imap(MapFunc, Containers &...);

    template <typename MapFunc, typename... Containers>
    class IMap {
        // The imap function is the only thing allowed to create a IMap
        friend IMap imap<MapFunc, Containers...>(MapFunc, Containers & ...);

        // The type returned when dereferencing the Containers...::Iterator
        // XXX depends on zip using iterator_range.  would be nice if it didn't
        using Zipped =
            iterator_range<zip_iter<decltype(std::declval<Containers>().begin())...>>;

        using ZippedIterType = decltype(std::declval<Zipped>().begin());
            //typename std::remove_const<decltype(std::declval<Zipped>().begin())>::type;

        private:
            MapFunc map_func;
            Zipped zipped;

            // Value constructor for use only in the imap function
            IMap(MapFunc map_func, Containers & ... containers) :
                map_func(map_func),
                zipped(zip(containers...))
            { }
            IMap () = delete;
            IMap & operator=(const IMap &) = delete;

        public:
            IMap (const IMap &) = default;

            class Iterator {
                private:
                    MapFunc map_func;
                    mutable ZippedIterType zipiter;

                public:
                    Iterator (MapFunc map_func, ZippedIterType zipiter) :
                        map_func(map_func),
                        zipiter(zipiter)
                    { }

                    auto operator*() const ->
                        decltype(detail::call(this->map_func, *(this->zipiter)))
                    {
                        return detail::call(this->map_func, *(this->zipiter));
                    }

                    Iterator & operator++() {
                        ++this->zipiter;
                        return *this;
                    }

                    bool operator!=(const Iterator & other) const {
                        return this->zipiter != other.zipiter;
                    }
            };

            Iterator begin() const {
                return Iterator(this->map_func, this->zipped.begin());
            }

            Iterator end() const {
                return Iterator(this->map_func, this->zipped.end());
            }

    };

    // Helper function to instantiate a IMap
    template <typename MapFunc, typename... Containers>
    IMap<MapFunc, Containers...> imap(
            MapFunc map_func, Containers & ... containers) {
        return IMap<MapFunc, Containers...>(map_func, containers...);
    }

}

#endif //ifndef IMAP__H__
<commit_msg>imap fixed with crazy delctypes<commit_after>#ifndef IMAP__H__
#define IMAP__H__

#include "zip.hpp"

#include <utility>
#include <type_traits>

namespace iter {

    // implementation details, users never invoke these directly
    namespace detail
    {
        template <typename F, typename Tuple, bool Done, int Total, int... N>
        struct call_impl
        {
            static auto call(F f, Tuple && t) ->
                decltype(call_impl<F,
                    Tuple,
                    Total == 1 + sizeof...(N),
                    Total,
                    N...,
                    sizeof...(N)>::call(f, std::forward<Tuple>(t)))
            {
                return call_impl<F,
                    Tuple,
                    Total == 1 + sizeof...(N),
                    Total,
                    N...,
                    sizeof...(N)>::call(f, std::forward<Tuple>(t));
            }
        };

        template <typename F, typename Tuple, int Total, int... N>
        struct call_impl<F, Tuple, true, Total, N...>
        {
            static auto call(F f, Tuple && t) ->
                decltype(f(std::get<N>(std::forward<Tuple>(t))...))
            {
                return f(std::get<N>(std::forward<Tuple>(t))...);
            }
        };

        // user invokes this
        template <typename F, typename Tuple>
        auto call(F f, Tuple && t) ->
            decltype(call_impl<F,
                Tuple,
                0 == std::tuple_size<typename std::decay<Tuple>::type>::value,
                std::tuple_size<typename std::decay<Tuple>::type>::value>
                ::call(f,std::forward<Tuple>(t)))
        {
            typedef typename std::decay<Tuple>::type ttype;
            return call_impl<F,
                Tuple,
                0 == std::tuple_size<ttype>::value,
                std::tuple_size<ttype>::value>::call(f,std::forward<Tuple>(t));
        }
    }

    //Forward declarations of IMap and imap
    template <typename MapFunc, typename... Containers>
    class IMap;

    template <typename MapFunc, typename... Containers>
    IMap<MapFunc, Containers...> imap(MapFunc, Containers &...);

    template <typename MapFunc, typename... Containers>
    class IMap {
        // The imap function is the only thing allowed to create a IMap
        friend IMap imap<MapFunc, Containers...>(MapFunc, Containers & ...);

        // The type returned when dereferencing the Containers...::Iterator
        // XXX depends on zip using iterator_range.  would be nice if it didn't
        using Zipped =
            iterator_range<zip_iter<decltype(std::declval<Containers>().begin())...>>;

        using ZippedIterType = decltype(std::declval<Zipped>().begin());
            //typename std::remove_const<decltype(std::declval<Zipped>().begin())>::type;

        private:
            MapFunc map_func;
            Zipped zipped;

            // Value constructor for use only in the imap function
            IMap(MapFunc map_func, Containers & ... containers) :
                map_func(map_func),
                zipped(zip(containers...))
            { }
            IMap () = delete;
            IMap & operator=(const IMap &) = delete;

        public:
            IMap (const IMap &) = default;

            class Iterator {
                private:
                    MapFunc map_func;
                    mutable ZippedIterType zipiter;

                public:
                    Iterator (MapFunc map_func, ZippedIterType zipiter) :
                        map_func(map_func),
                        zipiter(zipiter)
                    { }

                    auto operator*() const ->
                        decltype(detail::call(this->map_func, *(this->zipiter)))
                    {
                        return detail::call(this->map_func, *(this->zipiter));
                    }

                    Iterator & operator++() {
                        ++this->zipiter;
                        return *this;
                    }

                    bool operator!=(const Iterator & other) const {
                        return this->zipiter != other.zipiter;
                    }
            };

            Iterator begin() const {
                return Iterator(this->map_func, this->zipped.begin());
            }

            Iterator end() const {
                return Iterator(this->map_func, this->zipped.end());
            }

    };

    // Helper function to instantiate a IMap
    template <typename MapFunc, typename... Containers>
    IMap<MapFunc, Containers...> imap(
            MapFunc map_func, Containers & ... containers) {
        return IMap<MapFunc, Containers...>(map_func, containers...);
    }

}

#endif //ifndef IMAP__H__
<|endoftext|>


<commit_before>#include <primitiv/config.h>

#include <primitiv/internal/opencl/utils.h>

namespace primitiv {
namespace devices {

std::shared_ptr<void> OpenCL::new_handle(const Shape &shape) {
  return state_->pool.allocate(sizeof(float) * shape.size());
}

}  // namespace devices
}  // namespace primitiv
<commit_msg>Fix OpenCL::new_handle.<commit_after>#include <primitiv/config.h>

#include <primitiv/internal/opencl/utils.h>

namespace primitiv {
namespace devices {

std::shared_ptr<void> OpenCL::new_handle(const Shape &shape, std::size_t * const allocated_size) {
  return state_->pool.allocate(sizeof(float) * shape.size(), allocated_size);
}

}  // namespace devices
}  // namespace primitiv
<|endoftext|>


<commit_before>#include <stdio.h>

#include <Halide.h>

#include <algorithm>
#include <iostream>

using namespace Halide;
using namespace Halide::Internal;

Scope<Expr> scope;
Scope<int> linearity;

Expr x = Variable::make(Int(32), "x");
Expr y = Variable::make(Int(32), "y");

constexpr int N = 100;
Expr v[N];

void fill_scope() {
    // e.g. let y = 4*x
    scope.push("y", 4*x);
    linearity.push("y", Linearity::Linear);

    for (int i = 0; i < N; ++i) {
        // e.g. let x0 = x*x
        //      let x1 = x0*x0
        //      let x2 = x1*x1
        //      ...
        std::string vi = "v" + int_to_string(i);
        v[i] = Variable::make(Int(32), vi);
        if (i == 0) {
            scope.push(vi, x*x);
        } else {
            scope.push(vi, v[i-1]*v[i-1]);
        }
        linearity.push(vi, Linearity::NonLinear);
    }
}

bool test_branches_in_var() {
    // Test basic functionality of branches_in_var
    Stmt s1 = IfThenElse::make(x < 0, Evaluate::make(0));
    Expr e1 = Select::make(x < 0, 0, x);
    Expr e2 = clamp(x, 0, 100);

    if (!branches_linearly_in_var(s1, "x", linearity)) {
        std::cout << "Expected to branch in x:\n" << s1;
        return false;
    }

    if (!branches_linearly_in_var(e1, "x", linearity)) {
        std::cout << "Expected to branch in x: " << e1 << "\n";
        return false;
    }

    if (branches_linearly_in_var(e2, "x", linearity)) {
        std::cout << "Expected not to branch in x: " << e2 << "\n";
        return false;
    }

    if (!branches_linearly_in_var(e2, "x", linearity, true)) {
        std::cout << "Expected to branch in x: " << e2 << "\n";
        return false;
    }

    // Test branches_in_var uses linearity correctly.
    Stmt s2 = IfThenElse::make(y < 0, Evaluate::make(0));
    Expr e3 = Select::make(y < 0, 0, x);

    if (!branches_linearly_in_var(s2, "x", linearity)) {
        std::cout << "Expected to branch in x:\n" << s2;
        return false;
    }

    if (!branches_linearly_in_var(e3, "x", linearity)) {
        std::cout << "Expected to branch in x: " << e3 << "\n";
        return false;
    }

    // Test branches_in_var doesn't explode with deeply nested linearitys.
    Expr vN = v[N-1];
    Stmt s3 = IfThenElse::make(vN < 0, Evaluate::make(0));

    if (branches_linearly_in_var(s3, "x", linearity)) {
        std::cout << "Expected not to branch in x:\n" << s3;
        return false;
    }

    return true;
}

bool test_normalize_branches() {
    Scope<Interval> bounds;
    Scope<int> free_vars;
    free_vars.push("x", 0);

    Stmt then_case = Evaluate::make(0);
    Stmt else_case = Evaluate::make(1);

    Stmt s1 = IfThenElse::make(x != 0 && x != 1, then_case, else_case);
    Stmt s1_ans1 = IfThenElse::make(x < 1, then_case, IfThenElse::make(1 < x, then_case, else_case));
    Stmt s1_nrm = normalize_branch_conditions(s1, "x", scope, bounds, free_vars);
    Stmt s1_ans = IfThenElse::make(
        x < 0, then_case, IfThenElse::make(
            0 < x, IfThenElse::make(1 < x, then_case, else_case), else_case));

    if (!equal(s1_nrm, s1_ans)) {
        std::cout << "Normalized:\n" << s1_nrm
                  << "Expected:\n" << s1_ans;
        return false;
    }

    Expr e1 = select(x != 0 && x != 1, 0, 1);
    Expr e1_ans1 = select(x < 1, 0, select(1 < x, 0, 1));
    Expr e1_nrm = normalize_branch_conditions(e1, "x", scope, bounds, free_vars);
    Expr e1_ans = select(x < 0, 0, select(0 < x, select(1 < x, 0, 1), 1));

    if (!equal(e1_nrm, e1_ans)) {
        std::cout << "Normalized: " << e1_nrm << "\n"
                  << "Expected: " << e1_ans << "\n";
        return false;
    }

    return true;
}

int main() {
    fill_scope();

    if (!test_branches_in_var()) {
        std::cout << "Failure.\n";
        return -1;
    }

    if (!test_normalize_branches()) {
        std::cout << "Failure.\n";
        return -1;
    }

    std::cout << "Success!\n";
    return 0;
}
<commit_msg>Added test to check the results of branches_linearly_in_vars to demonstrate the correctness of the changes in the last commit.<commit_after>#include <stdio.h>

#include <Halide.h>

#include <algorithm>
#include <iostream>

using namespace Halide;
using namespace Halide::Internal;

Scope<Expr> scope;
Scope<int> linearity;

Expr x = Variable::make(Int(32), "x");
Expr y = Variable::make(Int(32), "y");
Expr z = Variable::make(Int(32), "z");

constexpr int N = 100;
Expr v[N];

void fill_scope() {
    // e.g. let y = 4*x
    scope.push("y", 4*x);
    linearity.push("y", Linearity::Linear);

    for (int i = 0; i < N; ++i) {
        // e.g. let x0 = x*x
        //      let x1 = x0*x0
        //      let x2 = x1*x1
        //      ...
        std::string vi = "v" + int_to_string(i);
        v[i] = Variable::make(Int(32), vi);
        if (i == 0) {
            scope.push(vi, x*x);
        } else {
            scope.push(vi, v[i-1]*v[i-1]);
        }
        linearity.push(vi, Linearity::NonLinear);
    }
}

bool test_branches_in_var() {
    // Test basic functionality of branches_in_var
    Stmt s1 = IfThenElse::make(x < 0, Evaluate::make(0));
    Expr e1 = Select::make(x < 0, 0, x);
    Expr e2 = clamp(x, 0, 100);

    if (!branches_linearly_in_var(s1, "x", linearity)) {
        std::cout << "Expected to branch in x:\n" << s1;
        return false;
    }

    if (!branches_linearly_in_var(e1, "x", linearity)) {
        std::cout << "Expected to branch in x: " << e1 << "\n";
        return false;
    }

    if (branches_linearly_in_var(e2, "x", linearity)) {
        std::cout << "Expected not to branch in x: " << e2 << "\n";
        return false;
    }

    if (!branches_linearly_in_var(e2, "x", linearity, true)) {
        std::cout << "Expected to branch in x: " << e2 << "\n";
        return false;
    }

    // Test branches_in_var uses linearity correctly.
    Stmt s2 = IfThenElse::make(y < 0, Evaluate::make(0));
    Expr e3 = Select::make(y < 0, 0, x);

    if (!branches_linearly_in_var(s2, "x", linearity)) {
        std::cout << "Expected to branch in x:\n" << s2;
        return false;
    }

    if (!branches_linearly_in_var(e3, "x", linearity)) {
        std::cout << "Expected to branch in x: " << e3 << "\n";
        return false;
    }

    // Test branches_in_var doesn't explode with deeply nested linearitys.
    Expr vN = v[N-1];
    Stmt s3 = IfThenElse::make(vN < 0, Evaluate::make(0));

    if (branches_linearly_in_var(s3, "x", linearity)) {
        std::cout << "Expected not to branch in x:\n" << s3;
        return false;
    }

    Stmt s4 = LetStmt::make("z", e3, For::make("w", 0, 10, For::Serial, Store::make("s", 0, z)));

    if (!branches_linearly_in_var(s4, "x", linearity)) {
        std::cout << "Expected to branch in x: " << s4 << "\n";
        return false;
    }

    return true;
}

bool test_normalize_branches() {
    Scope<Interval> bounds;
    Scope<int> free_vars;
    free_vars.push("x", 0);

    Stmt then_case = Evaluate::make(0);
    Stmt else_case = Evaluate::make(1);

    Stmt s1 = IfThenElse::make(x != 0 && x != 1, then_case, else_case);
    Stmt s1_ans1 = IfThenElse::make(x < 1, then_case, IfThenElse::make(1 < x, then_case, else_case));
    Stmt s1_nrm = normalize_branch_conditions(s1, "x", scope, bounds, free_vars);
    Stmt s1_ans = IfThenElse::make(
        x < 0, then_case, IfThenElse::make(
            0 < x, IfThenElse::make(1 < x, then_case, else_case), else_case));

    if (!equal(s1_nrm, s1_ans)) {
        std::cout << "Normalized:\n" << s1_nrm
                  << "Expected:\n" << s1_ans;
        return false;
    }

    Expr e1 = select(x != 0 && x != 1, 0, 1);
    Expr e1_ans1 = select(x < 1, 0, select(1 < x, 0, 1));
    Expr e1_nrm = normalize_branch_conditions(e1, "x", scope, bounds, free_vars);
    Expr e1_ans = select(x < 0, 0, select(0 < x, select(1 < x, 0, 1), 1));

    if (!equal(e1_nrm, e1_ans)) {
        std::cout << "Normalized: " << e1_nrm << "\n"
                  << "Expected: " << e1_ans << "\n";
        return false;
    }

    return true;
}

int main() {
    fill_scope();

    if (!test_branches_in_var()) {
        std::cout << "Failure.\n";
        return -1;
    }

    if (!test_normalize_branches()) {
        std::cout << "Failure.\n";
        return -1;
    }

    std::cout << "Success!\n";
    return 0;
}
<|endoftext|>


<commit_before>#pragma once

#include "types.hh"
#include <iostream>

template<typename T>
static inline
void write(std::ostream& out, T val) {
    auto n_val = net::ntoh(val);
    out.write(reinterpret_cast<char*>(&n_val), sizeof(n_val));
}

// TODO: Add AllowsMissing parameter which will allow to optimize serialized format.
// Currently we default to AllowsMissing = true.
template<bool AllowPrefixes = false>
class tuple_type final : public abstract_type {
private:
    const std::vector<shared_ptr<abstract_type>> types;
    const bool _byte_order_equal;
public:
    using prefix_type = tuple_type<true>;
    using value_type = std::vector<bytes_opt>;

    tuple_type(std::vector<shared_ptr<abstract_type>> types)
        : abstract_type("tuple") // FIXME: append names of member types
        , types(types)
        , _byte_order_equal(std::all_of(types.begin(), types.end(), [] (auto t) {
                return t->is_byte_order_equal();
            }))
    { }

    prefix_type as_prefix() {
        return prefix_type(types);
    }

    /*
     * Format:
     *   <len(value1)><value1><len(value2)><value2>...
     *
     *   if value is missing then len(value) < 0
     */
    void serialize_value(const value_type& values, std::ostream& out) {
        if (AllowPrefixes) {
            assert(values.size() <= types.size());
        } else {
            assert(values.size() == types.size());
        }

        for (auto&& val : values) {
            if (!val) {
                write<uint32_t>(out, uint32_t(-1));
            } else {
                assert(val->size() <= std::numeric_limits<int32_t>::max());
                write<uint32_t>(out, uint32_t(val->size()));
                out.write(val->begin(), val->size());
            }
        }
    }
    bytes serialize_value(const value_type& values) {
        return ::serialize_value(*this, values);
    }
    bytes serialize_value_deep(const std::vector<boost::any>& values) {
        // TODO: Optimize
        std::vector<bytes_opt> partial;
        auto i = types.begin();
        for (auto&& component : values) {
            assert(i != types.end());
            partial.push_back({(*i++)->decompose(component)});
        }
        return serialize_value(partial);
    }
    bytes decompose_value(const value_type& values) {
        return ::serialize_value(*this, values);
    }
    value_type deserialize_value(std::istream& in) {
        std::vector<bytes_opt> result;
        result.reserve(types.size());

        for (auto&& type : types) {
            uint32_t u;
            auto n = in.rdbuf()->sgetn(reinterpret_cast<char *>(&u), sizeof(u));
            if (!n) {
                if (AllowPrefixes) {
                    return result;
                } else {
                    throw marshal_exception();
                }
            }
            if (n != sizeof(u)) {
                throw marshal_exception();
            }
            auto len = int32_t(net::ntoh(u));
            if (len < 0) {
                result.emplace_back();
            } else {
                result.emplace_back(bytes(bytes::initialized_later(), len));
                auto& b = *result.back();
                auto n = in.rdbuf()->sgetn(b.begin(), len);
                if (n != len) {
                    throw marshal_exception();
                }
            }
        }

        return result;
    }
    object_opt deserialize(std::istream& in) override {
        return {boost::any(deserialize_value(in))};
    }
    void serialize(const boost::any& obj, std::ostream& out) override {
        serialize_value(boost::any_cast<const value_type&>(obj), out);
    }
    virtual bool less(const bytes& b1, const bytes& b2) override {
        return compare(b1, b2) < 0;
    }
    virtual size_t hash(const bytes& v) override {
        if (_byte_order_equal) {
            return std::hash<bytes>()(v);
        }
        size_t h = 0;
        auto current_type = types.begin();
        for (auto&& elem : ::deserialize_value(*this, v)) {
            if (elem) {
                h ^= (*current_type)->hash(*elem);
            }
            ++current_type;
        }
        return h;
    }
    virtual int32_t compare(const bytes& b1, const bytes& b2) override {
        if (is_byte_order_comparable()) {
            return compare_unsigned(b1, b2);
        }

        auto v1 = ::deserialize_value(*this, b1);
        auto v2 = ::deserialize_value(*this, b2);

        if (v1.size() != v2.size()) {
            return v1.size() < v2.size() ? -1 : 1;
        }

        if (AllowPrefixes) {
            assert(v1.size() <= types.size());
        } else {
            assert(v1.size() == types.size());
        }

        auto i1 = v1.begin();
        auto i2 = v2.begin();
        auto current_type = types.begin();

        while (i1 != v1.end()) {
            bytes_opt& e1 = *i1++;
            bytes_opt& e2 = *i2++;
            if (bool(e1) != bool(e2)) {
                return e2 ? -1 : 1;
            }
            auto c = (*current_type++)->compare(*e1, *e2);
            if (c != 0) {
                return c;
            }
        }

        return 0;
    }
    virtual bool is_byte_order_equal() const override {
        return _byte_order_equal;
    }
    virtual bool is_byte_order_comparable() const override {
        // We're not byte order comparable because we encode component length as signed integer,
        // which is not byte order comparable.
        // TODO: make the length byte-order comparable by adding numeric_limits<int32_t>::min() when serializing
        return false;
    }
    virtual bytes from_string(sstring_view s) override {
        throw std::runtime_error("not implemented");
    }
    virtual sstring to_string(const bytes& b) override {
        throw std::runtime_error("not implemented");
    }
    /**
     * Returns true iff all components of 'prefix' are equal to corresponding
     * leading components of 'value'.
     *
     * The 'value' is assumed to be serialized using tuple_type<AllowPrefixes=false>
     */
    bool is_prefix_of(const bytes& prefix, const bytes& value) const {
        assert(AllowPrefixes);

        if (prefix.size() > value.size()) {
            return false;
        }

        bytes_view i1(prefix);
        bytes_view i2(value);

        for (auto&& type : types) {
            if (i1.empty()) {
                return true;
            }
            if (i2.empty()) {
                return false;
            }
            assert(i1.size() >= sizeof(int32_t));
            assert(i2.size() >= sizeof(int32_t));
            auto len1 = (int32_t) net::ntoh(*reinterpret_cast<const uint32_t*>(i1.begin()));
            auto len2 = (int32_t) net::ntoh(*reinterpret_cast<const uint32_t*>(i2.begin()));
            i1.remove_prefix(sizeof(int32_t));
            i2.remove_prefix(sizeof(int32_t));
            if ((len1 < 0) != (len2 < 0)) {
                // one is empty and another one is not
                return false;
            }
            if (len1 >= 0) {
                // both are not empty
                // TODO: make equal() accept bytes_view
                if (!type->equal(bytes(i1.begin(), i1.begin() + len1),
                    bytes(i2.begin(), i2.begin() + len2))) {
                    return false;
                }
                i1.remove_prefix((uint32_t) len1);
                i2.remove_prefix((uint32_t) len2);
            }
        }
        return true;
    }
    virtual ::shared_ptr<cql3::cql3_type> as_cql3_type() override {
        assert(0);
    }
};

using tuple_prefix = tuple_type<true>;
<commit_msg>tuple: Add missing copyright banner<commit_after>/*
 * Copyright (C) 2015 Cloudius Systems, Ltd.
 */

#pragma once

#include "types.hh"
#include <iostream>

template<typename T>
static inline
void write(std::ostream& out, T val) {
    auto n_val = net::ntoh(val);
    out.write(reinterpret_cast<char*>(&n_val), sizeof(n_val));
}

// TODO: Add AllowsMissing parameter which will allow to optimize serialized format.
// Currently we default to AllowsMissing = true.
template<bool AllowPrefixes = false>
class tuple_type final : public abstract_type {
private:
    const std::vector<shared_ptr<abstract_type>> types;
    const bool _byte_order_equal;
public:
    using prefix_type = tuple_type<true>;
    using value_type = std::vector<bytes_opt>;

    tuple_type(std::vector<shared_ptr<abstract_type>> types)
        : abstract_type("tuple") // FIXME: append names of member types
        , types(types)
        , _byte_order_equal(std::all_of(types.begin(), types.end(), [] (auto t) {
                return t->is_byte_order_equal();
            }))
    { }

    prefix_type as_prefix() {
        return prefix_type(types);
    }

    /*
     * Format:
     *   <len(value1)><value1><len(value2)><value2>...
     *
     *   if value is missing then len(value) < 0
     */
    void serialize_value(const value_type& values, std::ostream& out) {
        if (AllowPrefixes) {
            assert(values.size() <= types.size());
        } else {
            assert(values.size() == types.size());
        }

        for (auto&& val : values) {
            if (!val) {
                write<uint32_t>(out, uint32_t(-1));
            } else {
                assert(val->size() <= std::numeric_limits<int32_t>::max());
                write<uint32_t>(out, uint32_t(val->size()));
                out.write(val->begin(), val->size());
            }
        }
    }
    bytes serialize_value(const value_type& values) {
        return ::serialize_value(*this, values);
    }
    bytes serialize_value_deep(const std::vector<boost::any>& values) {
        // TODO: Optimize
        std::vector<bytes_opt> partial;
        auto i = types.begin();
        for (auto&& component : values) {
            assert(i != types.end());
            partial.push_back({(*i++)->decompose(component)});
        }
        return serialize_value(partial);
    }
    bytes decompose_value(const value_type& values) {
        return ::serialize_value(*this, values);
    }
    value_type deserialize_value(std::istream& in) {
        std::vector<bytes_opt> result;
        result.reserve(types.size());

        for (auto&& type : types) {
            uint32_t u;
            auto n = in.rdbuf()->sgetn(reinterpret_cast<char *>(&u), sizeof(u));
            if (!n) {
                if (AllowPrefixes) {
                    return result;
                } else {
                    throw marshal_exception();
                }
            }
            if (n != sizeof(u)) {
                throw marshal_exception();
            }
            auto len = int32_t(net::ntoh(u));
            if (len < 0) {
                result.emplace_back();
            } else {
                result.emplace_back(bytes(bytes::initialized_later(), len));
                auto& b = *result.back();
                auto n = in.rdbuf()->sgetn(b.begin(), len);
                if (n != len) {
                    throw marshal_exception();
                }
            }
        }

        return result;
    }
    object_opt deserialize(std::istream& in) override {
        return {boost::any(deserialize_value(in))};
    }
    void serialize(const boost::any& obj, std::ostream& out) override {
        serialize_value(boost::any_cast<const value_type&>(obj), out);
    }
    virtual bool less(const bytes& b1, const bytes& b2) override {
        return compare(b1, b2) < 0;
    }
    virtual size_t hash(const bytes& v) override {
        if (_byte_order_equal) {
            return std::hash<bytes>()(v);
        }
        size_t h = 0;
        auto current_type = types.begin();
        for (auto&& elem : ::deserialize_value(*this, v)) {
            if (elem) {
                h ^= (*current_type)->hash(*elem);
            }
            ++current_type;
        }
        return h;
    }
    virtual int32_t compare(const bytes& b1, const bytes& b2) override {
        if (is_byte_order_comparable()) {
            return compare_unsigned(b1, b2);
        }

        auto v1 = ::deserialize_value(*this, b1);
        auto v2 = ::deserialize_value(*this, b2);

        if (v1.size() != v2.size()) {
            return v1.size() < v2.size() ? -1 : 1;
        }

        if (AllowPrefixes) {
            assert(v1.size() <= types.size());
        } else {
            assert(v1.size() == types.size());
        }

        auto i1 = v1.begin();
        auto i2 = v2.begin();
        auto current_type = types.begin();

        while (i1 != v1.end()) {
            bytes_opt& e1 = *i1++;
            bytes_opt& e2 = *i2++;
            if (bool(e1) != bool(e2)) {
                return e2 ? -1 : 1;
            }
            auto c = (*current_type++)->compare(*e1, *e2);
            if (c != 0) {
                return c;
            }
        }

        return 0;
    }
    virtual bool is_byte_order_equal() const override {
        return _byte_order_equal;
    }
    virtual bool is_byte_order_comparable() const override {
        // We're not byte order comparable because we encode component length as signed integer,
        // which is not byte order comparable.
        // TODO: make the length byte-order comparable by adding numeric_limits<int32_t>::min() when serializing
        return false;
    }
    virtual bytes from_string(sstring_view s) override {
        throw std::runtime_error("not implemented");
    }
    virtual sstring to_string(const bytes& b) override {
        throw std::runtime_error("not implemented");
    }
    /**
     * Returns true iff all components of 'prefix' are equal to corresponding
     * leading components of 'value'.
     *
     * The 'value' is assumed to be serialized using tuple_type<AllowPrefixes=false>
     */
    bool is_prefix_of(const bytes& prefix, const bytes& value) const {
        assert(AllowPrefixes);

        if (prefix.size() > value.size()) {
            return false;
        }

        bytes_view i1(prefix);
        bytes_view i2(value);

        for (auto&& type : types) {
            if (i1.empty()) {
                return true;
            }
            if (i2.empty()) {
                return false;
            }
            assert(i1.size() >= sizeof(int32_t));
            assert(i2.size() >= sizeof(int32_t));
            auto len1 = (int32_t) net::ntoh(*reinterpret_cast<const uint32_t*>(i1.begin()));
            auto len2 = (int32_t) net::ntoh(*reinterpret_cast<const uint32_t*>(i2.begin()));
            i1.remove_prefix(sizeof(int32_t));
            i2.remove_prefix(sizeof(int32_t));
            if ((len1 < 0) != (len2 < 0)) {
                // one is empty and another one is not
                return false;
            }
            if (len1 >= 0) {
                // both are not empty
                // TODO: make equal() accept bytes_view
                if (!type->equal(bytes(i1.begin(), i1.begin() + len1),
                    bytes(i2.begin(), i2.begin() + len2))) {
                    return false;
                }
                i1.remove_prefix((uint32_t) len1);
                i2.remove_prefix((uint32_t) len2);
            }
        }
        return true;
    }
    virtual ::shared_ptr<cql3::cql3_type> as_cql3_type() override {
        assert(0);
    }
};

using tuple_prefix = tuple_type<true>;
<|endoftext|>


<commit_before>//===--------------------- cxa_thread_atexit_test.cpp ---------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// REQUIRES: linux

#include <assert.h>
#include <cxxabi.h>

static bool AtexitImplCalled = false;

extern "C" int __cxa_thread_atexit_impl(void (*dtor)(void *), void *obj,
                                        void *dso_symbol) {
  assert(dtor == reinterpret_cast<void (*)(void *)>(1));
  assert(obj == reinterpret_cast<void *>(2));
  assert(dso_symbol == reinterpret_cast<void *>(3));
  AtexitImplCalled = true;
  return 4;
}

int main() {
  int RV = __cxxabiv1::__cxa_thread_atexit(
      reinterpret_cast<void (*)(void *)>(1), reinterpret_cast<void *>(2),
      reinterpret_cast<void *>(3));
  assert(RV == 4);
  assert(AtexitImplCalled);
  return 0;
}
<commit_msg>Mark thread exit test as unsupported w/o threads<commit_after>//===--------------------- cxa_thread_atexit_test.cpp ---------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: libcppabi-no-threads
// REQUIRES: linux

#include <assert.h>
#include <cxxabi.h>

static bool AtexitImplCalled = false;

extern "C" int __cxa_thread_atexit_impl(void (*dtor)(void *), void *obj,
                                        void *dso_symbol) {
  assert(dtor == reinterpret_cast<void (*)(void *)>(1));
  assert(obj == reinterpret_cast<void *>(2));
  assert(dso_symbol == reinterpret_cast<void *>(3));
  AtexitImplCalled = true;
  return 4;
}

int main() {
  int RV = __cxxabiv1::__cxa_thread_atexit(
      reinterpret_cast<void (*)(void *)>(1), reinterpret_cast<void *>(2),
      reinterpret_cast<void *>(3));
  assert(RV == 4);
  assert(AtexitImplCalled);
  return 0;
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.9  2003/12/15 17:23:48  cargilld
 * psvi updates; cleanup revisits and bug fixes
 *
 * Revision 1.8  2003/11/27 16:42:00  neilg
 * fixes for segfaults and infinite loops in schema component model implementation; thanks to David Cargill
 *
 * Revision 1.7  2003/11/25 18:08:31  knoaman
 * Misc. PSVI updates. Thanks to David Cargill.
 *
 * Revision 1.6  2003/11/21 17:19:30  knoaman
 * PSVI update.
 *
 * Revision 1.5  2003/11/14 22:47:53  neilg
 * fix bogus log message from previous commit...
 *
 * Revision 1.4  2003/11/14 22:33:30  neilg
 * Second phase of schema component model implementation.
 * Implement XSModel, XSNamespaceItem, and the plumbing necessary
 * to connect them to the other components.
 * Thanks to David Cargill.
 *
 * Revision 1.3  2003/11/10 21:56:54  neilg
 * make internal code use the new, stateless, method of traversing attribute lists
 *
 * Revision 1.2  2003/11/06 15:30:04  neilg
 * first part of PSVI/schema component model implementation, thanks to David Cargill.  This covers setting the PSVIHandler on parser objects, as well as implementing XSNotation, XSSimpleTypeDefinition, XSIDCDefinition, and most of XSWildcard, XSComplexTypeDefinition, XSElementDeclaration, XSAttributeDeclaration and XSAttributeUse.
 *
 * Revision 1.1  2003/09/16 14:33:36  neilg
 * PSVI/schema component model classes, with Makefile/configuration changes necessary to build them
 *
 */

#include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp>
#include <xercesc/framework/psvi/XSWildcard.hpp>
#include <xercesc/framework/psvi/XSSimpleTypeDefinition.hpp>
#include <xercesc/framework/psvi/XSAttributeUse.hpp>
#include <xercesc/framework/psvi/XSModel.hpp>
#include <xercesc/framework/psvi/XSAnnotation.hpp>
#include <xercesc/framework/psvi/XSParticle.hpp>
#include <xercesc/validators/schema/ComplexTypeInfo.hpp>
#include <xercesc/validators/schema/SchemaElementDecl.hpp>
#include <xercesc/validators/schema/SchemaAttDefList.hpp>

XERCES_CPP_NAMESPACE_BEGIN

// ---------------------------------------------------------------------------
//  XSComplexTypeDefinition: Constructors and Destructor
// ---------------------------------------------------------------------------
XSComplexTypeDefinition::XSComplexTypeDefinition
(
    ComplexTypeInfo* const          complexTypeInfo
    , XSWildcard* const             xsWildcard
    , XSSimpleTypeDefinition* const xsSimpleType
    , XSAttributeUseList* const     xsAttList
    , XSTypeDefinition* const       xsBaseType
    , XSParticle* const             xsParticle
    , XSAnnotation* const           headAnnot
    , XSModel* const                xsModel
    , MemoryManager* const          manager
)
    : XSTypeDefinition(COMPLEX_TYPE, xsBaseType, xsModel, manager)
    , fComplexTypeInfo(complexTypeInfo)
    , fXSWildcard(xsWildcard)
    , fXSAttributeUseList(xsAttList)
    , fXSSimpleTypeDefinition(xsSimpleType)
    , fXSAnnotationList(0)
    , fParticle(xsParticle)
    , fProhibitedSubstitution(0)
{
    int blockset = fComplexTypeInfo->getBlockSet();
    if (blockset)
    {
        if (blockset & SchemaSymbols::XSD_EXTENSION)
            fProhibitedSubstitution |= XSConstants::DERIVATION_EXTENSION;

        if (blockset & SchemaSymbols::XSD_RESTRICTION)
            fProhibitedSubstitution |= XSConstants::DERIVATION_RESTRICTION;
    }

    if (headAnnot)
    {
        fXSAnnotationList = new (manager) RefVectorOf<XSAnnotation>(1, false, manager);
        XSAnnotation* annot = headAnnot;

        do
        {
            fXSAnnotationList->addElement(annot);
            annot = annot->getNext();
        } while (annot);
    }
}

XSComplexTypeDefinition::~XSComplexTypeDefinition()
{
    // don't delete fXSWildcard - deleted by XSModel
    // don't delete fXSSimpleTypeDefinition - deleted by XSModel
    if (fXSAttributeUseList)
        delete fXSAttributeUseList;

    if (fXSAnnotationList)
        delete fXSAnnotationList;

    if (fParticle)
        delete fParticle;
}

// ---------------------------------------------------------------------------
//  XSComplexTypeDefinition: access methods
// ---------------------------------------------------------------------------
XSConstants::DERIVATION_TYPE XSComplexTypeDefinition::getDerivationMethod() const
{
    switch(fComplexTypeInfo->getDerivedBy()) {
        case SchemaSymbols::XSD_RESTRICTION:
            return XSConstants::DERIVATION_RESTRICTION;
        case SchemaSymbols::XSD_EXTENSION:
            return XSConstants::DERIVATION_EXTENSION;
        default:
            return XSConstants::DERIVATION_NONE;
    }
}

bool XSComplexTypeDefinition::getAbstract() const
{
    return fComplexTypeInfo->getAbstract();
}

XSComplexTypeDefinition::CONTENT_TYPE XSComplexTypeDefinition::getContentType() const
{
    switch(fComplexTypeInfo->getContentType()) {
        case SchemaElementDecl::Simple:
            return CONTENTTYPE_SIMPLE;
        case SchemaElementDecl::Empty:
            return CONTENTTYPE_EMPTY;
        case SchemaElementDecl::Children:
            return CONTENTTYPE_ELEMENT;
        default:
            //case SchemaElementDecl::Mixed_Complex:
            //case SchemaElementDecl::Mixed_Simple:
            //case SchemaElementDecl::Any:
            return CONTENTTYPE_MIXED;
    }
}

bool XSComplexTypeDefinition::isProhibitedSubstitution(XSConstants::DERIVATION_TYPE toTest)
{
    if (fProhibitedSubstitution & toTest)
        return true;

    return false;
}

XSAnnotationList *XSComplexTypeDefinition::getAnnotations()
{
    return fXSAnnotationList;
}

// ---------------------------------------------------------------------------
//  XSComplexTypeDefinition: virtual methods
// ---------------------------------------------------------------------------
const XMLCh *XSComplexTypeDefinition::getName()
{
    return fComplexTypeInfo->getTypeLocalName();
}

const XMLCh *XSComplexTypeDefinition::getNamespace()
{
    return fComplexTypeInfo->getTypeUri();
}

XSNamespaceItem *XSComplexTypeDefinition::getNamespaceItem()
{
    return fXSModel->getNamespaceItem(getNamespace());
}

bool XSComplexTypeDefinition::getAnonymous() const
{
    return fComplexTypeInfo->getAnonymous();
}

XSTypeDefinition *XSComplexTypeDefinition::getBaseType()
{
    return fBaseType;
}

bool XSComplexTypeDefinition::derivedFromType(const XSTypeDefinition * const ancestorType)
{
    if (!ancestorType)
        return false;

    XSTypeDefinition* type = this;

    while (type && (type != ancestorType))
    {
        type = type->getBaseType();
    }

    return (type == ancestorType);
}

XERCES_CPP_NAMESPACE_END
<commit_msg>PSVI: process 'final' information<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.10  2003/12/19 15:09:47  knoaman
 * PSVI: process 'final' information
 *
 * Revision 1.9  2003/12/15 17:23:48  cargilld
 * psvi updates; cleanup revisits and bug fixes
 *
 * Revision 1.8  2003/11/27 16:42:00  neilg
 * fixes for segfaults and infinite loops in schema component model implementation; thanks to David Cargill
 *
 * Revision 1.7  2003/11/25 18:08:31  knoaman
 * Misc. PSVI updates. Thanks to David Cargill.
 *
 * Revision 1.6  2003/11/21 17:19:30  knoaman
 * PSVI update.
 *
 * Revision 1.5  2003/11/14 22:47:53  neilg
 * fix bogus log message from previous commit...
 *
 * Revision 1.4  2003/11/14 22:33:30  neilg
 * Second phase of schema component model implementation.
 * Implement XSModel, XSNamespaceItem, and the plumbing necessary
 * to connect them to the other components.
 * Thanks to David Cargill.
 *
 * Revision 1.3  2003/11/10 21:56:54  neilg
 * make internal code use the new, stateless, method of traversing attribute lists
 *
 * Revision 1.2  2003/11/06 15:30:04  neilg
 * first part of PSVI/schema component model implementation, thanks to David Cargill.  This covers setting the PSVIHandler on parser objects, as well as implementing XSNotation, XSSimpleTypeDefinition, XSIDCDefinition, and most of XSWildcard, XSComplexTypeDefinition, XSElementDeclaration, XSAttributeDeclaration and XSAttributeUse.
 *
 * Revision 1.1  2003/09/16 14:33:36  neilg
 * PSVI/schema component model classes, with Makefile/configuration changes necessary to build them
 *
 */

#include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp>
#include <xercesc/framework/psvi/XSWildcard.hpp>
#include <xercesc/framework/psvi/XSSimpleTypeDefinition.hpp>
#include <xercesc/framework/psvi/XSAttributeUse.hpp>
#include <xercesc/framework/psvi/XSModel.hpp>
#include <xercesc/framework/psvi/XSAnnotation.hpp>
#include <xercesc/framework/psvi/XSParticle.hpp>
#include <xercesc/validators/schema/ComplexTypeInfo.hpp>
#include <xercesc/validators/schema/SchemaElementDecl.hpp>
#include <xercesc/validators/schema/SchemaAttDefList.hpp>

XERCES_CPP_NAMESPACE_BEGIN

// ---------------------------------------------------------------------------
//  XSComplexTypeDefinition: Constructors and Destructor
// ---------------------------------------------------------------------------
XSComplexTypeDefinition::XSComplexTypeDefinition
(
    ComplexTypeInfo* const          complexTypeInfo
    , XSWildcard* const             xsWildcard
    , XSSimpleTypeDefinition* const xsSimpleType
    , XSAttributeUseList* const     xsAttList
    , XSTypeDefinition* const       xsBaseType
    , XSParticle* const             xsParticle
    , XSAnnotation* const           headAnnot
    , XSModel* const                xsModel
    , MemoryManager* const          manager
)
    : XSTypeDefinition(COMPLEX_TYPE, xsBaseType, xsModel, manager)
    , fComplexTypeInfo(complexTypeInfo)
    , fXSWildcard(xsWildcard)
    , fXSAttributeUseList(xsAttList)
    , fXSSimpleTypeDefinition(xsSimpleType)
    , fXSAnnotationList(0)
    , fParticle(xsParticle)
    , fProhibitedSubstitution(0)
{
    int blockset = fComplexTypeInfo->getBlockSet();
    if (blockset)
    {
        if (blockset & SchemaSymbols::XSD_EXTENSION)
            fProhibitedSubstitution |= XSConstants::DERIVATION_EXTENSION;

        if (blockset & SchemaSymbols::XSD_RESTRICTION)
            fProhibitedSubstitution |= XSConstants::DERIVATION_RESTRICTION;
    }

    int finalSet = fComplexTypeInfo->getFinalSet();
    if (finalSet)
    {
        if (finalSet & SchemaSymbols::XSD_EXTENSION)
            fFinal |= XSConstants::DERIVATION_EXTENSION;

        if (finalSet & SchemaSymbols::XSD_RESTRICTION)
            fFinal |= XSConstants::DERIVATION_RESTRICTION;
    }

    if (headAnnot)
    {
        fXSAnnotationList = new (manager) RefVectorOf<XSAnnotation>(1, false, manager);
        XSAnnotation* annot = headAnnot;

        do
        {
            fXSAnnotationList->addElement(annot);
            annot = annot->getNext();
        } while (annot);
    }
}

XSComplexTypeDefinition::~XSComplexTypeDefinition()
{
    // don't delete fXSWildcard - deleted by XSModel
    // don't delete fXSSimpleTypeDefinition - deleted by XSModel
    if (fXSAttributeUseList)
        delete fXSAttributeUseList;

    if (fXSAnnotationList)
        delete fXSAnnotationList;

    if (fParticle)
        delete fParticle;
}

// ---------------------------------------------------------------------------
//  XSComplexTypeDefinition: access methods
// ---------------------------------------------------------------------------
XSConstants::DERIVATION_TYPE XSComplexTypeDefinition::getDerivationMethod() const
{
    switch(fComplexTypeInfo->getDerivedBy()) {
        case SchemaSymbols::XSD_RESTRICTION:
            return XSConstants::DERIVATION_RESTRICTION;
        case SchemaSymbols::XSD_EXTENSION:
            return XSConstants::DERIVATION_EXTENSION;
        default:
            return XSConstants::DERIVATION_NONE;
    }
}

bool XSComplexTypeDefinition::getAbstract() const
{
    return fComplexTypeInfo->getAbstract();
}

XSComplexTypeDefinition::CONTENT_TYPE XSComplexTypeDefinition::getContentType() const
{
    switch(fComplexTypeInfo->getContentType()) {
        case SchemaElementDecl::Simple:
            return CONTENTTYPE_SIMPLE;
        case SchemaElementDecl::Empty:
            return CONTENTTYPE_EMPTY;
        case SchemaElementDecl::Children:
            return CONTENTTYPE_ELEMENT;
        default:
            //case SchemaElementDecl::Mixed_Complex:
            //case SchemaElementDecl::Mixed_Simple:
            //case SchemaElementDecl::Any:
            return CONTENTTYPE_MIXED;
    }
}

bool XSComplexTypeDefinition::isProhibitedSubstitution(XSConstants::DERIVATION_TYPE toTest)
{
    if (fProhibitedSubstitution & toTest)
        return true;

    return false;
}

XSAnnotationList *XSComplexTypeDefinition::getAnnotations()
{
    return fXSAnnotationList;
}

// ---------------------------------------------------------------------------
//  XSComplexTypeDefinition: virtual methods
// ---------------------------------------------------------------------------
const XMLCh *XSComplexTypeDefinition::getName()
{
    return fComplexTypeInfo->getTypeLocalName();
}

const XMLCh *XSComplexTypeDefinition::getNamespace()
{
    return fComplexTypeInfo->getTypeUri();
}

XSNamespaceItem *XSComplexTypeDefinition::getNamespaceItem()
{
    return fXSModel->getNamespaceItem(getNamespace());
}

bool XSComplexTypeDefinition::getAnonymous() const
{
    return fComplexTypeInfo->getAnonymous();
}

XSTypeDefinition *XSComplexTypeDefinition::getBaseType()
{
    return fBaseType;
}

bool XSComplexTypeDefinition::derivedFromType(const XSTypeDefinition * const ancestorType)
{
    if (!ancestorType)
        return false;

    XSTypeDefinition* type = this;

    while (type && (type != ancestorType))
    {
        type = type->getBaseType();
    }

    return (type == ancestorType);
}

XERCES_CPP_NAMESPACE_END
<|endoftext|>


<commit_before>#include <iostream>

using namespace std;

#include "functions.h"
#include "player.h"

void turn(int playerNumber)
{
    int cityToWorkOn;
	for (int i = 0; i < 5; i++)
	{
        realPlayer[playerNumber].cities[i].getBlacksmithBonus();
	}
	while (true)
	{
        cout << "(1-3) Visit a city." << endl;
        cout << "(4) End Turn." << endl;
        cout << "What do you want to do: ";
        cin >> cityToWorkOn;
        cityToWorkOn -= 1;
        cout << endl;
        if (cityToWorkOn == 3)
        {
            return;
        }
        else
        {
            visitCity(cityToWorkOn, playerNumber);
        }
	}
}

void visitCity(int cityToWorkOn, int playerNumber)
{
    int thingToBeUpgraded, amountToBeUpgradedBy, answer;
    signed int result;
    while (true)
	{
		cout << "(1) Upgrade Buildings" << endl;
		cout << "(2) Hire Troops" << endl;
		cout << "(3) Not implemented." << endl;
		cout << "(4) Check Money" << endl;
		cout << "(5) Check Buildings" << endl;
		cout << "(6) Check Troops" << endl;
		cout << "(7) Exit City" << endl;
		cout << "What operation do you want to do: ";
		cin >> answer;
		cout << endl;
		switch (answer)
		{
			case 1:
				cout << "(0) Castle" << endl;
				cout << "(1) Training Camp" << endl;
				cout << "(2) Farms" << endl;
				cout << "(3-7) Blacksmiths" << endl;
				cout << "What building do you want to upgrade: ";
				cin >> thingToBeUpgraded;
				cout << endl;
				cout << "How many levels do you want to upgrade the building by: ";
				cin >> amountToBeUpgradedBy;
				cout << endl << endl;
				result = realPlayer[playerNumber].cities[cityToWorkOn].setBuilding(0, amountToBeUpgradedBy, thingToBeUpgraded);
				if (result == -1)
				{
					cout << "Upgrade failed for some reason. Could be no money or building level maxed out." << endl;
				}
				else
				{
					cout << "Building upgrade succeeded!" << endl;
					cout << "The chosen building now has " << result << " levels." << endl;
				}
				break;
			case 2:
                cout << "(0) Pikeman" << endl;
				cout << "(1) Swordsman" << endl;
				cout << "(2) Medic" << endl;
				cout << "(3) Archer" << endl;
				cout << "(4) Horseman" << endl;
				cout << "(5) SuperSoldier" << endl;
				cout << "What type of soldier do you want to recruit: ";
				cin >> thingToBeUpgraded;
				cout << endl;
				cout << "How many soldiers do you want to recruit: ";
				cin >> amountToBeUpgradedBy;
				cout << endl << endl;
				result = realPlayer[playerNumber].cities[cityToWorkOn].setSoldier(0, amountToBeUpgradedBy, thingToBeUpgraded);
				if (result == -1)
				{
					cout << "Upgrade failed for some reason. Could be no money or food." << endl;
				}
				else
				{
					cout << "Soldier recruiting succeeded!" << endl;
					cout << "The chosen soldiertype now has " << result << " soldiers in it." << endl;
				}
				break;
			case 3:
				cout << "This feature is not implemented." << endl;
				break;
			case 4:
				cout << "You have: $" << realPlayer[playerNumber].cities[cityToWorkOn].getMoney() << " in this city." << endl;
				break;
			case 5:
                cout << "(0) Castle" << endl;
				cout << "(1) Training Camp" << endl;
				cout << "(2) Farms" << endl;
				cout << "(3-7) Blacksmith (1-5)" << endl;
				cout << "What building do you want to inspect: ";
				cin >> thingToBeUpgraded;
				cout << endl;
				cout << "The cost of a level upgrade to building " << thingToBeUpgraded << " is " << realPlayer[playerNumber].cities[cityToWorkOn].buildingInfo(0, thingToBeUpgraded) << endl;
				cout << "The maximum level of building " << thingToBeUpgraded << " is " << realPlayer[playerNumber].cities[cityToWorkOn].buildingInfo(1, thingToBeUpgraded) << endl;
				cout << "The current level of building " << thingToBeUpgraded << " is " << realPlayer[playerNumber].cities[cityToWorkOn].buildingInfo(2, thingToBeUpgraded) << endl;
				break;
			case 6:
                cout << "(0) Pikeman" << endl;
				cout << "(1) Swordsman" << endl;
				cout << "(2) Medic" << endl;
				cout << "(3) Archer" << endl;
				cout << "(4) Horseman" << endl;
				cout << "(5) SuperSoldier" << endl;
				cout << "What type of soldier do you want to inspect: ";
				cin >> thingToBeUpgraded;
				cout << endl;
				cout << "The current amount of soldiertype " << thingToBeUpgraded << " is " << realPlayer[playerNumber].cities[cityToWorkOn].soldierInfo(2, thingToBeUpgraded) << endl;
				break;
			case 7:
				return;
				break;
			default:
				cout << "You entered a number that was not available, please try again." << endl;
				break;
		}
		break;
	}
}
<commit_msg>Fixed exiting from city without tessling to exit.<commit_after>#include <iostream>

using namespace std;

#include "functions.h"
#include "player.h"

void turn(int playerNumber)
{
    int cityToWorkOn;
	for (int i = 0; i < 5; i++)
	{
        realPlayer[playerNumber].cities[i].getBlacksmithBonus();
	}
	while (true)
	{
        cout << "(1-3) Visit a city." << endl;
        cout << "(4) End Turn." << endl;
        cout << "What do you want to do: ";
        cin >> cityToWorkOn;
        cityToWorkOn -= 1;
        cout << endl;
        if (cityToWorkOn == 3)
        {
            return;
        }
        else
        {
            visitCity(cityToWorkOn, playerNumber);
        }
	}
}

void visitCity(int cityToWorkOn, int playerNumber)
{
    int thingToBeUpgraded, amountToBeUpgradedBy, answer;
    signed int result;
    while (true)
	{
		cout << "(1) Upgrade Buildings" << endl;
		cout << "(2) Hire Troops" << endl;
		cout << "(3) Not implemented." << endl;
		cout << "(4) Check Money" << endl;
		cout << "(5) Check Buildings" << endl;
		cout << "(6) Check Troops" << endl;
		cout << "(7) Exit City" << endl;
		cout << "What operation do you want to do: ";
		cin >> answer;
		cout << endl;
		switch (answer)
		{
			case 1:
				cout << "(0) Castle" << endl;
				cout << "(1) Training Camp" << endl;
				cout << "(2) Farms" << endl;
				cout << "(3-7) Blacksmiths" << endl;
				cout << "What building do you want to upgrade: ";
				cin >> thingToBeUpgraded;
				cout << endl;
				cout << "How many levels do you want to upgrade the building by: ";
				cin >> amountToBeUpgradedBy;
				cout << endl << endl;
				result = realPlayer[playerNumber].cities[cityToWorkOn].setBuilding(0, amountToBeUpgradedBy, thingToBeUpgraded);
				if (result == -1)
				{
					cout << "Upgrade failed for some reason. Could be no money or building level maxed out." << endl;
				}
				else
				{
					cout << "Building upgrade succeeded!" << endl;
					cout << "The chosen building now has " << result << " levels." << endl;
				}
				break;
			case 2:
                cout << "(0) Pikeman" << endl;
				cout << "(1) Swordsman" << endl;
				cout << "(2) Medic" << endl;
				cout << "(3) Archer" << endl;
				cout << "(4) Horseman" << endl;
				cout << "(5) SuperSoldier" << endl;
				cout << "What type of soldier do you want to recruit: ";
				cin >> thingToBeUpgraded;
				cout << endl;
				cout << "How many soldiers do you want to recruit: ";
				cin >> amountToBeUpgradedBy;
				cout << endl << endl;
				result = realPlayer[playerNumber].cities[cityToWorkOn].setSoldier(0, amountToBeUpgradedBy, thingToBeUpgraded);
				if (result == -1)
				{
					cout << "Upgrade failed for some reason. Could be no money or food." << endl;
				}
				else
				{
					cout << "Soldier recruiting succeeded!" << endl;
					cout << "The chosen soldiertype now has " << result << " soldiers in it." << endl;
				}
				break;
			case 3:
				cout << "This feature is not implemented." << endl;
				break;
			case 4:
				cout << "You have: $" << realPlayer[playerNumber].cities[cityToWorkOn].getMoney() << " in this city." << endl;
				break;
			case 5:
                cout << "(0) Castle" << endl;
				cout << "(1) Training Camp" << endl;
				cout << "(2) Farms" << endl;
				cout << "(3-7) Blacksmith (1-5)" << endl;
				cout << "What building do you want to inspect: ";
				cin >> thingToBeUpgraded;
				cout << endl;
				cout << "The cost of a level upgrade to building " << thingToBeUpgraded << " is " << realPlayer[playerNumber].cities[cityToWorkOn].buildingInfo(0, thingToBeUpgraded) << endl;
				cout << "The maximum level of building " << thingToBeUpgraded << " is " << realPlayer[playerNumber].cities[cityToWorkOn].buildingInfo(1, thingToBeUpgraded) << endl;
				cout << "The current level of building " << thingToBeUpgraded << " is " << realPlayer[playerNumber].cities[cityToWorkOn].buildingInfo(2, thingToBeUpgraded) << endl;
				break;
			case 6:
                cout << "(0) Pikeman" << endl;
				cout << "(1) Swordsman" << endl;
				cout << "(2) Medic" << endl;
				cout << "(3) Archer" << endl;
				cout << "(4) Horseman" << endl;
				cout << "(5) SuperSoldier" << endl;
				cout << "What type of soldier do you want to inspect: ";
				cin >> thingToBeUpgraded;
				cout << endl;
				cout << "The current amount of soldiertype " << thingToBeUpgraded << " is " << realPlayer[playerNumber].cities[cityToWorkOn].soldierInfo(2, thingToBeUpgraded) << endl;
				break;
			case 7:
				return;
				break;
			default:
				cout << "You entered a number that was not available, please try again." << endl;
				break;
		}
	}
}
<|endoftext|>