<commit_before>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * 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.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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.

*/

#include <iostream>
#include <boost/config.hpp>
#include <fcntl.h>
#include <stdio.h>

int test_main();

extern bool tests_failure;

int main()
{
#ifdef O_NONBLOCK
	// on darwin, stdout is set to non-blocking mode by default
	// which sometimes causes tests to fail with EAGAIN just
	// by printing logs
	int flags = fcntl(fileno(stdout), F_GETFL, 0);
	fcntl(fileno(stdout), F_SETFL, flags & ~O_NONBLOCK);
	flags = fcntl(fileno(stderr), F_GETFL, 0);
	fcntl(fileno(stderr), F_SETFL, flags & ~O_NONBLOCK);
#endif

#ifndef BOOST_NO_EXCEPTIONS
	try
	{
#endif
		test_main();
#ifndef BOOST_NO_EXCEPTIONS
	}
	catch (std::exception const& e)
	{
		std::cerr << "Terminated with exception: \"" << e.what() << "\"\n";
		tests_failure = true;
	}
	catch (...)
	{
		std::cerr << "Terminated with unknown exception\n";
		tests_failure = true;
	}
#endif
	fflush(stdout);
	fflush(stderr);
	return tests_failure ? 1 : 0;
}

<commit_msg>make tests catch fatal signals and present a nice stack for the error<commit_after>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * 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.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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.

*/

#include <iostream>
#include <boost/config.hpp>
#include <fcntl.h>
#include <stdio.h>

int test_main();

extern bool tests_failure;

#include "libtorrent/assert.hpp"
#include <signal.h>

void sig_handler(int sig)
{
	char stack_text[10000];
	print_backtrace(stack_text, sizeof(stack_text), 30);
	char const* sig_name = 0;
	switch (sig)
	{
#define SIG(x) case x: sig_name = #x; break
		SIG(SIGSEGV);
		SIG(SIGBUS);
		SIG(SIGILL);
		SIG(SIGABRT);
		SIG(SIGFPE);
		SIG(SIGSYS);
#undef SIG
	};
	fprintf(stderr, "signal: %s caught:\n%s\n", sig_name, stack_text);
	exit(138);
}

int main()
{
#ifdef O_NONBLOCK
	// on darwin, stdout is set to non-blocking mode by default
	// which sometimes causes tests to fail with EAGAIN just
	// by printing logs
	int flags = fcntl(fileno(stdout), F_GETFL, 0);
	fcntl(fileno(stdout), F_SETFL, flags & ~O_NONBLOCK);
	flags = fcntl(fileno(stderr), F_GETFL, 0);
	fcntl(fileno(stderr), F_SETFL, flags & ~O_NONBLOCK);
#endif

	signal(SIGSEGV, &sig_handler);
	signal(SIGBUS, &sig_handler);
	signal(SIGILL, &sig_handler);
	signal(SIGABRT, &sig_handler);
	signal(SIGFPE, &sig_handler);
	signal(SIGSYS, &sig_handler);

#ifndef BOOST_NO_EXCEPTIONS
	try
	{
#endif
		test_main();
#ifndef BOOST_NO_EXCEPTIONS
	}
	catch (std::exception const& e)
	{
		std::cerr << "Terminated with exception: \"" << e.what() << "\"\n";
		tests_failure = true;
	}
	catch (...)
	{
		std::cerr << "Terminated with unknown exception\n";
		tests_failure = true;
	}
#endif
	fflush(stdout);
	fflush(stderr);
	return tests_failure ? 1 : 0;
}

<|endoftext|>


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

#include "http.h"

