<commit_before>#include "token.hpp"

namespace laskin
{
    static inline bool isword(char);

    token::token(enum type type, const std::string& data)
        : m_type(type)
        , m_data(data) {}

    token::token(const token& that)
        : m_type(that.m_type)
        , m_data(that.m_data) {}

    std::vector<token> token::scan(std::istream& is)
        throw(syntax_error)
    {
        std::vector<token> tokens;
        std::string buffer;

        for (std::istreambuf_iterator<char> current(is), end; current != end;)
        {
            char c = *current++;

            switch (c)
            {
                // Skip comments.
                case '#':
                    while (current != end)
                    {
                        if (*current++ == '\n')
                        {
                            break;
                        }
                    }
                    break;

                // Skip whitespace.
                case ' ':
                case '\t':
                case '\r':
                case '\n':
                    break;

                // Various separators.
                case '(': case ')':
                case '[': case ']':
                case '{': case '}':
                case ':':
                    tokens.push_back(token(
                                c == '(' ? type_lparen :
                                c == ')' ? type_rparen :
                                c == '[' ? type_lbrack :
                                c == ']' ? type_rbrack :
                                c == '{' ? type_lbrace :
                                c == '}' ? type_rbrace :
                                type_colon
                    ));
                    break;

                // Parse numbers from zero.
                case '0':
                    buffer.assign(1, '0');
                    if (current != end)
                    {
SCAN_NUMBER_FROM_ZERO:
                        switch (c = *current++)
                        {
                            case 'b': case 'B':
                                buffer.append(1, c);
                                while (current != end && std::isdigit(*current))
                                {
                                    if ((c = *current++) != '0' && c != '1')
                                    {
                                        throw syntax_error(
                                                "invalid binary digit"
                                        );
                                    }
                                    buffer.append(1, c);
                                }
                                break;

                            case 'x': case 'X':
                                buffer.append(1, 'x');
                                while (current != end && std::isxdigit(*current))
                                {
                                    buffer.append(1, *current++);
                                }
                                break;

                            case 'o': case 'O':
                            case '0': case '1':
                            case '2': case '3':
                            case '4': case '5':
                            case '6': case '7':
                                buffer.append(1, c);
                                while (current != end && std::isdigit(*current))
                                {
                                    if ((c = *current++) > '7')
                                    {
                                        throw syntax_error(
                                                "invalid octal digit"
                                        );
                                    }
                                    buffer.append(1, c);
                                }
                                break;

                            case '8': case '9':
                                throw syntax_error("invalid octal digit");

                            case 'e': case 'E':
                                goto SCAN_EXPONENT;

                            case '.':
                                goto SCAN_REAL;
                        }
                    }
                    tokens.push_back(token(type_integer, buffer));
                    break;

                // Parse numbers.
                case '1': case '2': case '3':
                case '4': case '5': case '6':
                case '7': case '8': case '9':
                    buffer.assign(1, c);
SCAN_NUMBER:
                    while (current != end && std::isdigit(*current))
                    {
                        buffer.append(1, *current++);
                    }
                    if (current != end && *current == '.')
                    {
                        ++current;
SCAN_REAL:
                        buffer.append(1, '.');
                        if (current == end || !std::isdigit(*current))
                        {
                            throw syntax_error("missing digits after `.'");
                        }
                        do
                        {
                            buffer.append(1, *current++);
                        }
                        while (current != end && std::isdigit(*current));
                        if (current != end && (*current == 'e' || *current == 'E'))
                        {
SCAN_EXPONENT:
                            buffer.append(1, 'e');
                            ++current;
                            if (current != end && (*current == '+' || *current == '-'))
                            {
                                buffer.append(1, *current++);
                            }
                            if (current == end || !std::isdigit(*current))
                            {
                                throw syntax_error("missing exponent");
                            }
                            do
                            {
                                buffer.append(1, *current++);
                            }
                            while (current != end && std::isdigit(*current));
                        }
                        tokens.push_back(token(type_real, buffer));
                    } else {
                        tokens.push_back(token(type_integer, buffer));
                    }
                    break;

                // Parse double quoted strings.
                case '"':
                    buffer.clear();
                    while (current != end && *current != '"')
                    {
                        if (*current == '\\')
                        {
                            // TODO: process escape sequence
                        } else {
                            buffer.append(1, *current++);
                        }
                    }
                    if (current == end)
                    {
                        throw syntax_error("unterminated string literal");
                    }
                    tokens.push_back(token(type_string, buffer));
                    ++current;
                    break;

                // Parse single quoted strings.
                case '\'':
                    buffer.clear();
                    while (current != end && *current != '\'')
                    {
                        if (*current == '\\')
                        {
                            // TODO: process escape sequence
                        } else {
                            buffer.append(1, *current++);
                        }
                    }
                    if (current == end)
                    {
                        throw syntax_error("unterminated string literal");
                    }
                    tokens.push_back(token(type_string, buffer));
                    ++current;
                    break;

                case '-':
                case '+':
                    buffer.assign(1, c);
                    if (current != end)
                    {
                        if (*current == '0')
                        {
                            goto SCAN_NUMBER_FROM_ZERO;
                        }
                        else if (std::isdigit(*current))
                        {
                            goto SCAN_NUMBER;
                        }
                    }
                    goto SCAN_WORD;

                default:
                    if (isword(c))
                    {
                        buffer.assign(1, c);
SCAN_WORD:
                        while (current != end && isword(*current))
                        {
                            buffer.append(1, *current++);
                        }
                        tokens.push_back(token(type_word, buffer));
                    } else {
                        throw syntax_error("unexpected input");
                    }
            }
        }

        return tokens;
    }

    token& token::assign(const token& that)
    {
        m_type = that.m_type;
        m_data = that.m_data;

        return *this;
    }

    std::ostream& operator<<(std::ostream& os, enum token::type type)
    {
        switch (type)
        {
            case token::type_lparen:
                os << "`('";
                break;

            case token::type_rparen:
                os << "`)'";
                break;

            case token::type_lbrack:
                os << "`['";
                break;

            case token::type_rbrack:
                os << "`]'";
                break;

            case token::type_lbrace:
                os << "`{'";
                break;

            case token::type_rbrace:
                os << "`}'";
                break;

            case token::type_colon:
                os << "`:'";
                break;

            case token::type_integer:
            case token::type_real:
                os << "number literal";
                break;

            case token::type_string:
                os << "string literal";
                break;

            case token::type_word:
                os << "word";
        }

        return os;
    }

    static inline bool isword(char c)
    {
        return (c >= '0' && c <= '9')
            || (c >= 'a' && c <= 'z')
            || (c >= 'A' && c <= 'Z')
            || c == '!'
            || c == '$'
            || c == '%'
            || c == '&'
            || c == '\''
            || c == '*'
            || c == '+'
            || c == ','
            || c == '-'
            || c == '.'
            || c == '/'
            || c == ':'
            || c == ';'
            || c == '<'
            || c == '>'
            || c == '='
            || c == '?'
            || c == '@'
            || c == '^'
            || c == '_'
            || c == '`'
            || c == '|'
            || c == '~';
    }
}
<commit_msg>simplify scanning routine<commit_after>#include "token.hpp"

namespace laskin
{
    static inline bool isword(char);

    token::token(enum type type, const std::string& data)
        : m_type(type)
        , m_data(data) {}

    token::token(const token& that)
        : m_type(that.m_type)
        , m_data(that.m_data) {}

    std::vector<token> token::scan(std::istream& is)
        throw(syntax_error)
    {
        std::vector<token> tokens;
        std::string buffer;

        for (std::istreambuf_iterator<char> current(is), end; current != end;)
        {
            char c = *current++;

            switch (c)
            {
                // Skip comments.
                case '#':
                    while (current != end)
                    {
                        if (*current++ == '\n')
                        {
                            break;
                        }
                    }
                    break;

                // Skip whitespace.
                case ' ':
                case '\t':
                case '\r':
                case '\n':
                    break;

                // Various separators.
                case '(': case ')':
                case '[': case ']':
                case '{': case '}':
                case ':':
                    tokens.push_back(token(
                                c == '(' ? type_lparen :
                                c == ')' ? type_rparen :
                                c == '[' ? type_lbrack :
                                c == ']' ? type_rbrack :
                                c == '{' ? type_lbrace :
                                c == '}' ? type_rbrace :
                                type_colon
                    ));
                    break;

                // Parse numbers from zero.
                case '0':
                    buffer.assign(1, '0');
                    if (current != end)
                    {
SCAN_NUMBER_FROM_ZERO:
                        switch (c = *current++)
                        {
                            case 'b': case 'B':
                                buffer.append(1, c);
                                while (current != end && std::isdigit(*current))
                                {
                                    if ((c = *current++) != '0' && c != '1')
                                    {
                                        throw syntax_error(
                                                "invalid binary digit"
                                        );
                                    }
                                    buffer.append(1, c);
                                }
                                break;

                            case 'x': case 'X':
                                buffer.append(1, 'x');
                                while (current != end && std::isxdigit(*current))
                                {
                                    buffer.append(1, *current++);
                                }
                                break;

                            case 'o': case 'O':
                            case '0': case '1':
                            case '2': case '3':
                            case '4': case '5':
                            case '6': case '7':
                                buffer.append(1, c);
                                while (current != end && std::isdigit(*current))
                                {
                                    if ((c = *current++) > '7')
                                    {
                                        throw syntax_error(
                                                "invalid octal digit"
                                        );
                                    }
                                    buffer.append(1, c);
                                }
                                break;

                            case '8': case '9':
                                throw syntax_error("invalid octal digit");

                            case 'e': case 'E':
                                goto SCAN_EXPONENT;

                            case '.':
                                goto SCAN_REAL;
                        }
                    }
                    tokens.push_back(token(type_integer, buffer));
                    break;

                // Parse numbers.
                case '1': case '2': case '3':
                case '4': case '5': case '6':
                case '7': case '8': case '9':
                    buffer.assign(1, c);
SCAN_NUMBER:
                    while (current != end && std::isdigit(*current))
                    {
                        buffer.append(1, *current++);
                    }
                    if (current != end && *current == '.')
                    {
                        ++current;
SCAN_REAL:
                        buffer.append(1, '.');
                        if (current == end || !std::isdigit(*current))
                        {
                            throw syntax_error("missing digits after `.'");
                        }
                        do
                        {
                            buffer.append(1, *current++);
                        }
                        while (current != end && std::isdigit(*current));
                        if (current != end && (*current == 'e' || *current == 'E'))
                        {
SCAN_EXPONENT:
                            buffer.append(1, 'e');
                            ++current;
                            if (current != end && (*current == '+' || *current == '-'))
                            {
                                buffer.append(1, *current++);
                            }
                            if (current == end || !std::isdigit(*current))
                            {
                                throw syntax_error("missing exponent");
                            }
                            do
                            {
                                buffer.append(1, *current++);
                            }
                            while (current != end && std::isdigit(*current));
                        }
                        tokens.push_back(token(type_real, buffer));
                    } else {
                        tokens.push_back(token(type_integer, buffer));
                    }
                    break;

                // Parse string literals.
                case '"':
                case '\'':
                {
                    buffer.clear();
                    while (current != end && *current != c)
                    {
                        if (*current == '\\')
                        {
                            // TODO: process escape sequence
                        } else {
                            buffer.append(1, *current++);
                        }
                    }
                    if (current == end)
                    {
                        throw syntax_error("unterminated string literal");
                    }
                    tokens.push_back(token(type_string, buffer));
                    ++current;
                    break;
                }

                case '-':
                case '+':
                    buffer.assign(1, c);
                    if (current != end)
                    {
                        if (*current == '0')
                        {
                            goto SCAN_NUMBER_FROM_ZERO;
                        }
                        else if (std::isdigit(*current))
                        {
                            goto SCAN_NUMBER;
                        }
                    }
                    goto SCAN_WORD;

                default:
                    if (isword(c))
                    {
                        buffer.assign(1, c);
SCAN_WORD:
                        while (current != end && isword(*current))
                        {
                            buffer.append(1, *current++);
                        }
                        tokens.push_back(token(type_word, buffer));
                    } else {
                        throw syntax_error("unexpected input");
                    }
            }
        }

        return tokens;
    }

    token& token::assign(const token& that)
    {
        m_type = that.m_type;
        m_data = that.m_data;

        return *this;
    }

    std::ostream& operator<<(std::ostream& os, enum token::type type)
    {
        switch (type)
        {
            case token::type_lparen:
                os << "`('";
                break;

            case token::type_rparen:
                os << "`)'";
                break;

            case token::type_lbrack:
                os << "`['";
                break;

            case token::type_rbrack:
                os << "`]'";
                break;

            case token::type_lbrace:
                os << "`{'";
                break;

            case token::type_rbrace:
                os << "`}'";
                break;

            case token::type_colon:
                os << "`:'";
                break;

            case token::type_integer:
            case token::type_real:
                os << "number literal";
                break;

            case token::type_string:
                os << "string literal";
                break;

            case token::type_word:
                os << "word";
        }

        return os;
    }

    static inline bool isword(char c)
    {
        return (c >= '0' && c <= '9')
            || (c >= 'a' && c <= 'z')
            || (c >= 'A' && c <= 'Z')
            || c == '!'
            || c == '$'
            || c == '%'
            || c == '&'
            || c == '\''
            || c == '*'
            || c == '+'
            || c == ','
            || c == '-'
            || c == '.'
            || c == '/'
            || c == ':'
            || c == ';'
            || c == '<'
            || c == '>'
            || c == '='
            || c == '?'
            || c == '@'
            || c == '^'
            || c == '_'
            || c == '`'
            || c == '|'
            || c == '~';
    }
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include "SDL2/SDL.h"
#include "Magicengine/Game.h"
#include "PlayState.h"

PlayState PlayState::m_PlayState;

void PlayState::Init(Game* game)
{
	phy2 = game->getPhysics();
	playTexture = NULL;
	playTexture = Load::Texture("assets/test.png", game->GetScreen());
	textColor = { 255, 255, 255 };
	fonttype = Load::Font("assets/Font/lazy.ttf", 26);
	test = new Object(playTexture, game->GetScreen(), 0,0,50,50);
	test2 = new Object(playTexture, game->GetScreen(), 100,100);
	timeFont = new Font(timeText.str(), fonttype, textColor, 50, 50, game->GetScreen());
	timer = new Timer();
	timer->start();
	phy2->addObject(test);
	phy2->addObject(test2);
	printf("PlayState Init Successful\n");
}

void PlayState::Clean()
{
	SDL_DestroyTexture(playTexture);
	printf("PlayState Clean Successful\n");
}

void PlayState::Pause()
{
	printf("PlayState Paused\n");
}

void PlayState::Resume()
{
	printf("PlayState Resumed\n");
}

void PlayState::HandleEvents(Game* game)
{
	SDL_Event event;

	if (SDL_PollEvent(&event)) {
		switch (event.type) {
			case SDL_QUIT:
				game->Quit();
				break;
		}
	}
}

void PlayState::Update(Game* game)
{

	timeText.str( "" );
	timeText << "Seconds since start time " << (timer->getTicks()/1000.f);
	timeFont->setText(timeText.str());
}

void PlayState::Draw(Game* game)
{
	timeFont->Draw();
	test->Draw();
	test2->Draw();
}
<commit_msg>stuff<commit_after>#include <stdio.h>
#include "SDL2/SDL.h"
#include "Magicengine/Game.h"
#include "PlayState.h"

PlayState PlayState::m_PlayState;

void PlayState::Init(Game* game)
{
	phy2 = game->getPhysics();
	playTexture = NULL;
	playTexture = Load::Texture((char *) "assets/test.png", game->GetScreen());
	textColor = { 255, 255, 255 };
	fonttype = Load::Font((char *) "assets/Font/lazy.ttf", 26);
	test = new Object(playTexture, game->GetScreen(), 0,0,50,50);
	test2 = new Object(playTexture, game->GetScreen(), 100,100);
	timeFont = new Font(timeText.str(), fonttype, textColor, 50, 50, game->GetScreen());
	timer = new Timer();
	timer->start();
	phy2->addObject(test);
	phy2->addObject(test2);
	printf("PlayState Init Successful\n");
}

void PlayState::Clean()
{
	SDL_DestroyTexture(playTexture);
	printf("PlayState Clean Successful\n");
}

void PlayState::Pause()
{
	printf("PlayState Paused\n");
}

void PlayState::Resume()
{
	printf("PlayState Resumed\n");
}

void PlayState::HandleEvents(Game* game)
{
	SDL_Event event;

	if (SDL_PollEvent(&event)) {
		switch (event.type) {
			case SDL_QUIT:
				game->Quit();
				break;
		}
	}
}

void PlayState::Update(Game* game)
{

	timeText.str( "" );
	timeText << "Seconds since start time " << (timer->getTicks()/1000.f);
	timeFont->setText(timeText.str());
}

void PlayState::Draw(Game* game)
{
	timeFont->Draw();
	test->Draw();
	test2->Draw();
}
<|endoftext|>


<commit_before>#ifndef PONG_DEFS_HPP_
#define PONG_DEFS_HPP_

#include <string>

namespace pong {

constexpr const wchar_t* WINDOW_TITLE = L"Pong";
constexpr const int WINDOW_WIDTH = 640;
constexpr const int WINDOW_HEIGHT = 480;
constexpr const float WINDOW_HALF_WIDTH = WINDOW_WIDTH / 2.0f;
constexpr const float WINDOW_HALF_HEIGHT = WINDOW_HEIGHT / 2.0f;

enum class Player {
    NONE,
    PLAYER_1, PLAYER_2,
    PLAYER_COUNT
};

constexpr const int PIXELS_PER_METER = 64;

constexpr const int GAME_FRAMES_PER_SECOND = 60;
constexpr const float GAME_TIME_STEP = 1.0f / GAME_FRAMES_PER_SECOND;
constexpr const int GAME_VELOCITY_ITERATIONS = 8;
constexpr const int GAME_POSITION_ITERATIONS = 3;

constexpr const int MATCH_POINT = 10;

constexpr const float WALL_WIDTH = WINDOW_WIDTH;
constexpr const float WALL_HALF_WIDTH = WALL_WIDTH / 2.0f;
constexpr const float WALL_HEIGHT = 10.0f;
constexpr const float WALL_HALF_HEIGHT = WALL_HEIGHT / 2.0f;

constexpr const float BALL_WIDTH = 10.0f;
constexpr const float BALL_HALF_WIDTH = BALL_WIDTH / 2.0f;
constexpr const float BALL_HEIGHT = 10.0f;
constexpr const float BALL_HALF_HEIGHT = BALL_HEIGHT / 2.0f;
constexpr const float BALL_MIN_SPEED = 2.0f;
constexpr const float BALL_MAX_SPEED = 15.0f;
constexpr const float BALL_VELOCITY_STEP = 0.003;
constexpr const float BALL_MIN_ROTATION_SPEED = 0.1f;
constexpr const float BALL_MAX_ROTATION_SPEED = 10.0f;

constexpr const float RACKET_MARGIN = 15.0f;
constexpr const float RACKET_WIDTH = 20.0f;
constexpr const float RACKET_HALF_WIDTH = RACKET_WIDTH / 2.0f;
constexpr const float RACKET_HEIGHT = 80.0f;
constexpr const float RACKET_HALF_HEIGHT = RACKET_HEIGHT / 2.0f;
constexpr const float RACKET_BASE_SPEED = 5.0f;

const std::string ASSETS_PATH = "assets/";
constexpr const int DEFAULT_FONT_SIZE = 24;

} /* namespace pong */
#endif /* PONG_DEFS_HPP_ */
<commit_msg>Remove unused enum<commit_after>#ifndef PONG_DEFS_HPP_
#define PONG_DEFS_HPP_

#include <string>

namespace pong {

constexpr const wchar_t* WINDOW_TITLE = L"Pong";
constexpr const int WINDOW_WIDTH = 640;
constexpr const int WINDOW_HEIGHT = 480;
constexpr const float WINDOW_HALF_WIDTH = WINDOW_WIDTH / 2.0f;
constexpr const float WINDOW_HALF_HEIGHT = WINDOW_HEIGHT / 2.0f;

constexpr const int PIXELS_PER_METER = 64;

constexpr const int GAME_FRAMES_PER_SECOND = 60;
constexpr const float GAME_TIME_STEP = 1.0f / GAME_FRAMES_PER_SECOND;
constexpr const int GAME_VELOCITY_ITERATIONS = 8;
constexpr const int GAME_POSITION_ITERATIONS = 3;

constexpr const int MATCH_POINT = 10;

constexpr const float WALL_WIDTH = WINDOW_WIDTH;
constexpr const float WALL_HALF_WIDTH = WALL_WIDTH / 2.0f;
constexpr const float WALL_HEIGHT = 10.0f;
constexpr const float WALL_HALF_HEIGHT = WALL_HEIGHT / 2.0f;

constexpr const float BALL_WIDTH = 10.0f;
constexpr const float BALL_HALF_WIDTH = BALL_WIDTH / 2.0f;
constexpr const float BALL_HEIGHT = 10.0f;
constexpr const float BALL_HALF_HEIGHT = BALL_HEIGHT / 2.0f;
constexpr const float BALL_MIN_SPEED = 2.0f;
constexpr const float BALL_MAX_SPEED = 15.0f;
constexpr const float BALL_VELOCITY_STEP = 0.003;
constexpr const float BALL_MIN_ROTATION_SPEED = 0.1f;
constexpr const float BALL_MAX_ROTATION_SPEED = 10.0f;

constexpr const float RACKET_MARGIN = 15.0f;
constexpr const float RACKET_WIDTH = 20.0f;
constexpr const float RACKET_HALF_WIDTH = RACKET_WIDTH / 2.0f;
constexpr const float RACKET_HEIGHT = 80.0f;
constexpr const float RACKET_HALF_HEIGHT = RACKET_HEIGHT / 2.0f;
constexpr const float RACKET_BASE_SPEED = 5.0f;

const std::string ASSETS_PATH = "assets/";
constexpr const int DEFAULT_FONT_SIZE = 24;

} /* namespace pong */
#endif /* PONG_DEFS_HPP_ */
<|endoftext|>


<commit_before>#ifndef _SNARKFRONT_POWERS_OF_2_HPP_
#define _SNARKFRONT_POWERS_OF_2_HPP_

#include <algorithm>
#include <cassert>
#include <climits>
#include <cstdint>
#include <gmp.h>
#include <vector>
#include <BigInt.hpp> // snarklib

namespace snarkfront {

// look up table for powers of 2 for BigInt/field/group
template <typename T>
class PowersOf2
{
public:
    PowersOf2()
        : m_lut(1, T::one())
    {}