bool isValidSourceUrl(const String &url)
{
    if (url.empty())
        return false;
    if (!isUrl(url))
        return false;
    if (url.find_first_of(R"bbb('"`\|;$ @!#^*()<>[],)bbb") != url.npos)
        return false;
    // remove? will fail: ssh://name:pass@web.site
    if (std::count(url.begin(), url.end(), ':') > 1)
        return false;
    if (url.find("&&") != url.npos)
        return false;
#ifndef CPPAN_TEST
    if (url.find("file:") == 0) // prevent loading local files
        return false;
#endif
    for (auto &c : url)
    {
        if (c < 0 || c > 127)
            return false;
    }
    return true;
}

void checkSourceUrl(const String &url)
{
    if (!isValidSourceUrl(url))
        throw std::runtime_error("Bad source url: " + url);
}
<commit_msg>Fix build.<commit_after>/*
 * Copyright (C) 2016-2017, Egor Pugin
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "http.h"

#include <algorithm>

bool isValidSourceUrl(const String &url)
{
    if (url.empty())
        return false;
    if (!isUrl(url))
        return false;
    if (url.find_first_of(R"bbb('"`\|;$ @!#^*()<>[],)bbb") != url.npos)
        return false;
    // remove? will fail: ssh://name:pass@web.site
    if (std::count(url.begin(), url.end(), ':') > 1)
        return false;
    if (url.find("&&") != url.npos)
        return false;
#ifndef CPPAN_TEST
    if (url.find("file:") == 0) // prevent loading local files
        return false;
#endif
    for (auto &c : url)
    {
        if (c < 0 || c > 127)
            return false;
    }
    return true;
}

void checkSourceUrl(const String &url)
{
    if (!isValidSourceUrl(url))
        throw std::runtime_error("Bad source url: " + url);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include "random.h"
#include "skip_list.h"

struct foo
{
    foo()
    {
        std::cout << "Construct foo" << std::endl;
    }

    foo(foo const& f)
    {
        std::cout << "Copy construct foo" << std::endl;
    }

    ~foo()
    {
        std::cout << "Destroy foo" << std::endl;
    }
};

int main(int argc, char* argv[])
{
    std::srand(std::time(nullptr));

    random<float> randGen;
    {
        foo fu;
        algic::node<foo> nd(5, fu);
        algic::skip_list<int, random<float>>  slist(randGen);

        std::cout << std::endl << "List constains 12: " << slist.contains(12) << std::endl;

        for (int i = 0; i < 5000; ++i)
        {
            int const rnd = std::rand();
            slist.insert(rnd);
        }
        std::cout << std::endl << "Print list" << std::endl;

        slist.print();

        std::cout << std::endl << "List constains 12: " << slist.contains(12) << std::endl;
    }
    foo f;
    getchar();
    return 0;
}
<commit_msg>changed test code little bit<commit_after>#include <iostream>
#include <string>
#include "random.h"
#include "skip_list.h"

struct foo
{
    foo()
    {
        std::cout << "Construct foo" << std::endl;
    }

    foo(foo const& f)
    {
        std::cout << "Copy construct foo" << std::endl;
    }

    ~foo()
    {
        std::cout << "Destroy foo" << std::endl;
    }
};

int main(int argc, char* argv[])
{
    std::srand(static_cast<unsigned int>(std::time(nullptr)));

    random<float> randGen;
    algic::skip_list<int, random<float>>  slist(randGen);

    std::cout << std::endl << "List constains 12: " << slist.contains(12) << std::endl;

    for (int i = 0; i < 5000; ++i)
    {
        int const rnd = std::rand();
        slist.insert(rnd);
    }
    std::cout << std::endl << "Print list" << std::endl;

    slist.print();

    std::cout << std::endl << "List constains 12: " << slist.contains(12) << std::endl;

    getchar();
    return 0;
}
<|endoftext|>


<commit_before>// --------------------------------------------------------------------
//  main.cpp
//
//  Created by Barrett Davis on 5/8/16.
//  Copyright © 2016 Tree Frog Software. All rights reserved.
// --------------------------------------------------------------------
#include <iostream>
#include "Dnn.h"
#include "Error.h"

namespace tfs {

    bool
    testAssembly( void ) {
        // Taking an example from ConvNetJS cifar10: http://cs.stanford.edu/people/karpathy/convnetjs/demo/cifar10.html
//        layer_defs = [];
//        layer_defs.push({type:'input', out_sx:32, out_sy:32, out_depth:3});
//        layer_defs.push({type:'conv', sx:5, filters:16, stride:1, pad:2, activation:'relu'});
//        layer_defs.push({type:'pool', sx:2, stride:2});
//        layer_defs.push({type:'conv', sx:5, filters:20, stride:1, pad:2, activation:'relu'});
//        layer_defs.push({type:'pool', sx:2, stride:2});
//        layer_defs.push({type:'conv', sx:5, filters:20, stride:1, pad:2, activation:'relu'});
//        layer_defs.push({type:'pool', sx:2, stride:2});
//        layer_defs.push({type:'softmax', num_classes:10});
//
//        net = new convnetjs.Net();
//        net.makeLayers(layer_defs);
//
//        trainer = new convnetjs.SGDTrainer(net, {method:'adadelta', batch_size:4, l2_decay:0.0001});
        Dnn *dnn = new Dnn();
        // Input layer
        if( !dnn->addLayerInput( 32, 32, 3 )) {             // Input layer for RGB image
            return log_error( "Cannot add Input layer" );
        }
        // Convolution / Pool set:
        if( !dnn->addLayerConvolution( 5, 16, 1, 2 )) {
            return log_error( "Cannot add Convolution layer" );
        }
        if( !dnn->addLayerRectifiedLinearUnit()) {          // Activation function for previous layer.
            return log_error( "Cannot add ReLu layer" );
        }
        if( !dnn->addLayerPool( 2, 2 )) {
            return log_error( "Cannot add Pool layer" );
        }
        // Convolution / Pool set:
        if( !dnn->addLayerConvolution( 5, 20, 1, 2 )) {
            return log_error( "Cannot add Convolution layer" );
        }
        if( !dnn->addLayerRectifiedLinearUnit()) {          // Activation function for previous layer.
            return log_error( "Cannot add ReLu layer" );
        }
        if( !dnn->addLayerPool( 2, 2 )) {
            return log_error( "Cannot add Pool layer" );
        }
        // Convolution / Pool set:
        if( !dnn->addLayerConvolution( 5, 20, 1, 2 )) {
            return log_error( "Cannot add Convolution layer" );
        }
        if( !dnn->addLayerRectifiedLinearUnit()) {          // Activation function for previous layer.
            return log_error( "Cannot add ReLu layer" );
        }
        if( !dnn->addLayerPool( 2, 2 )) {
            return log_error( "Cannot add Pool layer" );
        }
        // Fully connected layer with softmax:
        if( !dnn->addLayerFullyConnected( 1, 1, 10 )) {
            return log_error( "Cannot add Fully Connected layer" );
        }
        if( !dnn->addLayerSoftmax( 10 )) {                  // Output classifier
            return log_error( "Cannot add Softmax layer" );
        }
        return true;
    }

}  // tfs namespace

int
main( int argc, const char * argv[] ) {
    std::cout << "Test DNN begin\n";

    tfs::testAssembly();

    std::cout << "Test DNN end\n";
    return 0;

}

<commit_msg>Added a few comments<commit_after>// --------------------------------------------------------------------
//  main.cpp
//
//  Created by Barrett Davis on 5/8/16.
//  Copyright © 2016 Tree Frog Software. All rights reserved.
// --------------------------------------------------------------------
#include <iostream>
#include "Dnn.h"
#include "Error.h"

namespace tfs {

    bool
    testAssembly( void ) {
        // Taking an example from ConvNetJS cifar10: http://cs.stanford.edu/people/karpathy/convnetjs/demo/cifar10.html
//        layer_defs = [];
//        layer_defs.push({type:'input', out_sx:32, out_sy:32, out_depth:3});
//        layer_defs.push({type:'conv', sx:5, filters:16, stride:1, pad:2, activation:'relu'});
//        layer_defs.push({type:'pool', sx:2, stride:2});
//        layer_defs.push({type:'conv', sx:5, filters:20, stride:1, pad:2, activation:'relu'});
//        layer_defs.push({type:'pool', sx:2, stride:2});
//        layer_defs.push({type:'conv', sx:5, filters:20, stride:1, pad:2, activation:'relu'});
//        layer_defs.push({type:'pool', sx:2, stride:2});
//        layer_defs.push({type:'softmax', num_classes:10});
//
//        net = new convnetjs.Net();
//        net.makeLayers(layer_defs);
//
//        trainer = new convnetjs.SGDTrainer(net, {method:'adadelta', batch_size:4, l2_decay:0.0001});
        Dnn *dnn = new Dnn();
        if( !dnn->addLayerInput( 32, 32, 3 )) {             // Input layer for 32x32 RGB image
            return log_error( "Cannot add Input layer" );
        }
        // Convolution / Pool set:
        if( !dnn->addLayerConvolution( 5, 16, 1, 2 )) {     // 16 5x5 filters for convolution
            return log_error( "Cannot add Convolution layer" );
        }
        if( !dnn->addLayerRectifiedLinearUnit()) {          // Activation function for previous layer.
            return log_error( "Cannot add ReLu layer" );
        }
        if( !dnn->addLayerPool( 2, 2 )) {
            return log_error( "Cannot add Pool layer" );
        }
        // Convolution / Pool set:
        if( !dnn->addLayerConvolution( 5, 20, 1, 2 )) {     // 20 5x5 filters for convolution
            return log_error( "Cannot add Convolution layer" );
        }
        if( !dnn->addLayerRectifiedLinearUnit()) {          // Activation function for previous layer.
            return log_error( "Cannot add ReLu layer" );
        }
        if( !dnn->addLayerPool( 2, 2 )) {
            return log_error( "Cannot add Pool layer" );
        }
        // Convolution / Pool set:
        if( !dnn->addLayerConvolution( 5, 20, 1, 2 )) {     // 20 5x5 filters for convolution
            return log_error( "Cannot add Convolution layer" );
        }
        if( !dnn->addLayerRectifiedLinearUnit()) {          // Activation function for previous layer.
            return log_error( "Cannot add ReLu layer" );
        }
        if( !dnn->addLayerPool( 2, 2 )) {
            return log_error( "Cannot add Pool layer" );
        }
        // Fully connected layer with softmax:
        if( !dnn->addLayerFullyConnected( 1, 1, 10 )) {
            return log_error( "Cannot add Fully Connected layer" );
        }
        if( !dnn->addLayerSoftmax( 10 )) {                  // Output classifier
            return log_error( "Cannot add Softmax layer" );
        }
        return true;
    }

}  // tfs namespace

int
main( int argc, const char * argv[] ) {
    std::cout << "Test DNN begin\n";

    tfs::testAssembly();

    std::cout << "Test DNN end\n";
    return 0;

}

<|endoftext|>


<commit_before>/**
 * Created by Jian Chen
 * @since  2016.08.21
 * @author Jian Chen <admin@chensoft.com>
 * @link   http://chensoft.com
 */
#include <socket/tcp/tcp_handler.hpp>
#include <cstring>

// -----------------------------------------------------------------------------
// conn
chen::tcp::conn::conn(bsd::socket &&s, std::unique_ptr<handler> &&h) : _handler(std::move(h))
{
    this->reset(std::move(s));
}

chen::tcp::conn::~conn()
{
    if (this->_socket)
        this->_socket.close();
}

void chen::tcp::conn::disconnect()
{
    // we shutdown the socket here, server will
    // receive the ended event and destroy this
    if (this->_socket)
        this->_socket.shutdown();

    this->_connected = false;
}

// read
void chen::tcp::conn::readSome()
{
    this->readSome(4096);  // 4096 is just a magic number
}

void chen::tcp::conn::readSome(std::size_t size)
{
    this->_policy.reset(new read_some_policy(size));
    this->receive();
}

void chen::tcp::conn::readAll()
{
    this->_policy.reset(new read_all_policy);
    this->receive();
}

void chen::tcp::conn::readLine()
{
    this->_policy.reset(new read_line_policy);
    this->receive();
}

void chen::tcp::conn::readExact(std::size_t size)
{
    this->_policy.reset(new read_exact_policy(size));
    this->receive();
}

void chen::tcp::conn::readUntil(const std::string &text)
{
    this->_policy.reset(new read_until_policy(text));
    this->receive();
}

// write
void chen::tcp::conn::write(const char *text)
{
    this->write(text, ::strlen(text));
}

void chen::tcp::conn::write(const std::string &text)
{
    this->write(text.data(), text.size());
}

void chen::tcp::conn::write(const void *data, std::size_t size)
{
    auto ptr = static_cast<const std::uint8_t*>(data);

    // if pending data exist, it means we are waiting for writable event
    // if socket is not established, we wait for the connection to be established
    if (!this->_buf_write.empty() || !this->isConnected())
    {
        this->_buf_write.insert(this->_buf_write.end(), ptr, ptr + size);
        return;
    }

    // try to use send directly first
    auto ret = this->_socket.send(data, size);
    auto len = static_cast<std::size_t>(ret >= 0 ? ret : 0);

    if (len == size)
    {
        // all data has been sent out
        this->_handler->onWrite(*this, len);
    }
    else
    {
        // store remaining data into buf
        this->_buf_write.insert(this->_buf_write.end(), ptr + len, ptr + size);

        // partial data has been sent
        if (len)
            this->_handler->onWrite(*this, len);
    }
}

// property
bool chen::tcp::conn::isConnected() const
{
    return this->_connected;
}

bool chen::tcp::conn::isDisconnect() const
{
    return !this->_connected;
}

chen::socket_t chen::tcp::conn::native() const
{
    return this->_socket.native();
}

// receive
void chen::tcp::conn::receive()
{
    if (!this->_policy)
        return;

    // read all available data to buf
    std::uint8_t buf[4096];  // 4096 is just a magic number, no specific meaning

    while (true)
    {
        auto len = this->_socket.recv(buf, 4096);
        if (len <= 0)
            break;

        this->_buf_read.insert(this->_buf_read.end(), buf, buf + len);
    }

    if (this->_buf_read.empty())
        return;

    // check and dispatch read event
    auto ptr = this->_policy.get();

    switch (ptr->type)
    {
        case policy::Type::Some:
            this->receive(*static_cast<read_some_policy*>(ptr));
            break;

        case policy::Type::All:
            this->receive(*static_cast<read_all_policy*>(ptr));
            break;

        case policy::Type::Line:
            this->receive(*static_cast<read_line_policy*>(ptr));
            break;

        case policy::Type::Exact:
            this->receive(*static_cast<read_exact_policy*>(ptr));
            break;

        case policy::Type::Until:
            this->receive(*static_cast<read_until_policy*>(ptr));
            break;
    }
}

void chen::tcp::conn::receive(read_some_policy &policy)
{
    if (this->_buf_read.size() <= policy.size)
    {
        // for performance, directly move buf if size <= policy.size
        this->_handler->onRead(*this, std::move(this->_buf_read));
    }
    else
    {
        // copy and move buffer data
        std::vector<std::uint8_t> data(this->_buf_read.begin(), this->_buf_read.begin() + policy.size);
        this->_buf_read.erase(this->_buf_read.begin(), this->_buf_read.begin() + policy.size);

        this->_handler->onRead(*this, std::move(data));
    }
}

void chen::tcp::conn::receive(read_all_policy &policy)
{
    this->_handler->onRead(*this, std::move(this->_buf_read));
}

void chen::tcp::conn::receive(read_line_policy &policy)
{
    auto ptr = (const char*)this->_buf_read.data();
    auto len = this->_buf_read.size();
    auto num = 0;

    for (std::size_t i = policy.pos; i < len; ++i)
    {
        auto ch = ptr[i];

        if (ch == '\n')
        {
            num = 1;

            // further checking the "\r\n" line delimiter
            if ((i > policy.pos) && (ptr[i - 1] == '\r'))
                num = 2;
        }

        if (num)
        {
            // notice, don't include the delimiter in returned data
            std::vector<std::uint8_t> data(ptr, ptr + i + 1 - num);
            this->_buf_read.erase(this->_buf_read.begin(), this->_buf_read.begin() + i + 1);

            return this->_handler->onRead(*this, std::move(data));
        }
    }

    // pass rest of the data if eof
    if (this->isDisconnect())
        return this->_handler->onRead(*this, std::move(this->_buf_read));

    // caching last search position
    policy.pos = len;
}

void chen::tcp::conn::receive(read_exact_policy &policy)
{
    auto size = this->_buf_read.size();

    if (size == policy.size)
    {
        // for performance, directly move buf if size == policy.size
        this->_handler->onRead(*this, std::move(this->_buf_read));
    }
    else if (size > policy.size)
    {
        // copy and move buffer data
        std::vector<std::uint8_t> data(this->_buf_read.begin(), this->_buf_read.begin() + policy.size);
        this->_buf_read.erase(this->_buf_read.begin(), this->_buf_read.begin() + policy.size);

        this->_handler->onRead(*this, std::move(data));
    }
}

void chen::tcp::conn::receive(read_until_policy &policy)
{
    auto len_buffer = this->_buf_read.size();
    auto len_policy = policy.text.size();

    if (len_buffer < len_policy)
        return;

    auto ptr_buffer = (const char*)this->_buf_read.data();
    auto ptr_policy = policy.text.data();

    std::size_t i = policy.pos;

    while (i < len_buffer)
    {
        std::size_t j = 0;

        for (; j < len_policy; ++j)
        {
            if (ptr_policy[j] != ptr_buffer[i])
            {
                i += j + 1;
                break;
            }
            else
            {
                ++i;
            }
        }

        if (j == len_policy)
        {
            // notice, don't include the delimiter in returned data
            std::vector<std::uint8_t> data(ptr_buffer, ptr_buffer + i - len_policy);
            this->_buf_read.erase(this->_buf_read.begin(), this->_buf_read.begin() + i);

            return this->_handler->onRead(*this, std::move(data));
        }
    }

    policy.pos = i;
}

// event
void chen::tcp::conn::onAccepted()
{
    this->_handler->onAccepted(*this);
}

void chen::tcp::conn::onReadable()
{
    this->receive();
}

void chen::tcp::conn::onWritable()
{
    // try to send all data
    if (this->_buf_write.empty())
        return;

    auto ret = this->_socket.send(this->_buf_write.data(), this->_buf_write.size());
    if (ret <= 0)
        return;

    // notify write callback
    this->_buf_write.erase(this->_buf_write.begin(), this->_buf_write.begin() + ret);
    this->_handler->onWrite(*this, static_cast<std::size_t>(ret));
}

void chen::tcp::conn::onEnded()
{
    // read rest of the data
    this->receive();

    // connection broken
    this->_connected = false;
    this->_handler->onDisconnect(*this);
}<commit_msg>tcp: make connection nonblocking<commit_after>/**
 * Created by Jian Chen
 * @since  2016.08.21
 * @author Jian Chen <admin@chensoft.com>
 * @link   http://chensoft.com
 */
#include <socket/tcp/tcp_handler.hpp>
#include <cstring>

// -----------------------------------------------------------------------------
// conn
chen::tcp::conn::conn(bsd::socket &&s, std::unique_ptr<handler> &&h) : _handler(std::move(h))
{
    this->reset(std::move(s));
    this->nonblocking(true);
}

chen::tcp::conn::~conn()
{
    if (this->_socket)
        this->_socket.close();
}

void chen::tcp::conn::disconnect()
{
    // we shutdown the socket here, server will
    // receive the ended event and destroy this
    if (this->_socket)
        this->_socket.shutdown();

    this->_connected = false;
}

// read
void chen::tcp::conn::readSome()
{
    this->readSome(4096);  // 4096 is just a magic number
}

void chen::tcp::conn::readSome(std::size_t size)
{
    this->_policy.reset(new read_some_policy(size));
    this->receive();
}

void chen::tcp::conn::readAll()
{
    this->_policy.reset(new read_all_policy);
    this->receive();
}

void chen::tcp::conn::readLine()
{
    this->_policy.reset(new read_line_policy);
    this->receive();
}

void chen::tcp::conn::readExact(std::size_t size)
{
    this->_policy.reset(new read_exact_policy(size));
    this->receive();
}

void chen::tcp::conn::readUntil(const std::string &text)
{
    this->_policy.reset(new read_until_policy(text));
    this->receive();
}

// write
void chen::tcp::conn::write(const char *text)
{
    this->write(text, ::strlen(text));
}

void chen::tcp::conn::write(const std::string &text)
{
    this->write(text.data(), text.size());
}

void chen::tcp::conn::write(const void *data, std::size_t size)
{
    auto ptr = static_cast<const std::uint8_t*>(data);

    // if pending data exist, it means we are waiting for writable event
    // if socket is not established, we wait for the connection to be established
    if (!this->_buf_write.empty() || !this->isConnected())
    {
        this->_buf_write.insert(this->_buf_write.end(), ptr, ptr + size);
        return;
    }

    // try to use send directly first
    auto ret = this->_socket.send(data, size);
    auto len = static_cast<std::size_t>(ret >= 0 ? ret : 0);

    if (len == size)
    {
        // all data has been sent out
        this->_handler->onWrite(*this, len);
    }
    else
    {
        // store remaining data into buf
        this->_buf_write.insert(this->_buf_write.end(), ptr + len, ptr + size);

        // partial data has been sent
        if (len)
            this->_handler->onWrite(*this, len);
    }
}

// property
bool chen::tcp::conn::isConnected() const
{
    return this->_connected;
}

bool chen::tcp::conn::isDisconnect() const
{
    return !this->_connected;
}

chen::socket_t chen::tcp::conn::native() const
{
    return this->_socket.native();
}

// receive
void chen::tcp::conn::receive()
{
    if (!this->_policy)
        return;

    // read all available data to buf
    std::uint8_t buf[4096];  // 4096 is just a magic number, no specific meaning

    while (true)
    {
        auto len = this->_socket.recv(buf, 4096);
        if (len <= 0)
            break;

        this->_buf_read.insert(this->_buf_read.end(), buf, buf + len);
    }

    if (this->_buf_read.empty())
        return;

    // check and dispatch read event
    auto ptr = this->_policy.get();

    switch (ptr->type)
    {
        case policy::Type::Some:
            this->receive(*static_cast<read_some_policy*>(ptr));
            break;

        case policy::Type::All:
            this->receive(*static_cast<read_all_policy*>(ptr));
            break;

        case policy::Type::Line:
            this->receive(*static_cast<read_line_policy*>(ptr));
            break;

        case policy::Type::Exact:
            this->receive(*static_cast<read_exact_policy*>(ptr));
            break;

        case policy::Type::Until:
            this->receive(*static_cast<read_until_policy*>(ptr));
            break;
    }
}

void chen::tcp::conn::receive(read_some_policy &policy)
{
    if (this->_buf_read.size() <= policy.size)
    {
        // for performance, directly move buf if size <= policy.size
        this->_handler->onRead(*this, std::move(this->_buf_read));
    }
    else
    {
        // copy and move buffer data
        std::vector<std::uint8_t> data(this->_buf_read.begin(), this->_buf_read.begin() + policy.size);
        this->_buf_read.erase(this->_buf_read.begin(), this->_buf_read.begin() + policy.size);

        this->_handler->onRead(*this, std::move(data));
    }
}

void chen::tcp::conn::receive(read_all_policy &policy)
{
    this->_handler->onRead(*this, std::move(this->_buf_read));
}

void chen::tcp::conn::receive(read_line_policy &policy)
{
    auto ptr = (const char*)this->_buf_read.data();
    auto len = this->_buf_read.size();
    auto num = 0;

    for (std::size_t i = policy.pos; i < len; ++i)
    {
        auto ch = ptr[i];

        if (ch == '\n')
        {
            num = 1;

            // further checking the "\r\n" line delimiter
            if ((i > policy.pos) && (ptr[i - 1] == '\r'))
                num = 2;
        }

        if (num)
        {
            // notice, don't include the delimiter in returned data
            std::vector<std::uint8_t> data(ptr, ptr + i + 1 - num);
            this->_buf_read.erase(this->_buf_read.begin(), this->_buf_read.begin() + i + 1);

            return this->_handler->onRead(*this, std::move(data));
        }
    }

    // pass rest of the data if eof
    if (this->isDisconnect())
        return this->_handler->onRead(*this, std::move(this->_buf_read));

    // caching last search position
    policy.pos = len;
}

void chen::tcp::conn::receive(read_exact_policy &policy)
{
    auto size = this->_buf_read.size();

    if (size == policy.size)
    {
        // for performance, directly move buf if size == policy.size
        this->_handler->onRead(*this, std::move(this->_buf_read));
    }
    else if (size > policy.size)
    {
        // copy and move buffer data
        std::vector<std::uint8_t> data(this->_buf_read.begin(), this->_buf_read.begin() + policy.size);
        this->_buf_read.erase(this->_buf_read.begin(), this->_buf_read.begin() + policy.size);

        this->_handler->onRead(*this, std::move(data));
    }
}

void chen::tcp::conn::receive(read_until_policy &policy)
{
    auto len_buffer = this->_buf_read.size();
    auto len_policy = policy.text.size();

    if (len_buffer < len_policy)
        return;

    auto ptr_buffer = (const char*)this->_buf_read.data();
    auto ptr_policy = policy.text.data();

    std::size_t i = policy.pos;

    while (i < len_buffer)
    {
        std::size_t j = 0;

        for (; j < len_policy; ++j)
        {
            if (ptr_policy[j] != ptr_buffer[i])
            {
                i += j + 1;
                break;
            }
            else
            {
                ++i;
            }
        }

        if (j == len_policy)
        {
            // notice, don't include the delimiter in returned data
            std::vector<std::uint8_t> data(ptr_buffer, ptr_buffer + i - len_policy);
            this->_buf_read.erase(this->_buf_read.begin(), this->_buf_read.begin() + i);

            return this->_handler->onRead(*this, std::move(data));
        }
    }

    policy.pos = i;
}

// event
void chen::tcp::conn::onAccepted()
{
    this->_handler->onAccepted(*this);
}

void chen::tcp::conn::onReadable()
{
    this->receive();
}

void chen::tcp::conn::onWritable()
{
    // try to send all data
    if (this->_buf_write.empty())
        return;

    auto ret = this->_socket.send(this->_buf_write.data(), this->_buf_write.size());
    if (ret <= 0)
        return;

    // notify write callback
    this->_buf_write.erase(this->_buf_write.begin(), this->_buf_write.begin() + ret);
    this->_handler->onWrite(*this, static_cast<std::size_t>(ret));
}

void chen::tcp::conn::onEnded()
{
    // read rest of the data
    this->receive();

    // connection broken
    this->_connected = false;
    this->_handler->onDisconnect(*this);
}<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
// taskwarrior - a command line task list manager.
//
// Copyright 2006-2013, Paul Beckingham, Federico Hernandez.
//
// 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.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <iostream>
#include <Context.h>
#include <Task.h>
#include <test.h>

Context context;

////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)
{
  UnitTest t (1);

  bool good = true;
  try {Task t_ff1 ("{}");}
  catch (const std::string& e){t.diag (e); good = false;}
  t.ok (good, "Task::Task ('{}')");

  return 0;
}

////////////////////////////////////////////////////////////////////////////////
<commit_msg>Unit Tests<commit_after>////////////////////////////////////////////////////////////////////////////////
// taskwarrior - a command line task list manager.
//
// Copyright 2006-2013, Paul Beckingham, Federico Hernandez.
//
// 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.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <iostream>
#include <Context.h>
#include <Task.h>
#include <test.h>

Context context;

////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)
{
  UnitTest t (2);

  bool good = true;
  try {Task t1 ("{}");}
  catch (const std::string& e){t.diag (e); good = false;}
  t.ok (good, "Task::Task ('{}')");

  good = true;
  try {Task t2 ("{\"uuid\":\"00000000-0000-0000-000000000001\",\"description\":\"foo\",\"entry\":1234567890}");}
  catch (const std::string& e){t.diag (e); good = false;}
  t.ok (good, "Task::Task ('{<minimal>}')");

  return 0;
}

////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>#include <mio/mmap.hpp>
#include <mio/shared_mmap.hpp>

#include <string>
#include <fstream>
#include <cstdlib>
#include <iostream>
#include <cassert>
#include <system_error>
#include <numeric>

int handle_error(const std::error_code& error)
{
    const auto& errmsg = error.message();
    std::printf("error mapping file: %s, exiting...\n", errmsg.c_str());
    return error.value();
}

// Just make sure this compiles.
#ifdef CXX17
# include <cstddef>
using mmap_source = mio::basic_mmap_source<std::byte>;
#endif

int main()
{
    const char _path[] = "test-file";
    // Make sure mio compiles with non-const char* strings too.
    const int path_len = sizeof(_path);
    char* path = new char[path_len];
    std::copy(_path, _path + path_len, path);
    std::error_code error;
    // Fill buffer, then write it to file.
    const int file_size = 0x4000 - 250;
    std::string buffer(file_size, 0);
    std::iota(buffer.begin(), buffer.end(), 1);
    std::ofstream file(path);
    file << buffer;
    file.close();

    const size_t offset = 300;
    assert(offset < buffer.size());

    {
        // Map the region of the file to which buffer was written.
        mio::mmap_source file_view = mio::make_mmap_source(
                path, offset, mio::map_entire_file, error);
        if(error) { return handle_error(error); }

        const size_t mapped_size = buffer.size() - offset;
        assert(file_view.is_open());
        assert(file_view.size() == mapped_size);

        // Then verify that mmap's bytes correspond to that of buffer.
        for(size_t buf_idx = offset, view_idx = 0;
                buf_idx < buffer.size() && view_idx < mapped_size;
                ++buf_idx, ++view_idx) {
            if(file_view[view_idx] != buffer[buf_idx]) {
                std::printf("%luth byte mismatch: expected(%d) <> actual(%d)",
                        buf_idx, buffer[buf_idx], file_view[view_idx]);
                std::cout << std::flush;
                assert(0);
            }
        }

        // Turn file_view into a shared mmap.
        mio::shared_mmap_source shared_file_view(std::move(file_view));

        assert(!file_view.is_open());
        assert(shared_file_view.is_open());
        assert(shared_file_view.size() == mapped_size);

        // Then verify that shared_mmap's bytes correspond to that of buffer.
        for(size_t buf_idx = offset, view_idx = 0;
                buf_idx < buffer.size() && view_idx < mapped_size;
                ++buf_idx, ++view_idx) {
            if(shared_file_view[view_idx] != buffer[buf_idx]) {
                std::printf("%luth byte mismatch: expected(%d) <> actual(%d)",
                        buf_idx, buffer[buf_idx], shared_file_view[view_idx]);
                std::cout << std::flush;
                assert(0);
            }
        }
    }

    {
#define CHECK_INVALID_MMAP(m) do { \
        assert(error); \
        assert(m.empty()); \
        assert(!m.is_open()); \
        error.clear(); } while(0)

        mio::mmap_source m;

        // See if mapping an invalid file results in an error.
        m = mio::make_mmap_source("garbage-that-hopefully-doesnt-exist", 0, 0, error);
        CHECK_INVALID_MMAP(m);

        // Empty path?
        m = mio::make_mmap_source(static_cast<const char*>(0), 0, 0, error);
        CHECK_INVALID_MMAP(m);
        m = mio::make_mmap_source(std::string(), 0, 0, error);
        CHECK_INVALID_MMAP(m);

        // Invalid handle?
        m = mio::make_mmap_source(mio::invalid_handle, 0, 0, error);
        CHECK_INVALID_MMAP(m);

        // Invalid offset?
        m = mio::make_mmap_source(path, 100 * buffer.size(), buffer.size(), error);
        CHECK_INVALID_MMAP(m);
    }

    {
        // Make sure these compile.
        mio::ummap_source _1;
        mio::shared_ummap_source _2;
        // Make sure shared_mmap mapping compiles as all testing was done on
        // normal mmaps.
        mio::shared_mmap_source _3(path, 0, mio::map_entire_file);
        auto _4 = mio::make_mmap_source(path, error);
        auto _5 = mio::make_mmap<mio::shared_mmap_source>(path, 0, mio::map_entire_file, error);
#ifdef _WIN32
        const wchar_t* wpath1 = L"dasfsf";
        auto _6 = mio::make_mmap_source(wpath1, error);
        mio::mmap_source _7;
        _7.map(wpath1, error);
        const std::wstring wpath2 = wpath1;
        auto _8 = mio::make_mmap_source(wpath2, error);
        mio::mmap_source _9;
        _9.map(wpath1, error);
#endif
    }

    std::printf("all tests passed!\n");
}
<commit_msg>Start using human-readable output for test file<commit_after>#include <mio/mmap.hpp>
#include <mio/shared_mmap.hpp>

#include <string>
#include <fstream>
#include <cstdlib>
#include <iostream>
#include <cassert>
#include <system_error>
#include <numeric>

int handle_error(const std::error_code& error)
{
    const auto& errmsg = error.message();
    std::printf("error mapping file: %s, exiting...\n", errmsg.c_str());
    return error.value();
}

// Just make sure this compiles.
#ifdef CXX17
# include <cstddef>
using mmap_source = mio::basic_mmap_source<std::byte>;
#endif

int main()
{
    const char _path[] = "test-file";
    // Make sure mio compiles with non-const char* strings too.
    const int path_len = sizeof(_path);
    char* path = new char[path_len];
    std::copy(_path, _path + path_len, path);
    std::error_code error;
    // Fill buffer, then write it to file.
    const int file_size = 0x4000 - 250; // 16134
    std::string buffer(file_size, 0);
    // Start at first printable ASCII character.
    char v = 33;
    for (auto& b : buffer) {
       b = v;
       ++v;
       // Limit to last printable ASCII character.
       v %= 126;
       if(v == 0) {
           v = 33;
       }
    }
    std::ofstream file(path);
    file << buffer;
    file.close();

    const size_t offset = 300;
    assert(offset < buffer.size());

    {
        // Map the region of the file to which buffer was written.
        mio::mmap_source file_view = mio::make_mmap_source(
                path, offset, mio::map_entire_file, error);
        if(error) { return handle_error(error); }

        const size_t mapped_size = buffer.size() - offset; // 15834
        assert(file_view.is_open());
        assert(file_view.size() == mapped_size);

        // Then verify that mmap's bytes correspond to that of buffer.
        for(size_t buf_idx = offset, view_idx = 0;
                buf_idx < buffer.size() && view_idx < mapped_size;
                ++buf_idx, ++view_idx) {
            if(file_view[view_idx] != buffer[buf_idx]) {
                std::printf("%luth byte mismatch: expected(%d) <> actual(%d)",
                        buf_idx, buffer[buf_idx], file_view[view_idx]);
                std::cout << std::flush;
                assert(0);
            }
        }

        // Turn file_view into a shared mmap.
        mio::shared_mmap_source shared_file_view(std::move(file_view));

        assert(!file_view.is_open());
        assert(shared_file_view.is_open());
        assert(shared_file_view.size() == mapped_size);

        // Then verify that shared_mmap's bytes correspond to that of buffer.
        for(size_t buf_idx = offset, view_idx = 0;
                buf_idx < buffer.size() && view_idx < mapped_size;
                ++buf_idx, ++view_idx) {
            if(shared_file_view[view_idx] != buffer[buf_idx]) {
                std::printf("%luth byte mismatch: expected(%d) <> actual(%d)",
                        buf_idx, buffer[buf_idx], shared_file_view[view_idx]);
                std::cout << std::flush;
                assert(0);
            }
        }
    }

    {
#define CHECK_INVALID_MMAP(m) do { \
        assert(error); \
        assert(m.empty()); \
        assert(!m.is_open()); \
        error.clear(); } while(0)

        mio::mmap_source m;

        // See if mapping an invalid file results in an error.
        m = mio::make_mmap_source("garbage-that-hopefully-doesnt-exist", 0, 0, error);
        CHECK_INVALID_MMAP(m);

        // Empty path?
        m = mio::make_mmap_source(static_cast<const char*>(0), 0, 0, error);
        CHECK_INVALID_MMAP(m);
        m = mio::make_mmap_source(std::string(), 0, 0, error);
        CHECK_INVALID_MMAP(m);

        // Invalid handle?
        m = mio::make_mmap_source(mio::invalid_handle, 0, 0, error);
        CHECK_INVALID_MMAP(m);

        // Invalid offset?
        m = mio::make_mmap_source(path, 100 * buffer.size(), buffer.size(), error);
        CHECK_INVALID_MMAP(m);
    }

    {
        // Make sure these compile.
        mio::ummap_source _1;
        mio::shared_ummap_source _2;
        // Make sure shared_mmap mapping compiles as all testing was done on
        // normal mmaps.
        mio::shared_mmap_source _3(path, 0, mio::map_entire_file);
        auto _4 = mio::make_mmap_source(path, error);
        auto _5 = mio::make_mmap<mio::shared_mmap_source>(path, 0, mio::map_entire_file, error);
#ifdef _WIN32
        const wchar_t* wpath1 = L"dasfsf";
        auto _6 = mio::make_mmap_source(wpath1, error);
        mio::mmap_source _7;
        _7.map(wpath1, error);
        const std::wstring wpath2 = wpath1;
        auto _8 = mio::make_mmap_source(wpath2, error);
        mio::mmap_source _9;
        _9.map(wpath1, error);
#endif
    }

    std::printf("all tests passed!\n");
}
<|endoftext|>


<commit_before>#define CATCH_CONFIG_RUNNER
#include "catch.hpp"

#include "variant.hpp"
#include <cstdint>
#include <limits>
#include <string>
#include <ostream>
#include <memory>

TEST_CASE( "variant version", "[variant]" ) {
    unsigned int version = VARIANT_VERSION;
    REQUIRE(version == 100);
    #if VARIANT_VERSION == 100
        REQUIRE(true);
    #else
        REQUIRE(false);
    #endif
}

TEST_CASE( "variant can be moved into vector", "[variant]" ) {
    typedef util::variant<bool,std::string> variant_type;
    variant_type v(std::string("test"));
    std::vector<variant_type> vec;
    vec.emplace_back(std::move(v));
    REQUIRE(v.get<std::string>() != std::string("test"));
    REQUIRE(vec.at(0).get<std::string>() == std::string("test"));
}

TEST_CASE( "variant should support built-in types", "[variant]" ) {
    SECTION( "bool" ) {
        util::variant<bool> v(true);
        REQUIRE(v.valid());
        REQUIRE(v.is<bool>());
        REQUIRE(v.get<bool>() == true);
        v.set<bool>(false);
        REQUIRE(v.get<bool>() == false);
        v = true;
        REQUIRE(v == util::variant<bool>(true));
    }
    SECTION( "nullptr" ) {
        typedef std::nullptr_t value_type;
        util::variant<value_type> v(nullptr);
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        // TODO: commented since it breaks on windows: 'operator << is ambiguous'
        //REQUIRE(v.get<value_type>() == nullptr);
        // FIXME: does not compile: ./variant.hpp:340:14: error: use of overloaded operator '<<' is ambiguous (with operand types 'std::__1::basic_ostream<char>' and 'const nullptr_t')
        // https://github.com/mapbox/variant/issues/14
        //REQUIRE(v == util::variant<value_type>(nullptr));
    }
    SECTION( "unique_ptr" ) {
        typedef std::unique_ptr<std::string> value_type;
        util::variant<value_type> v(value_type(new std::string("hello")));
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(*v.get<value_type>().get() == *value_type(new std::string("hello")).get());
    }
    SECTION( "string" ) {
        typedef std::string value_type;
        util::variant<value_type> v(value_type("hello"));
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get<value_type>() == value_type("hello"));
        v.set<value_type>(value_type("there"));
        REQUIRE(v.get<value_type>() == value_type("there"));
        v = value_type("variant");
        REQUIRE(v == util::variant<value_type>(value_type("variant")));
    }
    SECTION( "size_t" ) {
        typedef std::size_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(value_type(0));
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
    SECTION( "int8_t" ) {
        typedef std::int8_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(0);
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
    SECTION( "int16_t" ) {
        typedef std::int16_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(0);
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
    SECTION( "int32_t" ) {
        typedef std::int32_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(0);
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
    SECTION( "int64_t" ) {
        typedef std::int64_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(0);
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
}

struct MissionInteger
{
    typedef uint64_t value_type;
    value_type val_;
    public:
      MissionInteger(uint64_t val) :
       val_(val) {}

    bool operator==(MissionInteger const& rhs) const
    {
        return (val_ == rhs.get());
    }

    uint64_t get() const
    {
        return val_;
    }
};

// TODO - remove after https://github.com/mapbox/variant/issues/14
std::ostream& operator<< (std::ostream& os, MissionInteger const& rhs)
{
    os << rhs.get();
    return os;
}

TEST_CASE( "variant should support custom types", "[variant]" ) {
    // http://www.missionintegers.com/integer/34838300
    util::variant<MissionInteger> v(MissionInteger(34838300));
    REQUIRE(v.valid());
    REQUIRE(v.is<MissionInteger>());
    REQUIRE(v.get<MissionInteger>() == MissionInteger(34838300));
    REQUIRE(v.get<MissionInteger>().get() == MissionInteger::value_type(34838300));
    // TODO: should both of the set usages below compile?
    v.set<MissionInteger>(MissionInteger::value_type(0));
    v.set<MissionInteger>(MissionInteger(0));
    REQUIRE(v.get<MissionInteger>().get() == MissionInteger::value_type(0));
    v = MissionInteger(1);
    REQUIRE(v == util::variant<MissionInteger>(MissionInteger(1)));
}

// Test detail code (internal api not mean for public use)
TEST_CASE( "variant type traits", "[variant::detail]" ) {
    // users should not create variants with duplicated types
    // however our type indexing should still work
    // Note index for types in reverse order
    REQUIRE((util::detail::type_traits<bool, bool, int, double, std::string>::id == 3));
    REQUIRE((util::detail::type_traits<int, bool, int, double, std::string>::id == 2));
    REQUIRE((util::detail::type_traits<double, bool, int, double, std::string>::id == 1));
    REQUIRE((util::detail::type_traits<std::string, bool, int, double, std::string>::id == 0));
    REQUIRE((util::detail::type_traits<long, bool, int, double, std::string>::id == util::detail::invalid_value));
    REQUIRE((util::detail::type_traits<std::vector<int>, bool, int, double, std::string>::id == util::detail::invalid_value));
}

int main (int argc, char* const argv[])
{
    int result = Catch::Session().run( argc, argv );
    if (!result) printf("\x1b[1;32m ✓ \x1b[0m\n");
    return result;
}
<commit_msg>fix typo in code comment [skip ci]<commit_after>#define CATCH_CONFIG_RUNNER
#include "catch.hpp"

#include "variant.hpp"
#include <cstdint>
#include <limits>
#include <string>
#include <ostream>
#include <memory>

TEST_CASE( "variant version", "[variant]" ) {
    unsigned int version = VARIANT_VERSION;
    REQUIRE(version == 100);
    #if VARIANT_VERSION == 100
        REQUIRE(true);
    #else
        REQUIRE(false);
    #endif
}

TEST_CASE( "variant can be moved into vector", "[variant]" ) {
    typedef util::variant<bool,std::string> variant_type;
    variant_type v(std::string("test"));
    std::vector<variant_type> vec;
    vec.emplace_back(std::move(v));
    REQUIRE(v.get<std::string>() != std::string("test"));
    REQUIRE(vec.at(0).get<std::string>() == std::string("test"));
}

TEST_CASE( "variant should support built-in types", "[variant]" ) {
    SECTION( "bool" ) {
        util::variant<bool> v(true);
        REQUIRE(v.valid());
        REQUIRE(v.is<bool>());
        REQUIRE(v.get<bool>() == true);
        v.set<bool>(false);
        REQUIRE(v.get<bool>() == false);
        v = true;
        REQUIRE(v == util::variant<bool>(true));
    }
    SECTION( "nullptr" ) {
        typedef std::nullptr_t value_type;
        util::variant<value_type> v(nullptr);
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        // TODO: commented since it breaks on windows: 'operator << is ambiguous'
        //REQUIRE(v.get<value_type>() == nullptr);
        // FIXME: does not compile: ./variant.hpp:340:14: error: use of overloaded operator '<<' is ambiguous (with operand types 'std::__1::basic_ostream<char>' and 'const nullptr_t')
        // https://github.com/mapbox/variant/issues/14
        //REQUIRE(v == util::variant<value_type>(nullptr));
    }
    SECTION( "unique_ptr" ) {
        typedef std::unique_ptr<std::string> value_type;
        util::variant<value_type> v(value_type(new std::string("hello")));
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(*v.get<value_type>().get() == *value_type(new std::string("hello")).get());
    }
    SECTION( "string" ) {
        typedef std::string value_type;
        util::variant<value_type> v(value_type("hello"));
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get<value_type>() == value_type("hello"));
        v.set<value_type>(value_type("there"));
        REQUIRE(v.get<value_type>() == value_type("there"));
        v = value_type("variant");
        REQUIRE(v == util::variant<value_type>(value_type("variant")));
    }
    SECTION( "size_t" ) {
        typedef std::size_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(value_type(0));
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
    SECTION( "int8_t" ) {
        typedef std::int8_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(0);
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
    SECTION( "int16_t" ) {
        typedef std::int16_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(0);
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
    SECTION( "int32_t" ) {
        typedef std::int32_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(0);
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
    SECTION( "int64_t" ) {
        typedef std::int64_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(0);
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
}

struct MissionInteger
{
    typedef uint64_t value_type;
    value_type val_;
    public:
      MissionInteger(uint64_t val) :
       val_(val) {}

    bool operator==(MissionInteger const& rhs) const
    {
        return (val_ == rhs.get());
    }

    uint64_t get() const
    {
        return val_;
    }
};

// TODO - remove after https://github.com/mapbox/variant/issues/14
std::ostream& operator<< (std::ostream& os, MissionInteger const& rhs)
{
    os << rhs.get();
    return os;
}

TEST_CASE( "variant should support custom types", "[variant]" ) {
    // http://www.missionintegers.com/integer/34838300
    util::variant<MissionInteger> v(MissionInteger(34838300));
    REQUIRE(v.valid());
    REQUIRE(v.is<MissionInteger>());
    REQUIRE(v.get<MissionInteger>() == MissionInteger(34838300));
    REQUIRE(v.get<MissionInteger>().get() == MissionInteger::value_type(34838300));
    // TODO: should both of the set usages below compile?
    v.set<MissionInteger>(MissionInteger::value_type(0));
    v.set<MissionInteger>(MissionInteger(0));
    REQUIRE(v.get<MissionInteger>().get() == MissionInteger::value_type(0));
    v = MissionInteger(1);
    REQUIRE(v == util::variant<MissionInteger>(MissionInteger(1)));
}

// Test detail code (internal api not meant for public use)
TEST_CASE( "variant type traits", "[variant::detail]" ) {
    // users should not create variants with duplicated types
    // however our type indexing should still work
    // Note index for types in reverse order
    REQUIRE((util::detail::type_traits<bool, bool, int, double, std::string>::id == 3));
    REQUIRE((util::detail::type_traits<int, bool, int, double, std::string>::id == 2));
    REQUIRE((util::detail::type_traits<double, bool, int, double, std::string>::id == 1));
    REQUIRE((util::detail::type_traits<std::string, bool, int, double, std::string>::id == 0));
    REQUIRE((util::detail::type_traits<long, bool, int, double, std::string>::id == util::detail::invalid_value));
    REQUIRE((util::detail::type_traits<std::vector<int>, bool, int, double, std::string>::id == util::detail::invalid_value));
}

int main (int argc, char* const argv[])
{
    int result = Catch::Session().run( argc, argv );
    if (!result) printf("\x1b[1;32m ✓ \x1b[0m\n");
    return result;
}
<|endoftext|>


<commit_before>#include "matrix.hxx"

#include <cstring>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>

#include "../exceptions.hxx"

using namespace std;

namespace game_of_life
{
Matrix::Matrix()
{}

Matrix::Matrix(size_t height, size_t width):
    height(height),
    width(width),
    data(new bool[height * width])
{
    memset(data, 0, height * width * sizeof(bool));
}

Matrix::Matrix(const AbstractTile& t):
    height(t.getHeight()),
    width(t.getWidth()),
    data(new bool[height * width])
{
    AbstractTile::copyValues(t);
}

Matrix::Matrix(Matrix&& temp):
    height(temp.height),
    width(temp.width),
    data(temp.data)
{
    temp.data = NULL;
}

Matrix::~Matrix() { delete[] data; }

void Matrix::operator=(const Matrix& m)
{
    if (width != m.width || height != m.height)
    {
        width = m.width;
        height = m.height;
        delete[] data;
        data = new bool[width * height];
    }
    memcpy(data, m.data, height * width * sizeof(data[0]));
}

size_t Matrix::getHeight() const { return height; }
size_t Matrix::getWidth() const { return width; }

bool Matrix::at(coord_t r, coord_t c) const { return data[r * getWidth() + c]; }
void Matrix::set(coord_t r, coord_t c, bool v) { data[r * getWidth() + c] = v; }

Matrix Matrix::fromCsv(std::istream& in)
{
    vector<pair<int, int>> alive;
    string line;
    int h = 0;
    int w = 0;
    for (; getline(in, line); ++h)
    {
        istringstream iss(line);
        int i = 0;
        string s;
        for (; getline(iss, s, ';'); ++i)
        {
            if (s == "1" || s == "#")
                alive.push_back(make_pair(h-1, i));
            else if (s != "0" && s != ".")
                throw InputError("CSV incorrect");
        }
        w = max(w, i);
    }
    Matrix ret(h, w);
    for (size_t i = 0; i < alive.size(); ++i)
        ret.set(alive[i].first, alive[i].second, true);
    return ret;
}

Matrix Matrix::random(size_t height, size_t width, int seed)
{
    Matrix ret(height, width);

    srand(seed);
    int n = rand() % (height * width + 1);

    memset(ret.data, 1, n * sizeof(bool));
    random_shuffle(ret.data, ret.data + height * width);

    return ret;
}

}

<commit_msg>Fix csv reading<commit_after>#include "matrix.hxx"

#include <cstring>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>

#include "../exceptions.hxx"

using namespace std;

namespace game_of_life
{
Matrix::Matrix()
{}

Matrix::Matrix(size_t height, size_t width):
    height(height),
    width(width),
    data(new bool[height * width])
{
    memset(data, 0, height * width * sizeof(bool));
}

Matrix::Matrix(const AbstractTile& t):
    height(t.getHeight()),
    width(t.getWidth()),
    data(new bool[height * width])
{
    AbstractTile::copyValues(t);
}

Matrix::Matrix(Matrix&& temp):
    height(temp.height),
    width(temp.width),
    data(temp.data)
{
    temp.data = NULL;
}

Matrix::~Matrix() { delete[] data; }

void Matrix::operator=(const Matrix& m)
{
    if (width != m.width || height != m.height)
    {
        width = m.width;
        height = m.height;
        delete[] data;
        data = new bool[width * height];
    }
    memcpy(data, m.data, height * width * sizeof(data[0]));
}

size_t Matrix::getHeight() const { return height; }
size_t Matrix::getWidth() const { return width; }

bool Matrix::at(coord_t r, coord_t c) const { return data[r * getWidth() + c]; }
void Matrix::set(coord_t r, coord_t c, bool v) { data[r * getWidth() + c] = v; }

Matrix Matrix::fromCsv(std::istream& in)
{
    vector<pair<int, int>> alive;
    string line;
    int h = 0;
    int w = 0;
    for (; getline(in, line); ++h)
    {
        istringstream iss(line);
        int i = 0;
        string s;
        for (; getline(iss, s, ';'); ++i)
        {
            if (s == "1" || s == "#")
                alive.push_back(make_pair(h, i));
            else if (s != "0" && s != ".")
                throw InputError("CSV incorrect");
        }
        w = max(w, i);
    }
    Matrix ret(h, w);
    for (size_t i = 0; i < alive.size(); ++i)
        ret.set(alive[i].first, alive[i].second, true);
    return ret;
}

Matrix Matrix::random(size_t height, size_t width, int seed)
{
    Matrix ret(height, width);

    srand(seed);
    int n = rand() % (height * width + 1);

    memset(ret.data, 1, n * sizeof(bool));
    random_shuffle(ret.data, ret.data + height * width);

    return ret;
}

}

<|endoftext|>


<commit_before>#include <stdio.h>
#include <time.h>
#include <math.h>
#include "expr.h"

double myrandom() {
    return double(rand()) / RAND_MAX;
}

double sqr(double x) {
    return x*x;
}

double len2(double a, double b) {
    return sqrt(a*a + b*b);
}

int main() {
    Expr::addFunction("sqr", sqr);
    Expr::addFunction("len2", len2);

    struct Test { const char *expr; int err; double result; } tests[] = {
        {"1", -1, 1.0},
        {"1+1", -1, 2.0},
        {"3 * 4", -1, 12.0},
        {"((1))", -1, 1.0},
        {"3*--3", -1, 9.0},
        {"1+2*(3+4)", -1, 15.0},
        {"1+2*(3+4*(5+6.5))", -1, 99.0},
        {"x1", -1, 100.0},
        {"x1+y1*2", -1, 500},
        {"1--1", -1, 2},
        {"1/(8--8) ; this comment is ignored", -1, 0.0625},
        {"1/;internal comment\n(8--8)", -1, 0.0625},
        {"1<2", -1, 1.0},
        {"1<=2", -1, 1.0},
        {"1>2", -1, 0.0},
        {"1>=2", -1, 0.0},
        {"1==2", -1, 0.0},
        {"1!=2", -1, 1.0},
        {"1!=2", -1, 1.0},
        {"1<2 && 3<4", -1, 1.0},
        {"1<2 && 3>4", -1, 0.0},
        {"1<2 || 3<4", -1, 1.0},
        {"1<2 || 3>4", -1, 1.0},
        {"(0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1)!=1.0", -1, 1.0}, // Approximation!

        {"1 | 2 == 3", -1, 1.0},
        {"3 ^ 2 == 1", -1, 1.0},
        {"3 ^ 1 == 2", -1, 1.0},
        {"-1 & 7 == 7", -1, 1.0},
        {"-1 >> 1 == -1", -1, 1.0},
        {"-1 << 1 == -2", -1, 1.0},
        {"(1 << 16)-1 >> 8 == 255", -1, 1.0},

        {"abs(-1)", -1, 1.0},
        {"cos(1-1)", -1, 1.0},
        {"abs(cos(3.141592654 * 0.5)) < 1E-6", -1, 1.0},
        {"cos()", 4, -1},
        {"atan2(12)", 8, -1},
        {"atan2(0, 1)", -1, 0},
        {"abs(atan(1)-3.141592654/4) < 1E-6", -1, 1.0},
        {"random() != 1.2", -1, 1.0},
        {"abs(log(1024)/log(2) - 10) < 1E-6", -1, 1.0},
        {"floor(pow(2, 8) + 0.5) == 256", -1, 1.0},
        {"abs(sqrt(2)*sqrt(2) - 2) < 1E-6", -1, 1.0},
        {"abs(tan(3.141592654/4)-1) < 1E-6", -1, 1.0},
        {"abs(log(exp(13)) - 13) < 1E-6", -1, 1.0},
        {"abs(len2(3,4) - 5) < 1E-6", -1, 1.0},
        {"sqr(3) == 9", -1, 1.0},

        {"1+z2*4", 4, -1},
        {"1+2*", 4, -1},
        {"1+(2*3", 6, -1},
        {"1+2()", 3, -1},
        {"+1", 0, -1},
    };

    std::map<std::string, double> vars;
    vars["x0"] = 3.14;
    vars["y0"] = 2.718;
    vars["x1"] = 100;
    vars["y1"] = 200;

    int errors = 0;
    int ntests = sizeof(tests)/sizeof(tests[0]);
    for (int i=0; i<ntests; i++) {
        const char *s = tests[i].expr;
        double res = -1;
        try {
            Expr expr = Expr::partialParse(s, vars);
            if (*s) throw Expr::Error("Extra characters");
            if (tests[i].err != -1) throw Expr::Error("Parsing should have failed");
            res = expr.eval();
            if (tests[i].result != res) throw Expr::Error("Unexpected result");
        } catch (Expr::Error& err) {
            if (tests[i].err == s - tests[i].expr) {
                // Ok; parsing error position is correct
            } else {
                errors++;
                printf("TEST FAILED: \"%s\" (err=%i, result=%0.3f) --> res=%0.3f\n%s\n\n",
                       tests[i].expr, tests[i].err, tests[i].result,
                       res, err.what());
            }
        }
    }
    printf("%i errors on %i tests\n", errors, ntests);

    int w=640, h=480;
    vars["k"] = 10*3.141592654 / ((w*w+h*h)/4);
    double& y = vars["y"];
    double& x = vars["x"];
    std::vector<unsigned char> img(w*h);
    Expr e("((128 + sin(((x-320)*(x-320) + (y-240)*(y-240))*k)*127) ^"
           " (255 * ((floor(x/128)+floor(y/96)) & 1))) + random()*32-16", vars);
    printf("Expression compiled code:\n%s\n", e.disassemble().c_str());
    clock_t start = clock();
    int i = 0;
    for (y=0; y<h; y++) {
        for (x=0; x<w; x++) {
            int ie = int(e);
            if (ie < 0) ie = 0; if (ie > 255) ie = 255;
            img[i++] = ie;
        }
    }
    clock_t stop = clock();
    printf("Test image generated in %0.3fms (%.0f pixels/sec)\n",
           (stop - start)*1000.0/CLOCKS_PER_SEC,
           double(w*h)*CLOCKS_PER_SEC/(stop-start+1));
    FILE *f = fopen("test.pgm", "wb");
    if (f) {
        fprintf(f, "P5\n%i %i 255\n", w, h);
        fwrite(&img[0], 1, w*h, f);
        fclose(f);
    } else {
        fprintf(stderr, "Error generating test.pgm\n");
    }

    clock_t start2 = clock();
    i = 0;
    double k = vars["k"];
    for (y=0; y<h; y++) {
        for (x=0; x<w; x++) {
            int ie = int(
                (int(128 + sin(((x-320)*(x-320) + (y-240)*(y-240))*k)*127) ^
                 int(255 * (int(floor(x/128)+floor(y/96)) & 1))) + myrandom()*32-16);
            if (ie < 0) ie = 0; if (ie > 255) ie = 255;
            img[i++] = ie;
        }
    }
    clock_t stop2 = clock();
    printf("Test image generated natively in %0.3fms (%.0f pixels/sec)\n",
           (stop2 - start2)*1000.0/CLOCKS_PER_SEC,
           double(w*h)*CLOCKS_PER_SEC/(stop2-start2+1));
    f = fopen("test_native.pgm", "wb");
    if (f) {
        fprintf(f, "P5\n%i %i 255\n", w, h);
        fwrite(&img[0], 1, w*h, f);
        fclose(f);
    } else {
        fprintf(stderr, "Error generating test_native.pgm\n");
    }

    return errors != 0;
}
<commit_msg>longer speed test for better accuracy<commit_after>#include <stdio.h>
#include <time.h>
#include <math.h>
#include "expr.h"

double myrandom() {
    return double(rand()) / RAND_MAX;
}

double sqr(double x) {
    return x*x;
}

double len2(double a, double b) {
    return sqrt(a*a + b*b);
}

int main() {
    Expr::addFunction("sqr", sqr);
    Expr::addFunction("len2", len2);

    struct Test { const char *expr; int err; double result; } tests[] = {
        {"1", -1, 1.0},
        {"1+1", -1, 2.0},
        {"3 * 4", -1, 12.0},
        {"((1))", -1, 1.0},
        {"3*--3", -1, 9.0},
        {"1+2*(3+4)", -1, 15.0},
        {"1+2*(3+4*(5+6.5))", -1, 99.0},
        {"x1", -1, 100.0},
        {"x1+y1*2", -1, 500},
        {"1--1", -1, 2},
        {"1/(8--8) ; this comment is ignored", -1, 0.0625},
        {"1/;internal comment\n(8--8)", -1, 0.0625},
        {"1<2", -1, 1.0},
        {"1<=2", -1, 1.0},
        {"1>2", -1, 0.0},
        {"1>=2", -1, 0.0},
        {"1==2", -1, 0.0},
        {"1!=2", -1, 1.0},
        {"1!=2", -1, 1.0},
        {"1<2 && 3<4", -1, 1.0},
        {"1<2 && 3>4", -1, 0.0},
        {"1<2 || 3<4", -1, 1.0},
        {"1<2 || 3>4", -1, 1.0},
        {"(0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1)!=1.0", -1, 1.0}, // Approximation!

        {"1 | 2 == 3", -1, 1.0},
        {"3 ^ 2 == 1", -1, 1.0},
        {"3 ^ 1 == 2", -1, 1.0},
        {"-1 & 7 == 7", -1, 1.0},
        {"-1 >> 1 == -1", -1, 1.0},
        {"-1 << 1 == -2", -1, 1.0},
        {"(1 << 16)-1 >> 8 == 255", -1, 1.0},

        {"abs(-1)", -1, 1.0},
        {"cos(1-1)", -1, 1.0},
        {"abs(cos(3.141592654 * 0.5)) < 1E-6", -1, 1.0},
        {"cos()", 4, -1},
        {"atan2(12)", 8, -1},
        {"atan2(0, 1)", -1, 0},
        {"abs(atan(1)-3.141592654/4) < 1E-6", -1, 1.0},
        {"random() != 1.2", -1, 1.0},
        {"abs(log(1024)/log(2) - 10) < 1E-6", -1, 1.0},
        {"floor(pow(2, 8) + 0.5) == 256", -1, 1.0},
        {"abs(sqrt(2)*sqrt(2) - 2) < 1E-6", -1, 1.0},
        {"abs(tan(3.141592654/4)-1) < 1E-6", -1, 1.0},
        {"abs(log(exp(13)) - 13) < 1E-6", -1, 1.0},
        {"abs(len2(3,4) - 5) < 1E-6", -1, 1.0},
        {"sqr(3) == 9", -1, 1.0},

        {"1+z2*4", 4, -1},
        {"1+2*", 4, -1},
        {"1+(2*3", 6, -1},
        {"1+2()", 3, -1},
        {"+1", 0, -1},
    };

    std::map<std::string, double> vars;
    vars["x0"] = 3.14;
    vars["y0"] = 2.718;
    vars["x1"] = 100;
    vars["y1"] = 200;

    int errors = 0;
    int ntests = sizeof(tests)/sizeof(tests[0]);
    for (int i=0; i<ntests; i++) {
        const char *s = tests[i].expr;
        double res = -1;
        try {
            Expr expr = Expr::partialParse(s, vars);
            if (*s) throw Expr::Error("Extra characters");
            if (tests[i].err != -1) throw Expr::Error("Parsing should have failed");
            res = expr.eval();
            if (tests[i].result != res) throw Expr::Error("Unexpected result");
        } catch (Expr::Error& err) {
            if (tests[i].err == s - tests[i].expr) {
                // Ok; parsing error position is correct
            } else {
                errors++;
                printf("TEST FAILED: \"%s\" (err=%i, result=%0.3f) --> res=%0.3f\n%s\n\n",
                       tests[i].expr, tests[i].err, tests[i].result,
                       res, err.what());
            }
        }
    }
    printf("%i errors on %i tests\n", errors, ntests);

    int w=640, h=480;
    vars["k"] = 10*3.141592654 / ((w*w+h*h)/4);
    double& y = vars["y"];
    double& x = vars["x"];
    std::vector<unsigned char> img(w*h);
    Expr e("((128 + sin(((x-320)*(x-320) + (y-240)*(y-240))*k)*127) ^"
           " (255 * ((floor(x/128)+floor(y/96)) & 1))) + random()*32-16", vars);
    printf("Expression compiled code:\n%s\n", e.disassemble().c_str());
    clock_t start = clock();
    for (int rep=0; rep<10; rep++) {
        int i = 0;
        for (y=0; y<h; y++) {
            for (x=0; x<w; x++) {
                int ie = int(e);
                if (ie < 0) ie = 0; if (ie > 255) ie = 255;
                img[i++] = ie;
            }
        }
    }
    clock_t stop = clock();
    printf("Test image generated in %0.3fms (%.0f pixels/sec)\n",
           (stop - start)*100.0/CLOCKS_PER_SEC,
           double(w*h*10)*CLOCKS_PER_SEC/(stop-start+1));
    FILE *f = fopen("test.pgm", "wb");
    if (f) {
        fprintf(f, "P5\n%i %i 255\n", w, h);
        fwrite(&img[0], 1, w*h, f);
        fclose(f);
    } else {
        fprintf(stderr, "Error generating test.pgm\n");
    }

    clock_t start2 = clock();
    double k = vars["k"];
    for (int rep=0; rep<10; rep++) {
        int i = 0;
        for (y=0; y<h; y++) {
            for (x=0; x<w; x++) {
                int ie = int(
                    (int(128 + sin(((x-320)*(x-320) + (y-240)*(y-240))*k)*127) ^
                     int(255 * (int(floor(x/128)+floor(y/96)) & 1))) + myrandom()*32-16);
                if (ie < 0) ie = 0; if (ie > 255) ie = 255;
                img[i++] = ie;
            }
        }
    }
    clock_t stop2 = clock();
    printf("Test image generated natively in %0.3fms (%.0f pixels/sec)\n",
           (stop2 - start2)*100.0/CLOCKS_PER_SEC,
           double(w*h*10)*CLOCKS_PER_SEC/(stop2-start2+1));
    f = fopen("test_native.pgm", "wb");
    if (f) {
        fprintf(f, "P5\n%i %i 255\n", w, h);
        fwrite(&img[0], 1, w*h, f);
        fclose(f);
    } else {
        fprintf(stderr, "Error generating test_native.pgm\n");
    }

    return errors != 0;
}
<|endoftext|>


<commit_before>#include "generate.hpp"
#include "serialization/model2d.hpp"

namespace beat {
	namespace g2 {
		template <class T>
		struct Serialization : Generator {};
		using STypes = ::testing::Types<
			Point,
			Line,
			Ray,
			Segment,
			Circle,
			Capsule,
			AABB,
			Triangle,
			Convex
		>;
		TYPED_TEST_CASE(Serialization, STypes);

		TYPED_TEST(Serialization, General) {
			using Mdl = Model<TypeParam>;
			Mdl shape;
			this->Generator::genShape(shape);
			lubee::CheckSerialization(shape);
		}
	}
}
<commit_msg>geometry2d: シリアライゼーションのテスト名を変更<commit_after>#include "generate.hpp"
#include "serialization/model2d.hpp"

namespace beat {
	namespace g2 {
		template <class T>
		struct Serialization : Generator {};

		template <class T>
		struct SerializationG2 : Serialization<T> {};
		using STypes = ::testing::Types<
			Point,
			Line,
			Ray,
			Segment,
			Circle,
			Capsule,
			AABB,
			Triangle,
			Convex
		>;
		TYPED_TEST_CASE(SerializationG2, STypes);
		TYPED_TEST(SerializationG2, General) {
			using Mdl = Model<TypeParam>;
			Mdl shape;
			this->Generator::genShape(shape);
			lubee::CheckSerialization(shape);
		}
	}
}
<|endoftext|>