    const T& lookUp(const std::size_t index)
    {
        // protect against huge index from accidental pointer argument
        assert(index < 1024);

        for (std::size_t i = m_lut.size(); i <= index; ++i) {
            // m_lut[i] = 2 * m_lut[i - 1];
            m_lut.emplace_back(m_lut.back() + m_lut.back());
        }

        return m_lut[index];
    }

    T getNumber(const std::size_t number) {
        T accum = T::zero();

        auto b = number;
        std::size_t i = 0;
        while (b) {
            if (b & 0x1)
                accum = accum + lookUp(i);

            b >>= 1;
            ++i;
        }

        return accum;
    }

    T getNumber(const std::vector<int>& bits) {
        T accum = T::zero();

        for (std::size_t i = 0; i < bits.size(); ++i) {
            if (bits[i])
                accum = accum + lookUp(i);
        }

        return accum;
    }

private:
    std::vector<T> m_lut; // index -> T(2^index)
};

// convert Boolean to BigInt/field/group one and zero
template <typename T>
T boolTo(const bool a) {
    return a ? T::one() : T::zero();
}

// size of type in bits
std::size_t sizeBits(const bool& dummy);
std::size_t sizeBits(const std::uint32_t& dummy);
std::size_t sizeBits(const std::uint64_t& dummy);

template <mp_size_t N>
std::size_t sizeBits(const snarklib::BigInt<N>& dummy) {
    return snarklib::BigInt<N>::maxBits();
}

// returns number of matching bits starting from most significant bit
template <typename BIT>
int matchMSB(const std::vector<BIT>& a,
             const std::vector<BIT>& b)
{
    if (a.size() != b.size())
        return -1; // a and b are different sizes, no matching bits

    for (int i = a.size() - 1; i >= 0; --i) {
        if (bool(a[i] != b[i]))
            return a.size() - 1 - i; // some bits match
    }

    return a.size(); // all bits match
}

// convert value to bits
std::vector<int> valueBits(const bool& a);
std::vector<int> valueBits(const std::uint32_t& a);
std::vector<int> valueBits(const std::uint64_t& a);

template <mp_size_t N>
std::vector<int> valueBits(const snarklib::BigInt<N>& a) {
    std::vector<int> v;
    v.reserve(sizeBits(a));

    for (std::size_t i = 0; i < sizeBits(a); ++i) {
        v.push_back(a.testBit(i));
    }

    return v;
}

// convert bits to value
template <typename UINT_N>
std::vector<int> bitsValue(UINT_N& a, const std::vector<int>& b)
{
    UINT_N result = 0;
    const std::size_t N = std::min(sizeBits(a), b.size());
    for (std::size_t i = 0; i < N; ++i) {
        result |= (UINT_N(b[i]) << i);
    }

    a = result;

    std::vector<int> v;
    for (std::size_t i = N; i < b.size(); ++i) {
        v.push_back(b[i]);
    }

    return v;
}

// count number of set bits
std::size_t countBits(const std::vector<int>& v);

// overflow addition (uint32_t and uint64_t)
template <typename UINT_N>
void addover(UINT_N& a1, UINT_N& a0, const UINT_N& b)
{
    // a0 = 2 * a0_half + a0_bit
    // b = 2 * b_half + b_bit
    const UINT_N
        a0_half = a0 >> 1, a0_bit = a0 & 0x1,
        b_half = b >> 1, b_bit = b & 0x1;

    // a0 + b = 2 * (a0_half + b_half) + (a0_bit + b_bit)
    //        = 2 * halfsum + a0_bit + b_bit
    const UINT_N halfsum = a0_half + b_half;

    // (high, low) = a0 + b
    UINT_N
        high = halfsum >> (sizeBits(high) - 1), // carry bit
        low = (halfsum << 1) + a0_bit;

    const UINT_N lowOriginal = low;
    low += b_bit;
    if ((0 == low) && (-1 == lowOriginal)) ++high; // handle carry

    // accumulate result
    a1 += high;
    a0 = low;
}

} // namespace snarkfront

#endif
<commit_msg>USE_ASSERT<commit_after>#ifndef _SNARKFRONT_POWERS_OF_2_HPP_
#define _SNARKFRONT_POWERS_OF_2_HPP_

#include <algorithm>
#include <cassert>
#include <climits>
#include <cstdint>
#include <gmp.h>
#include <vector>
#include <BigInt.hpp> // snarklib

namespace snarkfront {

// look up table for powers of 2 for BigInt/field/group
template <typename T>
class PowersOf2
{
public:
    PowersOf2()
        : m_lut(1, T::one())
    {}

    const T& lookUp(const std::size_t index)
    {
        // protect against huge index from accidental pointer argument
#ifdef USE_ASSERT
        assert(index < 1024);
#endif

        for (std::size_t i = m_lut.size(); i <= index; ++i) {
            // m_lut[i] = 2 * m_lut[i - 1];
            m_lut.emplace_back(m_lut.back() + m_lut.back());
        }

        return m_lut[index];
    }

    T getNumber(const std::size_t number) {
        T accum = T::zero();

        auto b = number;
        std::size_t i = 0;
        while (b) {
            if (b & 0x1)
                accum = accum + lookUp(i);

            b >>= 1;
            ++i;
        }

        return accum;
    }

    T getNumber(const std::vector<int>& bits) {
        T accum = T::zero();

        for (std::size_t i = 0; i < bits.size(); ++i) {
            if (bits[i])
                accum = accum + lookUp(i);
        }

        return accum;
    }

private:
    std::vector<T> m_lut; // index -> T(2^index)
};

// convert Boolean to BigInt/field/group one and zero
template <typename T>
T boolTo(const bool a) {
    return a ? T::one() : T::zero();
}

// size of type in bits
std::size_t sizeBits(const bool& dummy);
std::size_t sizeBits(const std::uint32_t& dummy);
std::size_t sizeBits(const std::uint64_t& dummy);

template <mp_size_t N>
std::size_t sizeBits(const snarklib::BigInt<N>& dummy) {
    return snarklib::BigInt<N>::maxBits();
}

// returns number of matching bits starting from most significant bit
template <typename BIT>
int matchMSB(const std::vector<BIT>& a,
             const std::vector<BIT>& b)
{
    if (a.size() != b.size())
        return -1; // a and b are different sizes, no matching bits

    for (int i = a.size() - 1; i >= 0; --i) {
        if (bool(a[i] != b[i]))
            return a.size() - 1 - i; // some bits match
    }

    return a.size(); // all bits match
}

// convert value to bits
std::vector<int> valueBits(const bool& a);
std::vector<int> valueBits(const std::uint32_t& a);
std::vector<int> valueBits(const std::uint64_t& a);

template <mp_size_t N>
std::vector<int> valueBits(const snarklib::BigInt<N>& a) {
    std::vector<int> v;
    v.reserve(sizeBits(a));

    for (std::size_t i = 0; i < sizeBits(a); ++i) {
        v.push_back(a.testBit(i));
    }

    return v;
}

// convert bits to value
template <typename UINT_N>
std::vector<int> bitsValue(UINT_N& a, const std::vector<int>& b)
{
    UINT_N result = 0;
    const std::size_t N = std::min(sizeBits(a), b.size());
    for (std::size_t i = 0; i < N; ++i) {
        result |= (UINT_N(b[i]) << i);
    }

    a = result;

    std::vector<int> v;
    for (std::size_t i = N; i < b.size(); ++i) {
        v.push_back(b[i]);
    }

    return v;
}

// count number of set bits
std::size_t countBits(const std::vector<int>& v);

// overflow addition (uint32_t and uint64_t)
template <typename UINT_N>
void addover(UINT_N& a1, UINT_N& a0, const UINT_N& b)
{
    // a0 = 2 * a0_half + a0_bit
    // b = 2 * b_half + b_bit
    const UINT_N
        a0_half = a0 >> 1, a0_bit = a0 & 0x1,
        b_half = b >> 1, b_bit = b & 0x1;

    // a0 + b = 2 * (a0_half + b_half) + (a0_bit + b_bit)
    //        = 2 * halfsum + a0_bit + b_bit
    const UINT_N halfsum = a0_half + b_half;

    // (high, low) = a0 + b
    UINT_N
        high = halfsum >> (sizeBits(high) - 1), // carry bit
        low = (halfsum << 1) + a0_bit;

    const UINT_N lowOriginal = low;
    low += b_bit;
    if ((0 == low) && (-1 == lowOriginal)) ++high; // handle carry

    // accumulate result
    a1 += high;
    a0 = low;
}

} // namespace snarkfront

#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <sstream>
#include "Myexception.h"
#include "chain.h"

using namespace std;

void chain :: readAndStoreFromFile(char* fileName)
{
	//This function reads integers from the file given by fileName then store them in the chain

	ifstream infile(fileName) ;
	string line;

	while(getline(infile, line)) {
		istringstream iss(line);
		int n;
		iss >> n;
		insert(listSize, n);
	}

}

void chain :: eraseModuloValue(int theInt)
{
	//This function erases all the entries from the list which are multiple of theInt

	for(int i=0; i < listSize; i++) {
		int value = *this->get(i);
		int remainder = value%theInt;

        	if (remainder == 0 && value > theInt) {
			erase(i);
        		i--;
		}
	}

}

void chain :: oddAndEvenOrdering()
{
	//This function reorders the list such a way that all odd numbers precede all even numbers.
	//Note that for two odd (even) numbers i and j, the ordering between i and j should be intact after reordering.

}

void chain :: reverse()
{
	//Reverses the list

	for(int i=0; i < listSize; i++) {
		int value = *this->get(i);
        	insert(0, value);
	}

}

chain :: chain(int initialCapacity)
{
	//Constructor
	if(initialCapacity < 1)
	{
		ostringstream s;
		s << "Initial capacity = " << initialCapacity << " Must be > 0";
		throw illegalParameterValue(s.str());
	}

	firstNode = NULL;
	listSize = 0;

}

chain :: ~chain()
{
	//Destructor. Delete all nodes in chain

	while(firstNode != NULL)
	{
		//delete firstNode
		chainNode* nextNode = firstNode->next;
		delete firstNode;
		firstNode = nextNode;

	}

}

int* chain :: get(int theIndex) const
{
	//Return element whose index is theIndex.
	//Throw illegalIndex exception if no such element.
	try{
		checkIndex(theIndex);
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return NULL;
	}

	chainNode* currentNode = firstNode;
	for(int i=0;i<theIndex;i++)
		currentNode = currentNode->next;

	return &currentNode->element;

}

int chain :: indexOf(const int& theElement) const
{
	//Return index of first occurrence of theElement.
	//Return -1 of theElement not in list.

	chainNode* currentNode = firstNode;
	int index = 0;
	while(currentNode != NULL && currentNode->element != theElement)
	{
		//move to the next node
		currentNode = currentNode->next;
		index++;

	}

	//make sure we found matching element
	if(currentNode == NULL)
		return -1;

	else
		return index;

}

void chain :: erase(int theIndex)
{
	//Delete the element whose index is theIndex.
	//Throw illegalIndex exception if no such element.

	try{
		checkIndex(theIndex);
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return;
	}

	chainNode* deleteNode;
	if(theIndex == 0)
	{
		//remove first node from chain
		deleteNode = firstNode;
		firstNode = firstNode->next;

	}
	else
	{
		//use p to get to predecessor of desired node
		chainNode* p = firstNode;
		for(int i=0;i<theIndex-1;i++)
			p = p->next;

		deleteNode = p->next;
		p->next = p->next->next; //remove deleteNode from chain

	}

	listSize--;
	delete deleteNode;

}

void chain :: insert(int theIndex, const int& theElement)
{
	//Insert theElement so that its index is theIndex.
	try{
   		if (theIndex < 0 || theIndex > listSize)
   		{// invalid index

			ostringstream s;
    			s << "index = " << theIndex << " size = " << listSize;
    			throw illegalIndex(s.str());
		}
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return;
	}

	if(theIndex == 0)
		//insert at front
		firstNode = new chainNode(theElement, firstNode);
	else
	{
		chainNode *p = firstNode;
		for(int i=0;i<theIndex-1;i++)
			p = p->next;

		//insert after p
		p->next = new chainNode(theElement, p->next);

	}

	listSize++;

}

void chain :: output() const
{
	//Put the list into the output.

	for(int i=0;i<listSize;i++)
		cout << *this->get(i) << " ";
	cout<<endl;

}

void chain::checkIndex(int theIndex) const
{
// Verify that theIndex is between 0 and
 // listSize - 1.

   	if (theIndex < 0 || theIndex >= listSize){
		ostringstream s;
    		s << "index = " << theIndex << " size = "
                    << listSize<<", the input index is invalid";
    		throw illegalIndex(s.str());
	}

}
<commit_msg>now includes multiples below indecated<commit_after>#include <iostream>
#include <fstream>
#include <sstream>
#include "Myexception.h"
#include "chain.h"

using namespace std;

void chain :: readAndStoreFromFile(char* fileName)
{
	//This function reads integers from the file given by fileName then store them in the chain

	ifstream infile(fileName) ;
	string line;

	while(getline(infile, line)) {
		istringstream iss(line);
		int n;
		iss >> n;
		insert(listSize, n);
	}

}

void chain :: eraseModuloValue(int theInt)
{
	//This function erases all the entries from the list which are multiple of theInt

	for(int i=0; i < listSize; i++) {
		int value = *this->get(i);
		int remainder = value%theInt;

        	if (remainder == 0) {
			erase(i);
        		i--;
		}
	}

}

void chain :: oddAndEvenOrdering()
{
	//This function reorders the list such a way that all odd numbers precede all even numbers.
	//Note that for two odd (even) numbers i and j, the ordering between i and j should be intact after reordering.

}

void chain :: reverse()
{
	//Reverses the list

	for(int i=0; i < listSize; i++) {
		int value = *this->get(i);
        	insert(0, value);
	}

}

chain :: chain(int initialCapacity)
{
	//Constructor
	if(initialCapacity < 1)
	{
		ostringstream s;
		s << "Initial capacity = " << initialCapacity << " Must be > 0";
		throw illegalParameterValue(s.str());
	}

	firstNode = NULL;
	listSize = 0;

}

chain :: ~chain()
{
	//Destructor. Delete all nodes in chain

	while(firstNode != NULL)
	{
		//delete firstNode
		chainNode* nextNode = firstNode->next;
		delete firstNode;
		firstNode = nextNode;

	}

}

int* chain :: get(int theIndex) const
{
	//Return element whose index is theIndex.
	//Throw illegalIndex exception if no such element.
	try{
		checkIndex(theIndex);
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return NULL;
	}

	chainNode* currentNode = firstNode;
	for(int i=0;i<theIndex;i++)
		currentNode = currentNode->next;

	return &currentNode->element;

}

int chain :: indexOf(const int& theElement) const
{
	//Return index of first occurrence of theElement.
	//Return -1 of theElement not in list.

	chainNode* currentNode = firstNode;
	int index = 0;
	while(currentNode != NULL && currentNode->element != theElement)
	{
		//move to the next node
		currentNode = currentNode->next;
		index++;

	}

	//make sure we found matching element
	if(currentNode == NULL)
		return -1;

	else
		return index;

}

void chain :: erase(int theIndex)
{
	//Delete the element whose index is theIndex.
	//Throw illegalIndex exception if no such element.

	try{
		checkIndex(theIndex);
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return;
	}

	chainNode* deleteNode;
	if(theIndex == 0)
	{
		//remove first node from chain
		deleteNode = firstNode;
		firstNode = firstNode->next;

	}
	else
	{
		//use p to get to predecessor of desired node
		chainNode* p = firstNode;
		for(int i=0;i<theIndex-1;i++)
			p = p->next;

		deleteNode = p->next;
		p->next = p->next->next; //remove deleteNode from chain

	}

	listSize--;
	delete deleteNode;

}

void chain :: insert(int theIndex, const int& theElement)
{
	//Insert theElement so that its index is theIndex.
	try{
   		if (theIndex < 0 || theIndex > listSize)
   		{// invalid index

			ostringstream s;
    			s << "index = " << theIndex << " size = " << listSize;
    			throw illegalIndex(s.str());
		}
	}
	catch(illegalIndex &e){
		e.outputMessage();
		return;
	}

	if(theIndex == 0)
		//insert at front
		firstNode = new chainNode(theElement, firstNode);
	else
	{
		chainNode *p = firstNode;
		for(int i=0;i<theIndex-1;i++)
			p = p->next;

		//insert after p
		p->next = new chainNode(theElement, p->next);

	}

	listSize++;

}

void chain :: output() const
{
	//Put the list into the output.

	for(int i=0;i<listSize;i++)
		cout << *this->get(i) << " ";
	cout<<endl;

}

void chain::checkIndex(int theIndex) const
{
// Verify that theIndex is between 0 and
 // listSize - 1.

   	if (theIndex < 0 || theIndex >= listSize){
		ostringstream s;
    		s << "index = " << theIndex << " size = "
                    << listSize<<", the input index is invalid";
    		throw illegalIndex(s.str());
	}

}
<|endoftext|>


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

#include "utilities.h"

#include <QTimer>
#include <QDebug>
#include <QScreen>
#include <QSettings>
#include <QClipboard>
#include <QApplication>

//------------------------------------------------------------------------------
// Windows hacks
//------------------------------------------------------------------------------

#if defined Q_OS_WIN
    #include <pdh.h>
    #include <tchar.h>
    #include <windows.h>
    #include <windowsx.h>

    static PDH_HQUERY cpuQuery;
    static PDH_HCOUNTER cpuTotal;
    static SYSTEM_POWER_STATUS power;
#endif

//------------------------------------------------------------------------------
// Mac OS hacks
//------------------------------------------------------------------------------

#if defined Q_OS_MAC
    static const QString CPU_CMD = "bash -c \"ps -A -o %cpu | "
    "awk '{s+=$1} END {print s}'\"";
    static const QString BTY_CMD = "pmset -g batt";
    static const QString PWR_CMD = "pmset -g batt";
#endif

//------------------------------------------------------------------------------
// Linux hacks
//------------------------------------------------------------------------------

#if defined Q_OS_LINUX
    #include <QFile>
    #include <QRegExp>

    static const QString BTY_CMD = "bash -c \"upower -i "
    "$(upower -e | grep 'BAT') | "
    "grep -E 'state|to\\ full|percentage'\"";
    static const QString PWR_CMD = "bash -c \"upower -i "
    "$(upower -e | grep 'BAT') | "
    "grep -E 'state|to\\ full|percentage'\"";
#endif

//------------------------------------------------------------------------------
// Ensure that application compiles even if OS is not supported
//------------------------------------------------------------------------------

#if !defined Q_OS_WIN && !defined Q_OS_MAC && !defined Q_OS_LINUX
    static const QString CPU_CMD = "";
    static const QString BTY_CMD = "";
    static const QString PWR_CMD = "";
#endif

//------------------------------------------------------------------------------
// Start class code
//------------------------------------------------------------------------------

/**
 * Configures the class and nitializes the CPU querying process under Windows.
 */
Utilities::Utilities()
{
    m_ratio = 0;
    m_cpuUsage = 0;
    m_batteryLevel = 0;
    m_connectedToAC = 0;

    m_settings = new QSettings (qApp->organizationName(),
                                qApp->applicationName());

    /* Read process data when they finish */
    connect (&m_cpuProcess,           SIGNAL (finished                 (int)),
             this,                      SLOT (readCpuUsageProcess      (int)));
    connect (&m_batteryLevelProcess,  SIGNAL (finished                 (int)),
             this,                      SLOT (readBatteryLevelProcess  (int)));
    connect (&m_connectedToACProcess, SIGNAL (finished                 (int)),
             this,                      SLOT (readConnectedToACProcess (int)));

    /* Kill the probing processes when application quits */
    connect (qApp,                  SIGNAL (aboutToQuit()),
             &m_cpuProcess,           SLOT (kill()));
    connect (qApp,                  SIGNAL (aboutToQuit()),
             &m_batteryLevelProcess,  SLOT (kill()));
    connect (qApp,                  SIGNAL (aboutToQuit()),
             &m_connectedToACProcess, SLOT (kill()));

    /* Configure Windows */
#if defined Q_OS_WIN
    PdhOpenQuery (0, 0, &cpuQuery);
    PdhAddCounter (cpuQuery,
                   L"\\Processor(_Total)\\% Processor Time",
                   0,
                   &cpuTotal);
    PdhCollectQueryData (cpuQuery);
#endif

    /* Start loop */
    updateCpuUsage();
    updateBatteryLevel();
    updateConnectedToAC();
}

/**
 * Returns the auto-calculates scale ratio
 */
qreal Utilities::scaleRatio()
{
    if (m_ratio < 1)
        calculateScaleRatio();

    return m_ratio;
}

/**
 * Returns the current CPU usage (from 0 to 100)
 */
int Utilities::cpuUsage()
{
    m_cpuUsage = abs (m_cpuUsage);

    if (m_cpuUsage <= 100)
        return m_cpuUsage;

    return 0;
}

/**
 * Returns the current battery level (from 0 to 100)
 */
int Utilities::batteryLevel()
{
    m_batteryLevel = abs (m_batteryLevel);

    if (m_batteryLevel <= 100)
        return m_batteryLevel;

    return 0;
}

/**
 * Returns \c true if the computer is connected to a power source or the
 * battery is not discharging.
 */
bool Utilities::isConnectedToAC()
{
    return m_connectedToAC;
}

/**
 * Copies the given \a data to the system clipboard
 */
void Utilities::copy (const QVariant& data)
{
    qApp->clipboard()->setText (data.toString(), QClipboard::Clipboard);
}

/**
 * Enables or disables the autoscale feature.
 * \note The application must be restarted for changes to take effect
 */
void Utilities::setAutoScaleEnabled (const bool enabled)
{
    m_settings->setValue ("AutoScale", enabled);
}

/**
 * Queries for the current CPU usage
 */
void Utilities::updateCpuUsage()
{
#if defined Q_OS_WIN
    PDH_FMT_COUNTERVALUE counterVal;
    PdhCollectQueryData (cpuQuery);
    PdhGetFormattedCounterValue (cpuTotal, PDH_FMT_DOUBLE, 0, &counterVal);
    m_cpuUsage = static_cast<int> (counterVal.doubleValue);
    emit cpuUsageChanged();
#elif defined Q_OS_MAC
    m_cpuProcess.terminate();
    m_cpuProcess.start (CPU_CMD, QIODevice::ReadOnly);
#elif defined Q_OS_LINUX
    auto cpuJiffies = getCpuJiffies();

    m_cpuUsage = (cpuJiffies.first - m_pastCpuJiffies.first) * 100 /
                 (cpuJiffies.second - m_pastCpuJiffies.second);

    m_pastCpuJiffies = cpuJiffies;
#endif

    QTimer::singleShot (1000,
                        Qt::PreciseTimer,
                        this, SLOT (updateCpuUsage()));
}

/**
 * Queries for the current battery level
 */
void Utilities::updateBatteryLevel()
{
#if defined Q_OS_WIN
    GetSystemPowerStatus (&power);
    m_batteryLevel = static_cast<int> (power.BatteryLifePercent);
    emit batteryLevelChanged();
#else
    m_batteryLevelProcess.terminate();
    m_batteryLevelProcess.start (BTY_CMD, QIODevice::ReadOnly);
#endif

    QTimer::singleShot (1000,
                        Qt::PreciseTimer,
                        this, SLOT (updateBatteryLevel()));
}

/**
 * Queries for the current AC power source status
 */
void Utilities::updateConnectedToAC()
{
#if defined Q_OS_WIN
    GetSystemPowerStatus (&power);
    m_connectedToAC = (power.ACLineStatus != 0);
    emit connectedToACChanged();
#else
    m_connectedToACProcess.terminate();
    m_connectedToACProcess.start (PWR_CMD, QIODevice::ReadOnly);
#endif

    QTimer::singleShot (1000,
                        Qt::PreciseTimer,
                        this, SLOT (updateConnectedToAC()));
}

/**
 * Calculates the scale factor to apply to the UI.
 * \note This function uses different procedures depending on the OS
 */
void Utilities::calculateScaleRatio()
{
    bool enabled = m_settings->value ("AutoScale", true).toBool();

    /* Get scale factor using OS-specific code */
#if defined Q_OS_WIN
    HDC screen = GetDC (Q_NULLPTR);
    m_ratio = (qreal) GetDeviceCaps (screen, LOGPIXELSX) / 96;
    ReleaseDC (Q_NULLPTR, screen);
#elif defined Q_OS_LINUX
    m_ratio = qApp->primaryScreen()->physicalDotsPerInch() / 120;
#endif

    /* Ensure that values between x.40 and x.65 round down to x.40 */
    qreal decimals = m_ratio - (int) m_ratio;
    if (decimals >= 0.40 && decimals <= 0.65)
        m_ratio -= (decimals - 0.40);

    /* Ratio is too small to be useful to us */
    if (!enabled || m_ratio < 1.2)
        m_ratio = 1;

    /* Brag about the obtained result */
    qDebug() << "Scale factor set to:" << m_ratio;
}

/**
 * Reads the output of the process launched to get the CPU usage
 */
void Utilities::readCpuUsageProcess (int exit_code)
{
    if (exit_code == EXIT_FAILURE)
        return;

#if defined Q_OS_MAC
    m_cpuUsage = 0;
    m_cpuProcess.terminate();
    QByteArray data = m_cpuProcess.readAll();

    if (!data.isEmpty() && data.length() >= 2) {
        /* Parse the digits of the percentage */
        int t = data.at (0) - '0'; // Tens
        int u = data.at (1) - '0'; // Units

        /* Check if process data is invalid */
        if (t < 0) t = 0;
        if (u < 0) u = 0;

        /* Update information */
        m_cpuUsage = (t * 10) + u;
        emit cpuUsageChanged();
    }
#endif
}

/**
 * Reads the output of the process launched to get the battery level
 */
void Utilities::readBatteryLevelProcess (int exit_code)
{
    if (exit_code == EXIT_FAILURE)
        return;

#if defined Q_OS_MAC || defined Q_OS_LINUX
    m_batteryLevel = 0;
    m_batteryLevelProcess.terminate();
    QByteArray data = m_batteryLevelProcess.readAll();

    if (!data.isEmpty()) {
        /* Parse the digits of the percentage */
        int h = data.at (data.indexOf ("%") - 3) - '0'; // Hundreds
        int t = data.at (data.indexOf ("%") - 2) - '0'; // Tens
        int u = data.at (data.indexOf ("%") - 1) - '0'; // Units

        /* Check if process data is invalid */
        if (h < 0) h = 0;
        if (t < 0) t = 0;
        if (u < 0) u = 0;

        /* Update information */
        m_batteryLevel = (h * 100) + (t * 10) + u;
        emit batteryLevelChanged();
    }
#endif
}

/**
 * Reads the output of the process launched to get the AC power source status
 */
void Utilities::readConnectedToACProcess (int exit_code)
{
    if (exit_code == EXIT_FAILURE)
        return;

#if defined Q_OS_MAC || defined Q_OS_LINUX
    m_connectedToAC = false;
    m_connectedToACProcess.terminate();
    QByteArray data = m_connectedToACProcess.readAll();

    if (!data.isEmpty()) {
        m_connectedToAC = !data.contains ("discharging");
        emit connectedToACChanged();
    }
#endif
}

#if defined Q_OS_LINUX
/**
 * Reads the current count of CPU jiffies from /proc/stat and return a pair
 * consisting of non-idle jiffies and total jiffies
 */
QPair<quint64, quint64> Utilities::getCpuJiffies()
{
    quint64 totalJiffies = 0;
    quint64 nonIdleJiffies = 0;

    QFile file ("/proc/stat");
    if (file.open (QFile::ReadOnly)) {
        QString line = file.readLine();
        QStringList jiffies = line.replace ("cpu  ", "").split (" ");

        if (jiffies.count() > 3) {
            nonIdleJiffies = jiffies.at (0).toInt() + jiffies.at (2).toInt();
            totalJiffies = nonIdleJiffies + jiffies.at (3).toInt();
        }

        file.close();
    }

    return qMakePair (nonIdleJiffies, totalJiffies);
}
#endif
<commit_msg>Fixed Linux CPU usage GUI update<commit_after>/*
 * Copyright (c) 2015-2016 Alex Spataru <alex_spataru@outlook.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "utilities.h"

#include <QTimer>
#include <QDebug>
#include <QScreen>
#include <QSettings>
#include <QClipboard>
#include <QApplication>

//------------------------------------------------------------------------------
// Windows hacks
//------------------------------------------------------------------------------

#if defined Q_OS_WIN
    #include <pdh.h>
    #include <tchar.h>
    #include <windows.h>
    #include <windowsx.h>

    static PDH_HQUERY cpuQuery;
    static PDH_HCOUNTER cpuTotal;
    static SYSTEM_POWER_STATUS power;
#endif

//------------------------------------------------------------------------------
// Mac OS hacks
//------------------------------------------------------------------------------

#if defined Q_OS_MAC
    static const QString CPU_CMD = "bash -c \"ps -A -o %cpu | "
    "awk '{s+=$1} END {print s}'\"";
    static const QString BTY_CMD = "pmset -g batt";
    static const QString PWR_CMD = "pmset -g batt";
#endif

//------------------------------------------------------------------------------
// Linux hacks
//------------------------------------------------------------------------------

#if defined Q_OS_LINUX
    #include <QFile>
    #include <QRegExp>

    static const QString BTY_CMD = "bash -c \"upower -i "
    "$(upower -e | grep 'BAT') | "
    "grep -E 'state|to\\ full|percentage'\"";
    static const QString PWR_CMD = "bash -c \"upower -i "
    "$(upower -e | grep 'BAT') | "
    "grep -E 'state|to\\ full|percentage'\"";
#endif

//------------------------------------------------------------------------------
// Ensure that application compiles even if OS is not supported
//------------------------------------------------------------------------------

#if !defined Q_OS_WIN && !defined Q_OS_MAC && !defined Q_OS_LINUX
    static const QString CPU_CMD = "";
    static const QString BTY_CMD = "";
    static const QString PWR_CMD = "";
#endif

//------------------------------------------------------------------------------
// Start class code
//------------------------------------------------------------------------------

/**
 * Configures the class and nitializes the CPU querying process under Windows.
 */
Utilities::Utilities()
{
    m_ratio = 0;
    m_cpuUsage = 0;
    m_batteryLevel = 0;
    m_connectedToAC = 0;

    m_settings = new QSettings (qApp->organizationName(),
                                qApp->applicationName());

    /* Read process data when they finish */
    connect (&m_cpuProcess,           SIGNAL (finished                 (int)),
             this,                      SLOT (readCpuUsageProcess      (int)));
    connect (&m_batteryLevelProcess,  SIGNAL (finished                 (int)),
             this,                      SLOT (readBatteryLevelProcess  (int)));
    connect (&m_connectedToACProcess, SIGNAL (finished                 (int)),
             this,                      SLOT (readConnectedToACProcess (int)));

    /* Kill the probing processes when application quits */
    connect (qApp,                  SIGNAL (aboutToQuit()),
             &m_cpuProcess,           SLOT (kill()));
    connect (qApp,                  SIGNAL (aboutToQuit()),
             &m_batteryLevelProcess,  SLOT (kill()));
    connect (qApp,                  SIGNAL (aboutToQuit()),
             &m_connectedToACProcess, SLOT (kill()));

    /* Configure Windows */
#if defined Q_OS_WIN
    PdhOpenQuery (0, 0, &cpuQuery);
    PdhAddCounter (cpuQuery,
                   L"\\Processor(_Total)\\% Processor Time",
                   0,
                   &cpuTotal);
    PdhCollectQueryData (cpuQuery);
#endif

    /* Start loop */
    updateCpuUsage();
    updateBatteryLevel();
    updateConnectedToAC();
}

/**
 * Returns the auto-calculates scale ratio
 */
qreal Utilities::scaleRatio()
{
    if (m_ratio < 1)
        calculateScaleRatio();

    return m_ratio;
}

/**
 * Returns the current CPU usage (from 0 to 100)
 */
int Utilities::cpuUsage()
{
    m_cpuUsage = abs (m_cpuUsage);

    if (m_cpuUsage <= 100)
        return m_cpuUsage;

    return 0;
}

/**
 * Returns the current battery level (from 0 to 100)
 */
int Utilities::batteryLevel()
{
    m_batteryLevel = abs (m_batteryLevel);

    if (m_batteryLevel <= 100)
        return m_batteryLevel;

    return 0;
}

/**
 * Returns \c true if the computer is connected to a power source or the
 * battery is not discharging.
 */
bool Utilities::isConnectedToAC()
{
    return m_connectedToAC;
}

/**
 * Copies the given \a data to the system clipboard
 */
void Utilities::copy (const QVariant& data)
{
    qApp->clipboard()->setText (data.toString(), QClipboard::Clipboard);
}

/**
 * Enables or disables the autoscale feature.
 * \note The application must be restarted for changes to take effect
 */
void Utilities::setAutoScaleEnabled (const bool enabled)
{
    m_settings->setValue ("AutoScale", enabled);
}

/**
 * Queries for the current CPU usage
 */
void Utilities::updateCpuUsage()
{
#if defined Q_OS_WIN
    PDH_FMT_COUNTERVALUE counterVal;
    PdhCollectQueryData (cpuQuery);
    PdhGetFormattedCounterValue (cpuTotal, PDH_FMT_DOUBLE, 0, &counterVal);
    m_cpuUsage = static_cast<int> (counterVal.doubleValue);
    emit cpuUsageChanged();
#elif defined Q_OS_MAC
    m_cpuProcess.terminate();
    m_cpuProcess.start (CPU_CMD, QIODevice::ReadOnly);
#elif defined Q_OS_LINUX
    auto cpuJiffies = getCpuJiffies();

    m_cpuUsage = (cpuJiffies.first - m_pastCpuJiffies.first) * 100 /
                 (cpuJiffies.second - m_pastCpuJiffies.second);

    m_pastCpuJiffies = cpuJiffies;
    emit cpuUsageChanged();
#endif

    QTimer::singleShot (1000,
                        Qt::PreciseTimer,
                        this, SLOT (updateCpuUsage()));
}

/**
 * Queries for the current battery level
 */
void Utilities::updateBatteryLevel()
{
#if defined Q_OS_WIN
    GetSystemPowerStatus (&power);
    m_batteryLevel = static_cast<int> (power.BatteryLifePercent);
    emit batteryLevelChanged();
#else
    m_batteryLevelProcess.terminate();
    m_batteryLevelProcess.start (BTY_CMD, QIODevice::ReadOnly);
#endif

    QTimer::singleShot (1000,
                        Qt::PreciseTimer,
                        this, SLOT (updateBatteryLevel()));
}

/**
 * Queries for the current AC power source status
 */
void Utilities::updateConnectedToAC()
{
#if defined Q_OS_WIN
    GetSystemPowerStatus (&power);
    m_connectedToAC = (power.ACLineStatus != 0);
    emit connectedToACChanged();
#else
    m_connectedToACProcess.terminate();
    m_connectedToACProcess.start (PWR_CMD, QIODevice::ReadOnly);
#endif

    QTimer::singleShot (1000,
                        Qt::PreciseTimer,
                        this, SLOT (updateConnectedToAC()));
}

/**
 * Calculates the scale factor to apply to the UI.
 * \note This function uses different procedures depending on the OS
 */
void Utilities::calculateScaleRatio()
{
    bool enabled = m_settings->value ("AutoScale", true).toBool();

    /* Get scale factor using OS-specific code */
#if defined Q_OS_WIN
    HDC screen = GetDC (Q_NULLPTR);
    m_ratio = (qreal) GetDeviceCaps (screen, LOGPIXELSX) / 96;
    ReleaseDC (Q_NULLPTR, screen);
#elif defined Q_OS_LINUX
    m_ratio = qApp->primaryScreen()->physicalDotsPerInch() / 120;
#endif

    /* Ensure that values between x.40 and x.65 round down to x.40 */
    qreal decimals = m_ratio - (int) m_ratio;
    if (decimals >= 0.40 && decimals <= 0.65)
        m_ratio -= (decimals - 0.40);

    /* Ratio is too small to be useful to us */
    if (!enabled || m_ratio < 1.2)
        m_ratio = 1;

    /* Brag about the obtained result */
    qDebug() << "Scale factor set to:" << m_ratio;
}

/**
 * Reads the output of the process launched to get the CPU usage
 */
void Utilities::readCpuUsageProcess (int exit_code)
{
    if (exit_code == EXIT_FAILURE)
        return;

#if defined Q_OS_MAC
    m_cpuUsage = 0;
    m_cpuProcess.terminate();
    QByteArray data = m_cpuProcess.readAll();

    if (!data.isEmpty() && data.length() >= 2) {
        /* Parse the digits of the percentage */
        int t = data.at (0) - '0'; // Tens
        int u = data.at (1) - '0'; // Units

        /* Check if process data is invalid */
        if (t < 0) t = 0;
        if (u < 0) u = 0;

        /* Update information */
        m_cpuUsage = (t * 10) + u;
        emit cpuUsageChanged();
    }
#endif
}

/**
 * Reads the output of the process launched to get the battery level
 */
void Utilities::readBatteryLevelProcess (int exit_code)
{
    if (exit_code == EXIT_FAILURE)
        return;

#if defined Q_OS_MAC || defined Q_OS_LINUX
    m_batteryLevel = 0;
    m_batteryLevelProcess.terminate();
    QByteArray data = m_batteryLevelProcess.readAll();

    if (!data.isEmpty()) {
        /* Parse the digits of the percentage */
        int h = data.at (data.indexOf ("%") - 3) - '0'; // Hundreds
        int t = data.at (data.indexOf ("%") - 2) - '0'; // Tens
        int u = data.at (data.indexOf ("%") - 1) - '0'; // Units

        /* Check if process data is invalid */
        if (h < 0) h = 0;
        if (t < 0) t = 0;
        if (u < 0) u = 0;

        /* Update information */
        m_batteryLevel = (h * 100) + (t * 10) + u;
        emit batteryLevelChanged();
    }
#endif
}

/**
 * Reads the output of the process launched to get the AC power source status
 */
void Utilities::readConnectedToACProcess (int exit_code)
{
    if (exit_code == EXIT_FAILURE)
        return;

#if defined Q_OS_MAC || defined Q_OS_LINUX
    m_connectedToAC = false;
    m_connectedToACProcess.terminate();
    QByteArray data = m_connectedToACProcess.readAll();

    if (!data.isEmpty()) {
        m_connectedToAC = !data.contains ("discharging");
        emit connectedToACChanged();
    }
#endif
}

#if defined Q_OS_LINUX
/**
 * Reads the current count of CPU jiffies from /proc/stat and return a pair
 * consisting of non-idle jiffies and total jiffies
 */
QPair<quint64, quint64> Utilities::getCpuJiffies()
{
    quint64 totalJiffies = 0;
    quint64 nonIdleJiffies = 0;

    QFile file ("/proc/stat");
    if (file.open (QFile::ReadOnly)) {
        QString line = file.readLine();
        QStringList jiffies = line.replace ("cpu  ", "").split (" ");

        if (jiffies.count() > 3) {
            nonIdleJiffies = jiffies.at (0).toInt() + jiffies.at (2).toInt();
            totalJiffies = nonIdleJiffies + jiffies.at (3).toInt();
        }

        file.close();
    }

    return qMakePair (nonIdleJiffies, totalJiffies);
}
#endif
<|endoftext|>


<commit_before>/* vim: set ai et ts=4 sw=4: */

#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include <cstdint>
#include <iostream>
#include <sstream>
#include <stdexcept>

class Date {
public:
    Date(uint16_t year, uint8_t month, uint8_t day)
      : _year(year)
      , _month(month)
      , _day(day) {
    }

    static Date fromJSON(const rapidjson::Value& doc) {
        if(!doc.IsArray())
            throw std::runtime_error("Date::fromJSON - document is not an array");

        if(doc.Size() != 3)
            throw std::runtime_error("Date::fromJSON - wrong array size");

        uint16_t year = doc[0].GetInt();
        uint8_t month = doc[1].GetInt();
        uint8_t day = doc[2].GetInt();

        Date result(year, month, day);
        return result;
    }

    rapidjson::Document toJSON() {
        rapidjson::Document doc;
        auto& allocator = doc.GetAllocator();
        doc.SetArray().PushBack(_year, allocator).PushBack(_month, allocator).PushBack(_day, allocator);
        return doc;
    }

    uint16_t getYear() const {
        return _year;
    }

    uint8_t getMonth() const {
        return _month;
    }

    uint8_t getDay() const {
        return _day;
    }

    Date& setYear(uint16_t year) {
        _year = year;
        return *this;
    }

    Date& setMonth(uint8_t month) {
        _month = month;
        return *this;
    }

    Date& setDay(uint8_t day) {
        _day = day;
        return *this;
    }

private:
    uint16_t _year;
    uint8_t _month;
    uint8_t _day;
};

class User {
public:
    User(uint64_t id, const std::string& name, uint64_t phone, Date birthday)
      : _id(id)
      , _name(name)
      , _phone(phone)
      , _birthday(birthday) {
    }

    static User fromJSON(const rapidjson::Value& doc) {
        if(!doc.IsObject())
            throw std::runtime_error("User::fromJSON() - document should be an object");

        static const char* members[] = {"id", "name", "phone", "birthday"};
        for(size_t i = 0; i < sizeof(members) / sizeof(members[0]); i++) {
            if(!doc.HasMember(members[i]))
                throw std::runtime_error("User::fromJSON() - invalid JSON, missing fields");
        }

        if(!doc["id"].IsNumber())
            throw std::runtime_error("User::fromJSON() - invalid JSON, `id` should be an integer");

        if(!doc["name"].IsString())
            throw std::runtime_error("User::fromJSON() - invalid JSON, `name` should be a string");

        if(!doc["phone"].IsNumber())
            throw std::runtime_error("User::fromJSON() - invalid JSON, `phone` should be an integer");

        if(!doc["birthday"].IsArray())
            throw std::runtime_error("User::fromJSON() - invalid JSON, `birthday` should be an array");

        uint64_t id = doc["id"].GetUint64();
        std::string name = doc["name"].GetString();
        uint64_t phone = doc["phone"].GetUint64();
        Date birthday = Date::fromJSON(doc["birthday"]);

        User result(id, name, phone, birthday);
        return result;
    }

    rapidjson::Document toJSON() {
        rapidjson::Value json_val;
        rapidjson::Document doc;
        auto& allocator = doc.GetAllocator();

        doc.SetObject();

        json_val.SetUint64(_id);
        doc.AddMember("id", json_val, allocator);

        json_val.SetString(_name.c_str(), allocator);
        doc.AddMember("name", json_val, allocator);

        // see http://rapidjson.org/md_doc_tutorial.html#DeepCopyValue
        json_val.CopyFrom(_birthday.toJSON(), allocator);
        doc.AddMember("birthday", json_val, allocator);

        json_val.SetUint64(_phone);
        doc.AddMember("phone", json_val, allocator);

        return doc;
    }

    uint64_t getId() const {
        return _id;
    }

    const std::string& getName() const {
        return _name;
    }

    uint64_t getPhone() const {
        return _phone;
    }

    Date getBirthday() const {
        return _birthday;
    }

    User& setName(const std::string& name) {
        _name = name;
        return *this;
    }

    User& setPhone(uint64_t phone) {
        _phone = phone;
        return *this;
    }

    User& setBirthday(Date birthday) {
        _birthday = birthday;
        return *this;
    }

private:
    uint64_t _id;
    std::string _name;
    uint64_t _phone;
    Date _birthday;
};

std::ostream& operator<<(std::ostream& os, const Date& date) {
    os << "Date(year = " << date.getYear() << ", month = " << (int)date.getMonth() << ", day = " << (int)date.getDay()
       << ")";
    return os;
}

std::ostream& operator<<(std::ostream& os, const User& user) {
    os << "User(id = " << user.getId() << ", name = " << user.getName() << ", phone = " << user.getPhone()
       << ", birthday = " << user.getBirthday() << ")";
    return os;
}

Date readDate() {
    std::string line;
    uint16_t year, month, day;

    std::cout << "Year: ";
    std::getline(std::cin, line);
    std::stringstream(line) >> year;

    std::cout << "Month: ";
    std::getline(std::cin, line);
    std::stringstream(line) >> month;

    std::cout << "Day: ";
    std::getline(std::cin, line);
    std::stringstream(line) >> day;

    Date result(year, (uint8_t)month, (uint8_t)day);
    return result;
}

User readUser() {
    uint64_t id;
    uint64_t phone;
    std::string name, line;

    std::cout << "Id: ";
    std::getline(std::cin, line);
    std::stringstream(line) >> id;

    std::cout << "Name: ";
    std::getline(std::cin, name);

    std::cout << "Phone: ";
    std::getline(std::cin, line);
    std::stringstream(line) >> phone;

    std::cout << "--- Birthday ---" << std::endl;
    Date birthday = readDate();
    std::cout << "----------------" << std::endl;

    User result(id, name, phone, birthday);
    return result;
}

int main() {
    User user = readUser();
    std::cout << user << std::endl;

    {
        rapidjson::Document doc = user.toJSON();
        rapidjson::StringBuffer buffer;
        // rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
        rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
        doc.Accept(writer);
        std::cout << buffer.GetString() << std::endl;

        User decodedUser = User::fromJSON(doc);
        std::cout << decodedUser << std::endl;
    }

    return 0;
}
<commit_msg>Run clang-format<commit_after>/* vim: set ai et ts=4 sw=4: */

#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include <cstdint>
#include <iostream>
#include <sstream>
#include <stdexcept>

class Date {
public:
    Date(uint16_t year, uint8_t month, uint8_t day)
      : _year(year)
      , _month(month)
      , _day(day) {
    }

    static Date fromJSON(const rapidjson::Value& doc) {
        if(!doc.IsArray())
            throw std::runtime_error("Date::fromJSON - document is not an array");

        if(doc.Size() != 3)
            throw std::runtime_error("Date::fromJSON - wrong array size");

        uint16_t year = doc[0].GetInt();
        uint8_t month = doc[1].GetInt();
        uint8_t day = doc[2].GetInt();

        Date result(year, month, day);
        return result;
    }

    rapidjson::Document toJSON() {
        rapidjson::Document doc;
        auto& allocator = doc.GetAllocator();
        doc.SetArray().PushBack(_year, allocator).PushBack(_month, allocator).PushBack(_day, allocator);
        return doc;
    }

    uint16_t getYear() const {
        return _year;
    }

    uint8_t getMonth() const {
        return _month;
    }

    uint8_t getDay() const {
        return _day;
    }

    Date& setYear(uint16_t year) {
        _year = year;
        return *this;
    }

    Date& setMonth(uint8_t month) {
        _month = month;
        return *this;
    }

    Date& setDay(uint8_t day) {
        _day = day;
        return *this;
    }

private:
    uint16_t _year;
    uint8_t _month;
    uint8_t _day;
};

class User {
public:
    User(uint64_t id, const std::string& name, uint64_t phone, Date birthday)
      : _id(id)
      , _name(name)
      , _phone(phone)
      , _birthday(birthday) {
    }

    static User fromJSON(const rapidjson::Value& doc) {
        if(!doc.IsObject())
            throw std::runtime_error("User::fromJSON() - document should be an object");

        static const char* members[] = { "id", "name", "phone", "birthday" };
        for(size_t i = 0; i < sizeof(members) / sizeof(members[0]); i++) {
            if(!doc.HasMember(members[i]))
                throw std::runtime_error("User::fromJSON() - invalid JSON, missing fields");
        }

        if(!doc["id"].IsNumber())
            throw std::runtime_error("User::fromJSON() - invalid JSON, `id` should be an integer");

        if(!doc["name"].IsString())
            throw std::runtime_error("User::fromJSON() - invalid JSON, `name` should be a string");

        if(!doc["phone"].IsNumber())
            throw std::runtime_error("User::fromJSON() - invalid JSON, `phone` should be an integer");

        if(!doc["birthday"].IsArray())
            throw std::runtime_error("User::fromJSON() - invalid JSON, `birthday` should be an array");

        uint64_t id = doc["id"].GetUint64();
        std::string name = doc["name"].GetString();
        uint64_t phone = doc["phone"].GetUint64();
        Date birthday = Date::fromJSON(doc["birthday"]);

        User result(id, name, phone, birthday);
        return result;
    }

    rapidjson::Document toJSON() {
        rapidjson::Value json_val;
        rapidjson::Document doc;
        auto& allocator = doc.GetAllocator();

        doc.SetObject();

        json_val.SetUint64(_id);
        doc.AddMember("id", json_val, allocator);

        json_val.SetString(_name.c_str(), allocator);
        doc.AddMember("name", json_val, allocator);

        // see http://rapidjson.org/md_doc_tutorial.html#DeepCopyValue
        json_val.CopyFrom(_birthday.toJSON(), allocator);
        doc.AddMember("birthday", json_val, allocator);

        json_val.SetUint64(_phone);
        doc.AddMember("phone", json_val, allocator);

        return doc;
    }

    uint64_t getId() const {
        return _id;
    }

    const std::string& getName() const {
        return _name;
    }

    uint64_t getPhone() const {
        return _phone;
    }

    Date getBirthday() const {
        return _birthday;
    }

    User& setName(const std::string& name) {
        _name = name;
        return *this;
    }

    User& setPhone(uint64_t phone) {
        _phone = phone;
        return *this;
    }

    User& setBirthday(Date birthday) {
        _birthday = birthday;
        return *this;
    }

private:
    uint64_t _id;
    std::string _name;
    uint64_t _phone;
    Date _birthday;
};

std::ostream& operator<<(std::ostream& os, const Date& date) {
    os << "Date(year = " << date.getYear() << ", month = " << (int)date.getMonth() << ", day = " << (int)date.getDay()
       << ")";
    return os;
}

std::ostream& operator<<(std::ostream& os, const User& user) {
    os << "User(id = " << user.getId() << ", name = " << user.getName() << ", phone = " << user.getPhone()
       << ", birthday = " << user.getBirthday() << ")";
    return os;
}

Date readDate() {
    std::string line;
    uint16_t year, month, day;

    std::cout << "Year: ";
    std::getline(std::cin, line);
    std::stringstream(line) >> year;

    std::cout << "Month: ";
    std::getline(std::cin, line);
    std::stringstream(line) >> month;

    std::cout << "Day: ";
    std::getline(std::cin, line);
    std::stringstream(line) >> day;

    Date result(year, (uint8_t)month, (uint8_t)day);
    return result;
}

User readUser() {
    uint64_t id;
    uint64_t phone;
    std::string name, line;

    std::cout << "Id: ";
    std::getline(std::cin, line);
    std::stringstream(line) >> id;

    std::cout << "Name: ";
    std::getline(std::cin, name);

    std::cout << "Phone: ";
    std::getline(std::cin, line);
    std::stringstream(line) >> phone;

    std::cout << "--- Birthday ---" << std::endl;
    Date birthday = readDate();
    std::cout << "----------------" << std::endl;

    User result(id, name, phone, birthday);
    return result;
}

int main() {
    User user = readUser();
    std::cout << user << std::endl;

    {
        rapidjson::Document doc = user.toJSON();
        rapidjson::StringBuffer buffer;
        // rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
        rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
        doc.Accept(writer);
        std::cout << buffer.GetString() << std::endl;

        User decodedUser = User::fromJSON(doc);
        std::cout << decodedUser << std::endl;
    }

    return 0;
}
<|endoftext|>


<commit_before>/**
 * Created by Liam Huang (Liam0205) on 2018/10/17.
 */

#ifndef SORTS_MERGE_SORT_HPP_
#define SORTS_MERGE_SORT_HPP_

#include <functional>
#include <algorithm>
#include <iterator>
#include <vector>

namespace detail {
template <typename InputIt1, typename InputIt2, typename OutputIt,
          typename BinaryPred = std::less<typename std::iterator_traits<InputIt1>::value_type>>
OutputIt merge(InputIt1 first1, InputIt1 last1,
               InputIt2 first2, InputIt2 last2,
               OutputIt d_first,
               BinaryPred comp = BinaryPred()) {
    for (; first1 != last1; ++d_first) {
        if (first2 == last2) {
            return std::copy(first1, last1, d_first);
        }
        if (comp(*first2, *first1)) {
            *d_first = *first2;
            ++first2;
        } else {
            *d_first = *first1;
            ++first1;
        }
    }
    return std::copy(first2, last2, d_first);
}
}  // namespace detail

template <typename FrwdIt,
          typename BinaryPred = std::less<typename std::iterator_traits<FrwdIt>::value_type>>
void merge_sort(FrwdIt first, FrwdIt last, BinaryPred comp = BinaryPred()) {
    const auto len = std::distance(first, last);
    if (len <= 1) { return; }
    auto cut = first + len / 2;
    merge_sort(first, cut, comp);
    merge_sort(cut, last, comp);
    std::vector<typename std::iterator_traits<FrwdIt>::value_type> tmp;
    tmp.reserve(len);
    detail::merge(first, cut, cut, last, std::back_inserter(tmp), comp);
    std::copy(tmp.begin(), tmp.end(), first);
}

template <typename BidirIt,
          typename BinaryPred = std::less<typename std::iterator_traits<BidirIt>::value_type>>
void inplace_merge_sort(BidirIt first, BidirIt last, BinaryPred comp = BinaryPred()) {
    const auto len = std::distance(first, last);
    if (len <= 1) { return; }
    auto cut = first + len / 2;
    merge_sort(first, cut, comp);
    merge_sort(cut, last, comp);
    std::inplace_merge(first, cut, last, comp);
}

#endif  // SORTS_MERGE_SORT_HPP_

<commit_msg>Update merge_sort.hpp<commit_after>/**
 * Created by Liam Huang (Liam0205) on 2018/10/17.
 */

#ifndef SORTS_MERGE_SORT_HPP_
#define SORTS_MERGE_SORT_HPP_

#include <functional>
#include <algorithm>
#include <iterator>
#include <vector>

namespace detail {
template <typename InputIt1, typename InputIt2, typename OutputIt,
          typename BinaryPred = std::less<typename std::iterator_traits<InputIt1>::value_type>>
OutputIt merge(InputIt1 first1, InputIt1 last1,
               InputIt2 first2, InputIt2 last2,
               OutputIt d_first,
               BinaryPred comp = BinaryPred()) {
    for (; first1 != last1; ++d_first) {
        if (first2 == last2) {
            return std::copy(first1, last1, d_first);
        }
        if (comp(*first2, *first1)) {
            *d_first = *first2;
            ++first2;
        } else {
            *d_first = *first1;
            ++first1;
        }
    }
    return std::copy(first2, last2, d_first);
}
}  // namespace detail

template <typename FrwdIt,
          typename BinaryPred = std::less<typename std::iterator_traits<FrwdIt>::value_type>>
void merge_sort(FrwdIt first, FrwdIt last, BinaryPred comp = BinaryPred()) {
    const auto len = std::distance(first, last);
    if (len <= 1) { return; }
    auto cut = first + len / 2;
    merge_sort(first, cut, comp);
    merge_sort(cut, last, comp);
    std::vector<typename std::iterator_traits<FrwdIt>::value_type> tmp;
    tmp.reserve(len);
    detail::merge(first, cut, cut, last, std::back_inserter(tmp), comp);
    std::copy(tmp.begin(), tmp.end(), first);
}

template <typename BidirIt,
          typename BinaryPred = std::less<typename std::iterator_traits<BidirIt>::value_type>>
void inplace_merge_sort(BidirIt first, BidirIt last, BinaryPred comp = BinaryPred()) {
    const auto len = std::distance(first, last);
    if (len <= 1) { return; }
    auto cut = first + len / 2;
    inplace_merge_sort(first, cut, comp);
    inplace_merge_sort(cut, last, comp);
    std::inplace_merge(first, cut, last, comp);
}

#endif  // SORTS_MERGE_SORT_HPP_

<|endoftext|>