<commit_before>//-- includes -----
#define BOOST_LIB_DIAGNOSTIC

#include "ServerNetworkManager.h"
#include "ServerRequestHandler.h"
#include "ControllerManager.h"
#include "ServerLog.h"

#include <boost/asio.hpp>
#include <boost/application.hpp>
#include <boost/program_options.hpp>
#include <fstream>
#include <cstdio>
#include <string>
#include <signal.h>

// provide setup example for windows service
#if defined(BOOST_WINDOWS_API)
#include "setup/windows/setup/service_setup.hpp"
#endif

using namespace boost;

//-- constants -----
const int PSMOVE_SERVER_PORT = 9512;

//-- definitions -----
class PSMoveService
{
public:
    PSMoveService()
        : m_io_service()
        , m_signals(m_io_service)
        , m_controller_manager()
        , m_request_handler(&m_controller_manager)
        , m_network_manager(&m_io_service, PSMOVE_SERVER_PORT, &m_request_handler)
        , m_status()
    {
        // Register to handle the signals that indicate when the server should exit.
        m_signals.add(SIGINT);
        m_signals.add(SIGTERM);
#if defined(SIGQUIT)
        m_signals.add(SIGQUIT);
#endif // defined(SIGQUIT)
        m_signals.async_wait(boost::bind(&PSMoveService::handle_termination_signal, this));
    }

    int operator()(application::context& context)
    {
        BOOST_APPLICATION_FEATURE_SELECT

        // Attempt to start and run the service
        try
        {
            if (startup())
            {
                m_status = context.find<application::status>();

                while (m_status->state() != application::status::stoped)
                {
                    if (m_status->state() != application::status::paused)
                    {
                        update();
                    }

                    boost::this_thread::sleep(boost::posix_time::milliseconds(1));
                }
            }
            else
            {
                SERVER_LOG_FATAL("PSMoveService") << "Failed to startup the PSMove service";
            }
        }
        catch (std::exception& e)
        {
            SERVER_LOG_FATAL("PSMoveService") << e.what();
        }

        // Attempt to shutdown the service
        try
        {
           shutdown();
        }
        catch (std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }

        return 0;
    }

    bool stop(application::context& context)
    {
        if (m_status->state() != application::status::stoped)
        {
            SERVER_LOG_WARNING("PSMoveService") << "Received stop request. Stopping Service.";
            m_status->state(application::status::stoped);
        }

        return true;
    }

    bool pause(application::context& context)
    {
        if (m_status->state() == application::status::running)
        {
            SERVER_LOG_WARNING("PSMoveService") << "Received pause request. Pausing Service.";
            m_status->state(application::status::paused);
        }

        return true;
    }

    bool resume(application::context& context)
    {
        if (m_status->state() == application::status::paused)
        {
            SERVER_LOG_WARNING("PSMoveService") << "Received resume request. Resuming Service.";
            m_status->state(application::status::running);
        }

        return true;
    }

private:
    bool startup()
    {
        bool success= true;

        // Start listening for client connections
        if (success)
        {
            if (!m_network_manager.startup())
            {
                SERVER_LOG_FATAL("PSMoveService") << "Failed to initialize the service network manager";
                success= false;
            }
        }

        // Setup the request handler
        if (success)
        {
            if (!m_request_handler.startup())
            {
                SERVER_LOG_FATAL("PSMoveService") << "Failed to initialize the service request handler";
                success= false;
            }
        }

        // Setup the controller manager
        if (success)
        {
            if (!m_controller_manager.startup())
            {
                SERVER_LOG_FATAL("PSMoveService") << "Failed to initialize the controller manager";
                success= false;
            }
        }

        return success;
    }

    void update()
    {
        // Update the list of active tracked controllers
        // Send controller updates to the client
        m_controller_manager.update();

        // Process incoming/outgoing networking requests
        m_network_manager.update();
    }

    void shutdown()
    {
        // Disconnect any actively connected controllers
        m_controller_manager.shutdown();

        // Kill any pending request state
        m_request_handler.shutdown();

        // Close all active network connections
        m_network_manager.shutdown();
    }

    void handle_termination_signal()
    {
        SERVER_LOG_WARNING("PSMoveService") << "Received termination signal. Stopping Service.";
        m_status->state(application::status::stoped);
    }

private:
    // The io_service used to perform asynchronous operations.
    boost::asio::io_service m_io_service;

    // The signal_set is used to register for process termination notifications.
    boost::asio::signal_set m_signals;

    // Keep track of currently connected PSMove controllers
    ControllerManager m_controller_manager;

    // Generates responses from incoming requests sent to the network manager
    ServerRequestHandler m_request_handler;

    // Manages all TCP and UDP client connections
    ServerNetworkManager m_network_manager;

    // Whether the application should keep running or not
    std::shared_ptr<application::status> m_status;
};

#if defined(BOOST_WINDOWS_API)
bool win32_service_management_action(
    const program_options::variables_map &options_map)
{
    HMODULE hModule = GetModuleHandleW(NULL);
    CHAR path[MAX_PATH];
    GetModuleFileNameA(hModule, path, MAX_PATH);
    std::string exe_full_path(path);

    bool exit_program= false;

    // Install the service
    if (options_map.count("-i"))
    {
        std::string service_options(" -d");

        if (options_map.count("log_level"))
        {
            std::string log_level= options_map["log_level"].as<std::string>();

            service_options+= " --log_level ";
            service_options+= log_level;
        }

        boost::system::error_code ec;
        application::example::install_windows_service(
            application::setup_arg(options_map["name"].as<std::string>()),
            application::setup_arg(options_map["display"].as<std::string>()),
            application::setup_arg(options_map["description"].as<std::string>()),
            application::setup_arg(exe_full_path),
            application::setup_arg(std::string("")), // username
            application::setup_arg(std::string("")), // password
            application::setup_arg(service_options)).install(ec);

        std::cout << ec.message() << std::endl;

        exit_program= true;
    }
    // Uninstall the service
    else if (options_map.count("-u"))
    {
        boost::system::error_code ec;
        application::example::uninstall_windows_service(
            application::setup_arg(options_map["name"].as<std::string>()),
            application::setup_arg(exe_full_path)).uninstall(ec);

        std::cout << ec.message() << std::endl;

        exit_program= true;
    }
    // Check the status of the service
    else if (options_map.count("-c"))
    {
        boost::system::error_code ec;
        bool exist =
            application::example::check_windows_service(
                application::setup_arg(options_map["name"].as<std::string>())).exist(ec);

        if(ec)
        {
            std::cout << ec.message() << std::endl;
        }
        else
        {
            if(exist)
            {
                std::cout
                    << "The service "
                    << options_map["name"].as<std::string>()
                    <<  " is installed!"
                    << std::endl;
            }
            else
            {
                std::cout
                    << "The service "
                    << options_map["name"].as<std::string>()
                    <<  " is NOT installed!"
                    << std::endl;
            }
        }

        exit_program= true;
    }

    return exit_program;
}
#endif // defined(BOOST_WINDOWS_API)

//-- Entry Point ---
int main(int argc, char *argv[])
{
    // used to select between std:: and boost:: namespaces
    BOOST_APPLICATION_FEATURE_SELECT

    // Parse service options
    program_options::variables_map options_map;
    program_options::options_description desc;

    // Extract the executable name
    std::string exe_name = boost::filesystem::path(argv[0]).stem().string();

    // Define the set of valid command line options
    desc.add_options()
        ("help,h", "Shows help.")
        (",d", "Run as background daemon/service")
        ("log_level,l", program_options::value<std::string>(), "The level of logging to use: trace, debug, info, warning, error, fatal")
#if defined(BOOST_WINDOWS_API)
        (",i", "install service")
        (",u", "uninstall service")
        (",c", "check service")
        ("name", program_options::value<std::string>()->default_value(exe_name), "service name")
        ("display", program_options::value<std::string>()->default_value("PSMove Service"), "service display name (optional, installation only)")
        ("description", program_options::value<std::string>()->default_value("Manages PSMove controller and broadcasts state to clients"), "service description (optional, installation only)")
#endif // defined(BOOST_WINDOWS_API)
        ;

    // Parse the command line
    try
    {
        program_options::store(program_options::parse_command_line(argc, argv, desc), options_map);
    }
    catch(boost::program_options::unknown_option &option)
    {
        std::cout << option.what() << std::endl;
        std::cout << "Valid Options: " << std::endl;
        std::cout << desc << std::endl;
        return 0;
    }

    if (options_map.count("-h"))
    {
        std::cout << "Valid Options: " << std::endl;
        std::cout << desc << std::endl;
        return 0;
    }

    #if defined(BOOST_WINDOWS_API)
    // On Windows, make a modification to the service installation if requested
    if (win32_service_management_action(options_map))
    {
        // Exit after completing the service management operation
        return 0;
    }
    #endif // defined(BOOST_WINDOWS_API)

    // initialize logging system
    log_init(&options_map);

    // Start the service app
    SERVER_LOG_INFO("main") << "Starting PSMoveService";
    try
    {
        PSMoveService app;
        application::context app_context;

        // service aspects
        app_context.insert<application::path>(
            make_shared<application::path_default_behaviour>(argc, argv));

        app_context.insert<application::args>(
            make_shared<application::args>(argc, argv));

        // add termination handler
        application::handler<>::parameter_callback termination_callback
            = boost::bind<bool>(&PSMoveService::stop, &app, _1);

        app_context.insert<application::termination_handler>(
            make_shared<application::termination_handler_default_behaviour>(termination_callback));

        // To  "pause/resume" works, is required to add the 2 handlers.
#if defined(BOOST_WINDOWS_API)
        // windows only : add pause handler
        application::handler<>::parameter_callback pause_callback
            = boost::bind<bool>(&PSMoveService::pause, &app, _1);

        app_context.insert<application::pause_handler>(
            make_shared<application::pause_handler_default_behaviour>(pause_callback));

        // windows only : add resume handler
        application::handler<>::parameter_callback resume_callback
            = boost::bind<bool>(&PSMoveService::resume, &app, _1);

        app_context.insert<application::resume_handler>(
            make_shared<application::resume_handler_default_behaviour>(resume_callback));
#endif // defined(BOOST_WINDOWS_API)

        // my common/server instantiation
        if (options_map.count("-d"))
        {
            return application::launch<application::server>(app, app_context);
        }
        else
        {
            return application::launch<application::common>(app, app_context);
        }
    }
    catch (boost::system::system_error& se)
    {
        SERVER_LOG_FATAL("main") << "Failed to start PSMoveService: " << se.what();
        return 1;
    }
    catch (std::exception &e)
    {
        SERVER_LOG_FATAL("main") << "Failed to start PSMoveService: " <<  e.what();
        return 1;
    }
    catch (...)
    {
        SERVER_LOG_FATAL("main") << "Failed to start PSMoveService: Unknown error.";
        return 1;
    }

    SERVER_LOG_INFO("main") << "Exiting PSMoveService";

    return 0;
}
<commit_msg>Adjusting the main server loop sleep time from 1ms -> 10ms * Experiment to see of this prevents pegging CPU on os x when server is run as daemon<commit_after>//-- includes -----
#define BOOST_LIB_DIAGNOSTIC

#include "ServerNetworkManager.h"
#include "ServerRequestHandler.h"
#include "ControllerManager.h"
#include "ServerLog.h"

#include <boost/asio.hpp>
#include <boost/application.hpp>
#include <boost/program_options.hpp>
#include <fstream>
#include <cstdio>
#include <string>
#include <signal.h>

// provide setup example for windows service
#if defined(BOOST_WINDOWS_API)
#include "setup/windows/setup/service_setup.hpp"
#endif

using namespace boost;

//-- constants -----
const int PSMOVE_SERVER_PORT = 9512;

//-- definitions -----
class PSMoveService
{
public:
    PSMoveService()
        : m_io_service()
        , m_signals(m_io_service)
        , m_controller_manager()
        , m_request_handler(&m_controller_manager)
        , m_network_manager(&m_io_service, PSMOVE_SERVER_PORT, &m_request_handler)
        , m_status()
    {
        // Register to handle the signals that indicate when the server should exit.
        m_signals.add(SIGINT);
        m_signals.add(SIGTERM);
#if defined(SIGQUIT)
        m_signals.add(SIGQUIT);
#endif // defined(SIGQUIT)
        m_signals.async_wait(boost::bind(&PSMoveService::handle_termination_signal, this));
    }

    int operator()(application::context& context)
    {
        BOOST_APPLICATION_FEATURE_SELECT

        // Attempt to start and run the service
        try
        {
            if (startup())
            {
                m_status = context.find<application::status>();

                while (m_status->state() != application::status::stoped)
                {
                    if (m_status->state() != application::status::paused)
                    {
                        update();
                    }

                    boost::this_thread::sleep(boost::posix_time::milliseconds(10));
                }
            }
            else
            {
                SERVER_LOG_FATAL("PSMoveService") << "Failed to startup the PSMove service";
            }
        }
        catch (std::exception& e)
        {
            SERVER_LOG_FATAL("PSMoveService") << e.what();
        }

        // Attempt to shutdown the service
        try
        {
           shutdown();
        }
        catch (std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }

        return 0;
    }

    bool stop(application::context& context)
    {
        if (m_status->state() != application::status::stoped)
        {
            SERVER_LOG_WARNING("PSMoveService") << "Received stop request. Stopping Service.";
            m_status->state(application::status::stoped);
        }

        return true;
    }

    bool pause(application::context& context)
    {
        if (m_status->state() == application::status::running)
        {
            SERVER_LOG_WARNING("PSMoveService") << "Received pause request. Pausing Service.";
            m_status->state(application::status::paused);
        }

        return true;
    }

    bool resume(application::context& context)
    {
        if (m_status->state() == application::status::paused)
        {
            SERVER_LOG_WARNING("PSMoveService") << "Received resume request. Resuming Service.";
            m_status->state(application::status::running);
        }

        return true;
    }

private:
    bool startup()
    {
        bool success= true;

        // Start listening for client connections
        if (success)
        {
            if (!m_network_manager.startup())
            {
                SERVER_LOG_FATAL("PSMoveService") << "Failed to initialize the service network manager";
                success= false;
            }
        }

        // Setup the request handler
        if (success)
        {
            if (!m_request_handler.startup())
            {
                SERVER_LOG_FATAL("PSMoveService") << "Failed to initialize the service request handler";
                success= false;
            }
        }

        // Setup the controller manager
        if (success)
        {
            if (!m_controller_manager.startup())
            {
                SERVER_LOG_FATAL("PSMoveService") << "Failed to initialize the controller manager";
                success= false;
            }
        }

        return success;
    }

    void update()
    {
        // Update the list of active tracked controllers
        // Send controller updates to the client
        m_controller_manager.update();

        // Process incoming/outgoing networking requests
        m_network_manager.update();
    }

    void shutdown()
    {
        // Disconnect any actively connected controllers
        m_controller_manager.shutdown();

        // Kill any pending request state
        m_request_handler.shutdown();

        // Close all active network connections
        m_network_manager.shutdown();
    }

    void handle_termination_signal()
    {
        SERVER_LOG_WARNING("PSMoveService") << "Received termination signal. Stopping Service.";
        m_status->state(application::status::stoped);
    }

private:
    // The io_service used to perform asynchronous operations.
    boost::asio::io_service m_io_service;

    // The signal_set is used to register for process termination notifications.
    boost::asio::signal_set m_signals;

    // Keep track of currently connected PSMove controllers
    ControllerManager m_controller_manager;

    // Generates responses from incoming requests sent to the network manager
    ServerRequestHandler m_request_handler;

    // Manages all TCP and UDP client connections
    ServerNetworkManager m_network_manager;

    // Whether the application should keep running or not
    std::shared_ptr<application::status> m_status;
};

#if defined(BOOST_WINDOWS_API)
bool win32_service_management_action(
    const program_options::variables_map &options_map)
{
    HMODULE hModule = GetModuleHandleW(NULL);
    CHAR path[MAX_PATH];
    GetModuleFileNameA(hModule, path, MAX_PATH);
    std::string exe_full_path(path);

    bool exit_program= false;

    // Install the service
    if (options_map.count("-i"))
    {
        std::string service_options(" -d");

        if (options_map.count("log_level"))
        {
            std::string log_level= options_map["log_level"].as<std::string>();

            service_options+= " --log_level ";
            service_options+= log_level;
        }

        boost::system::error_code ec;
        application::example::install_windows_service(
            application::setup_arg(options_map["name"].as<std::string>()),
            application::setup_arg(options_map["display"].as<std::string>()),
            application::setup_arg(options_map["description"].as<std::string>()),
            application::setup_arg(exe_full_path),
            application::setup_arg(std::string("")), // username
            application::setup_arg(std::string("")), // password
            application::setup_arg(service_options)).install(ec);

        std::cout << ec.message() << std::endl;

        exit_program= true;
    }
    // Uninstall the service
    else if (options_map.count("-u"))
    {
        boost::system::error_code ec;
        application::example::uninstall_windows_service(
            application::setup_arg(options_map["name"].as<std::string>()),
            application::setup_arg(exe_full_path)).uninstall(ec);

        std::cout << ec.message() << std::endl;

        exit_program= true;
    }
    // Check the status of the service
    else if (options_map.count("-c"))
    {
        boost::system::error_code ec;
        bool exist =
            application::example::check_windows_service(
                application::setup_arg(options_map["name"].as<std::string>())).exist(ec);

        if(ec)
        {
            std::cout << ec.message() << std::endl;
        }
        else
        {
            if(exist)
            {
                std::cout
                    << "The service "
                    << options_map["name"].as<std::string>()
                    <<  " is installed!"
                    << std::endl;
            }
            else
            {
                std::cout
                    << "The service "
                    << options_map["name"].as<std::string>()
                    <<  " is NOT installed!"
                    << std::endl;
            }
        }

        exit_program= true;
    }

    return exit_program;
}
#endif // defined(BOOST_WINDOWS_API)

//-- Entry Point ---
int main(int argc, char *argv[])
{
    // used to select between std:: and boost:: namespaces
    BOOST_APPLICATION_FEATURE_SELECT

    // Parse service options
    program_options::variables_map options_map;
    program_options::options_description desc;

    // Extract the executable name
    std::string exe_name = boost::filesystem::path(argv[0]).stem().string();

    // Define the set of valid command line options
    desc.add_options()
        ("help,h", "Shows help.")
        (",d", "Run as background daemon/service")
        ("log_level,l", program_options::value<std::string>(), "The level of logging to use: trace, debug, info, warning, error, fatal")
#if defined(BOOST_WINDOWS_API)
        (",i", "install service")
        (",u", "uninstall service")
        (",c", "check service")
        ("name", program_options::value<std::string>()->default_value(exe_name), "service name")
        ("display", program_options::value<std::string>()->default_value("PSMove Service"), "service display name (optional, installation only)")
        ("description", program_options::value<std::string>()->default_value("Manages PSMove controller and broadcasts state to clients"), "service description (optional, installation only)")
#endif // defined(BOOST_WINDOWS_API)
        ;

    // Parse the command line
    try
    {
        program_options::store(program_options::parse_command_line(argc, argv, desc), options_map);
    }
    catch(boost::program_options::unknown_option &option)
    {
        std::cout << option.what() << std::endl;
        std::cout << "Valid Options: " << std::endl;
        std::cout << desc << std::endl;
        return 0;
    }

    if (options_map.count("-h"))
    {
        std::cout << "Valid Options: " << std::endl;
        std::cout << desc << std::endl;
        return 0;
    }

    #if defined(BOOST_WINDOWS_API)
    // On Windows, make a modification to the service installation if requested
    if (win32_service_management_action(options_map))
    {
        // Exit after completing the service management operation
        return 0;
    }
    #endif // defined(BOOST_WINDOWS_API)

    // initialize logging system
    log_init(&options_map);

    // Start the service app
    SERVER_LOG_INFO("main") << "Starting PSMoveService";
    try
    {
        PSMoveService app;
        application::context app_context;

        // service aspects
        app_context.insert<application::path>(
            make_shared<application::path_default_behaviour>(argc, argv));

        app_context.insert<application::args>(
            make_shared<application::args>(argc, argv));

        // add termination handler
        application::handler<>::parameter_callback termination_callback
            = boost::bind<bool>(&PSMoveService::stop, &app, _1);

        app_context.insert<application::termination_handler>(
            make_shared<application::termination_handler_default_behaviour>(termination_callback));

        // To  "pause/resume" works, is required to add the 2 handlers.
#if defined(BOOST_WINDOWS_API)
        // windows only : add pause handler
        application::handler<>::parameter_callback pause_callback
            = boost::bind<bool>(&PSMoveService::pause, &app, _1);

        app_context.insert<application::pause_handler>(
            make_shared<application::pause_handler_default_behaviour>(pause_callback));

        // windows only : add resume handler
        application::handler<>::parameter_callback resume_callback
            = boost::bind<bool>(&PSMoveService::resume, &app, _1);

        app_context.insert<application::resume_handler>(
            make_shared<application::resume_handler_default_behaviour>(resume_callback));
#endif // defined(BOOST_WINDOWS_API)

        // my common/server instantiation
        if (options_map.count("-d"))
        {
            return application::launch<application::server>(app, app_context);
        }
        else
        {
            return application::launch<application::common>(app, app_context);
        }
    }
    catch (boost::system::system_error& se)
    {
        SERVER_LOG_FATAL("main") << "Failed to start PSMoveService: " << se.what();
        return 1;
    }
    catch (std::exception &e)
    {
        SERVER_LOG_FATAL("main") << "Failed to start PSMoveService: " <<  e.what();
        return 1;
    }
    catch (...)
    {
        SERVER_LOG_FATAL("main") << "Failed to start PSMoveService: Unknown error.";
        return 1;
    }

    SERVER_LOG_INFO("main") << "Exiting PSMoveService";

    return 0;
}
<|endoftext|>


<commit_before>#include "TemporaryCS.h"
#include "../common/Types.h"

#if defined(WIN32) || defined(_WIN32_WCE)

#include "windows.h"
#include "winbase.h"

class __critical_section : public NSCriticalSection::CRITICAL_SECTION_NATIVE
{
private:
	::CRITICAL_SECTION m_cs;

public:
	virtual void Enter()
	{
		EnterCriticalSection(&m_cs);
	}
	virtual void Leave()
	{
		LeaveCriticalSection(&m_cs);
	}

public:
	static void InitializeCriticalSection(NSCriticalSection::CRITICAL_SECTION_NATIVE* pNative)
	{
		__critical_section* pCS = (__critical_section*)pNative;
		::InitializeCriticalSection(&pCS->m_cs);
	}
	static void DeleteCriticalSection(NSCriticalSection::CRITICAL_SECTION_NATIVE* pNative)
	{
		__critical_section* pCS = (__critical_section*)pNative;
		::DeleteCriticalSection(&pCS->m_cs);
	}
};

#else

#include <pthread.h>

class __critical_section : public NSCriticalSection::CRITICAL_SECTION_NATIVE
{
private:
	pthread_mutex_t m_cs;

public:
	virtual void Enter()
	{
		pthread_mutex_lock(&m_cs);
	}
	virtual void Leave()
	{
		pthread_mutex_unlock(&m_cs);
	}

public:
	static void InitializeCriticalSection(NSCriticalSection::CRITICAL_SECTION_NATIVE* pNative)
	{
		__critical_section* pCS = (__critical_section*)pNative;

		pthread_mutexattr_t _attr;
		pthread_mutexattr_settype(&_attr, PTHREAD_MUTEX_RECURSIVE_NP);

		pthread_mutex_init(&m_cs, &_attr);

		pthread_mutexattr_destroy(&_attr);
	}
	static void DeleteCriticalSection(NSCriticalSection::CRITICAL_SECTION_NATIVE* pNative)
	{
		__critical_section* pCS = (__critical_section*)pNative;
		pthread_mutex_destroy(&m_cs);
	}
};

#endif

namespace NSCriticalSection
{
	CRITICAL_SECTION::CRITICAL_SECTION()
	{
		m_pCS = new __critical_section();
	}
	CRITICAL_SECTION::~CRITICAL_SECTION()
	{
		RELEASEOBJECT(m_pCS);
	}

	void CRITICAL_SECTION::InitializeCriticalSection()
	{
		__critical_section::InitializeCriticalSection(m_pCS);
	}

	void CRITICAL_SECTION::DeleteCriticalSection()
	{
		__critical_section::DeleteCriticalSection(m_pCS);
	}

	void CRITICAL_SECTION::Enter()
	{
		if (NULL != m_pCS)
			m_pCS->Enter();
	}
	void CRITICAL_SECTION::Leave()
	{
		if (NULL != m_pCS)
			m_pCS->Leave();
	}
}

CTemporaryCS::CTemporaryCS(NSCriticalSection::CRITICAL_SECTION* cs)
{
	cs->Enter();
	m_cs = cs;
}
CTemporaryCS::~CTemporaryCS()
{
	LeaveCS();
}
void CTemporaryCS::LeaveCS()
{
	if (NULL != m_cs)
		m_cs->Leave();
	m_cs = NULL;
}
void CTemporaryCS::EnterCS(NSCriticalSection::CRITICAL_SECTION* cs)
{
	LeaveCS();
	cs->Enter();
	m_cs = cs;
}<commit_msg>git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@55222 954022d7-b5bf-4e40-9824-e11837661b57<commit_after>#include "TemporaryCS.h"
#include "../common/Types.h"

#if defined(WIN32) || defined(_WIN32_WCE)

#include "windows.h"
#include "winbase.h"

class __critical_section : public NSCriticalSection::CRITICAL_SECTION_NATIVE
{
private:
	::CRITICAL_SECTION m_cs;

public:
	virtual void Enter()
	{
		EnterCriticalSection(&m_cs);
	}
	virtual void Leave()
	{
		LeaveCriticalSection(&m_cs);
	}

public:
	static void InitializeCriticalSection(NSCriticalSection::CRITICAL_SECTION_NATIVE* pNative)
	{
		__critical_section* pCS = (__critical_section*)pNative;
		::InitializeCriticalSection(&pCS->m_cs);
	}
	static void DeleteCriticalSection(NSCriticalSection::CRITICAL_SECTION_NATIVE* pNative)
	{
		__critical_section* pCS = (__critical_section*)pNative;
		::DeleteCriticalSection(&pCS->m_cs);
	}
};

#else

#include <pthread.h>

class __critical_section : public NSCriticalSection::CRITICAL_SECTION_NATIVE
{
private:
	pthread_mutex_t m_cs;

public:
	virtual void Enter()
	{
		pthread_mutex_lock(&m_cs);
	}
	virtual void Leave()
	{
		pthread_mutex_unlock(&m_cs);
	}

public:
	static void InitializeCriticalSection(NSCriticalSection::CRITICAL_SECTION_NATIVE* pNative)
	{
		__critical_section* pCS = (__critical_section*)pNative;

		pthread_mutexattr_t _attr;
        pthread_mutexattr_init(&_attr);
		pthread_mutexattr_settype(&_attr, PTHREAD_MUTEX_RECURSIVE_NP);
        pthread_mutex_init(&pCS->m_cs, &_attr);
		pthread_mutexattr_destroy(&_attr);
	}
	static void DeleteCriticalSection(NSCriticalSection::CRITICAL_SECTION_NATIVE* pNative)
	{
		__critical_section* pCS = (__critical_section*)pNative;
        pthread_mutex_destroy(&pCS->m_cs);
	}
};

#endif

namespace NSCriticalSection
{
	CRITICAL_SECTION::CRITICAL_SECTION()
	{
		m_pCS = new __critical_section();
	}
	CRITICAL_SECTION::~CRITICAL_SECTION()
	{
		RELEASEOBJECT(m_pCS);
	}

	void CRITICAL_SECTION::InitializeCriticalSection()
	{
		__critical_section::InitializeCriticalSection(m_pCS);
	}

	void CRITICAL_SECTION::DeleteCriticalSection()
	{
		__critical_section::DeleteCriticalSection(m_pCS);
	}

	void CRITICAL_SECTION::Enter()
	{
		if (NULL != m_pCS)
			m_pCS->Enter();
	}
	void CRITICAL_SECTION::Leave()
	{
		if (NULL != m_pCS)
			m_pCS->Leave();
	}
}

CTemporaryCS::CTemporaryCS(NSCriticalSection::CRITICAL_SECTION* cs)
{
	cs->Enter();
	m_cs = cs;
}
CTemporaryCS::~CTemporaryCS()
{
	LeaveCS();
}
void CTemporaryCS::LeaveCS()
{
	if (NULL != m_cs)
		m_cs->Leave();
	m_cs = NULL;
}
void CTemporaryCS::EnterCS(NSCriticalSection::CRITICAL_SECTION* cs)
{
	LeaveCS();
	cs->Enter();
	m_cs = cs;
}<|endoftext|>


<commit_before>#include "opencv2/core.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgcodecs/imgcodecs_c.h"
using namespace cv;

#include "cvmatio/MatlabIO.hpp"

#include "Chen.hpp"
#include "../constants.hpp"
#include "../autocrop/autocrop.hpp"
#include "../classify/Classifier.hpp"
#include "../util/math.hpp"
#include "../util/file.hpp"
#include "../features/feature.hpp"
#include "../features/FeatMat.hpp"

// DataSets namespace
namespace ds
{

	void Chen::addToFeatMat(FeatMat& featMat)
	{
		getTurkCrops();

#pragma omp parallel for
		for (int i = 0; i < turkCrops.size(); i++)
		{
			auto fname = turkCrops[i].fname;
			auto crops = turkCrops[i].crops;

			printf("Loading %s (%d/%d)\n", fname.c_str(), i + 1,
				turkCrops.size());

			Mat saliency, gradient;
			try {
				auto maps = getMaps(fname);
				saliency = maps.first;
				gradient = maps.second;
			} catch (std::exception e) {
				printf("Error in loading %s", fname.c_str());
				continue;
			}

			Rect bad_crop, good_crop;

			// Image is bad crop
			bad_crop = Rect(0, 0, saliency.cols, saliency.rows);
			featMat.addFeatVec(saliency, gradient, bad_crop, BAD_CROP);

			// For each Mechanical Turk crop for given image
			for (int c = 0; c < crops.rows; c++)
			{
				// Mechanical turk data is good crop
				try {
					good_crop = getFixedCrop(saliency, crops.row(c));
				} catch (std::exception e) {
					std::cout << "Invalid crop: " << crops.row(c) << std::endl;
					continue;
				}
				featMat.addFeatVec(saliency, gradient, good_crop, GOOD_CROP);

				// Randomly generated crop is "bad"
				// Only picks crop with less than 0.4 overlap
				bad_crop = randomCrop(saliency, good_crop, 0.3);
				featMat.addFeatVec(saliency, gradient, bad_crop, BAD_CROP);
			}
		}
	}

	void Chen::quantEval()
	{
		getTurkCrops();

		// Initialise classifier
		Classifier classifier;
		classifier.loadModel("Trained_model.yml");

		const int MAX_CROP_CANDS = 10;
		std::vector<float> indices;
		std::vector<std::vector<float>> overlaps(10);

		const int N = turkCrops.size();

#pragma omp parallel for
		for (int i = 0; i < N; i++)
		{
			auto fname = turkCrops[i].fname;
			auto _crops = turkCrops[i].crops;

			Mat saliency, gradient;
			try {
				auto maps = getMaps(fname);
				saliency = maps.first;
				gradient = maps.second;
			} catch (std::exception e) {
				printf("Error in loading %s\n", fname.c_str());
				continue;
			}

			Candidates crop_cands = getCropCandidates(classifier, saliency, gradient);

			// Get list of valid crops
			std::vector<Rect> crops;

			Rect crop;
			int best_crop;
			float overlap, max_overlap = 0.f;

			for (int C = 1; C <= MAX_CROP_CANDS; C++)
			{
				for (int a = 0; a < C; a++)
					for (int c = 0; c < _crops.rows; c++)
					{
						// Mechanical turk data is good crop
						try {
							crop = getFixedCrop(saliency, _crops.row(c));
							crops.push_back(crop);
						} catch (std::exception e) {
							continue;
						}

						overlap = cropOverlap(crop_cands[a]->crop, crop);

						max_overlap = max(max_overlap, overlap);
						if (max_overlap == overlap)
							best_crop = a;
					}

				overlaps[C-1].push_back(max_overlap);
			}

			indices.push_back(best_crop);
			printf("[%3d/%3d] Best crop index: %2d, Max overlap: %.2f, Filename: %s\n",
				i, N, best_crop, max_overlap, fname.c_str());
		}

		printf("\n%d images were evaluated.\n", N);

		for (int C = 1; C <= 5; C++)
		{
			printf("\nFor %d top candidates only:\n", C);
			printf("- Mean max overlap is: %.3f\n", mean(overlaps[C-1]));
			printf("- Median max overlap is: %.3f\n", median(overlaps[C-1]));
			printf("- std. err. of max overlaps is: %.3f\n\n", stder(overlaps[C-1]));
		}
		printf("- Mean best crop index is: %.1f\n", mean(indices));
		printf("- Median best crop index is: %.1f\n", median(indices));
	}

	void Chen::getTurkCrops()
	{
		// Reset list
		std::vector<TurkCrop>().swap(turkCrops);

		// Read mat file with Mechanical Turk sourced crops
		MatlabIO mio;
		mio.open("../datasets/Chen/500_image_dataset.mat", "r");
		auto MAT = mio.read();
		mio.close();

		auto img_gt = MAT[0].data<std::vector<std::vector<MatlabIOContainer>>>();

		for (int i = 0; i < img_gt.size(); i++)
			turkCrops.push_back((TurkCrop) {
				img_gt[i][0].data<std::string>(),
				img_gt[i][1].data<Mat>()
			});
	}

	std::pair<Mat, Mat> Chen::getMaps(std::string fname)
	{
		path ipath = path("../datasets/Chen/image/" + fname);

		// Load cached image maps. Abort if invalid image [maps]
		Mat saliency = imread(setSuffix(ipath, "saliency").string(), CV_LOAD_IMAGE_UNCHANGED);
		Mat gradient = imread(setSuffix(ipath, "gradient").string(), CV_LOAD_IMAGE_UNCHANGED);

		if (!saliency.data || !gradient.data)
			throw std::runtime_error("Chen: Error in loading image maps");

		return std::pair<Mat, Mat>(saliency, gradient);
	}

	Rect Chen::getFixedCrop(const Mat& img, const Mat& crop)
	{
		int y    = crop.at<double>(0),
		    x    = crop.at<double>(1),
		    ymax = crop.at<double>(2),
		    xmax = crop.at<double>(3);

		// Correct bad data
		y = y < 0 ? 0 : y;
		x = x < 0 ? 0 : x;
		ymax = ymax < 0 ? 0 : ymax;
		xmax = xmax < 0 ? 0 : xmax;
		ymax = ymax >= img.rows ? img.rows - 1 : ymax;
		xmax = xmax >= img.cols ? img.cols - 1 : xmax;
		int h = ymax - y,
		    w = xmax - x;

		//std::cout << "Current crop: " << crop << std::endl;
		if (h < 2 || w < 2)
		{
			//std::cout << "Bad crop: " << crop << std::endl;
			throw std::runtime_error("Invalid crop");
		}

		return Rect(x, y, w, h);
	}
}

<commit_msg>Fix warning due to formatting lu as d<commit_after>#include "opencv2/core.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgcodecs/imgcodecs_c.h"
using namespace cv;

#include "cvmatio/MatlabIO.hpp"

#include "Chen.hpp"
#include "../constants.hpp"
#include "../autocrop/autocrop.hpp"
#include "../classify/Classifier.hpp"
#include "../util/math.hpp"
#include "../util/file.hpp"
#include "../features/feature.hpp"
#include "../features/FeatMat.hpp"

// DataSets namespace
namespace ds
{

	void Chen::addToFeatMat(FeatMat& featMat)
	{
		getTurkCrops();

#pragma omp parallel for
		for (int i = 0; i < turkCrops.size(); i++)
		{
			auto fname = turkCrops[i].fname;
			auto crops = turkCrops[i].crops;

			printf("Loading %s (%d/%lu)\n", fname.c_str(), i + 1,
				turkCrops.size());

			Mat saliency, gradient;
			try {
				auto maps = getMaps(fname);
				saliency = maps.first;
				gradient = maps.second;
			} catch (std::exception e) {
				printf("Error in loading %s", fname.c_str());
				continue;
			}

			Rect bad_crop, good_crop;

			// Image is bad crop
			bad_crop = Rect(0, 0, saliency.cols, saliency.rows);
			featMat.addFeatVec(saliency, gradient, bad_crop, BAD_CROP);

			// For each Mechanical Turk crop for given image
			for (int c = 0; c < crops.rows; c++)
			{
				// Mechanical turk data is good crop
				try {
					good_crop = getFixedCrop(saliency, crops.row(c));
				} catch (std::exception e) {
					std::cout << "Invalid crop: " << crops.row(c) << std::endl;
					continue;
				}
				featMat.addFeatVec(saliency, gradient, good_crop, GOOD_CROP);

				// Randomly generated crop is "bad"
				// Only picks crop with less than 0.4 overlap
				bad_crop = randomCrop(saliency, good_crop, 0.3);
				featMat.addFeatVec(saliency, gradient, bad_crop, BAD_CROP);
			}
		}
	}

	void Chen::quantEval()
	{
		getTurkCrops();

		// Initialise classifier
		Classifier classifier;
		classifier.loadModel("Trained_model.yml");

		const int MAX_CROP_CANDS = 10;
		std::vector<float> indices;
		std::vector<std::vector<float>> overlaps(10);

		const int N = turkCrops.size();

#pragma omp parallel for
		for (int i = 0; i < N; i++)
		{
			auto fname = turkCrops[i].fname;
			auto _crops = turkCrops[i].crops;

			Mat saliency, gradient;
			try {
				auto maps = getMaps(fname);
				saliency = maps.first;
				gradient = maps.second;
			} catch (std::exception e) {
				printf("Error in loading %s\n", fname.c_str());
				continue;
			}

			Candidates crop_cands = getCropCandidates(classifier, saliency, gradient);

			// Get list of valid crops
			std::vector<Rect> crops;

			Rect crop;
			int best_crop;
			float overlap, max_overlap = 0.f;

			for (int C = 1; C <= MAX_CROP_CANDS; C++)
			{
				for (int a = 0; a < C; a++)
					for (int c = 0; c < _crops.rows; c++)
					{
						// Mechanical turk data is good crop
						try {
							crop = getFixedCrop(saliency, _crops.row(c));
							crops.push_back(crop);
						} catch (std::exception e) {
							continue;
						}

						overlap = cropOverlap(crop_cands[a]->crop, crop);

						max_overlap = max(max_overlap, overlap);
						if (max_overlap == overlap)
							best_crop = a;
					}

				overlaps[C-1].push_back(max_overlap);
			}

			indices.push_back(best_crop);
			printf("[%3d/%3d] Best crop index: %2d, Max overlap: %.2f, Filename: %s\n",
				i, N, best_crop, max_overlap, fname.c_str());
		}

		printf("\n%d images were evaluated.\n", N);

		for (int C = 1; C <= 5; C++)
		{
			printf("\nFor %d top candidates only:\n", C);
			printf("- Mean max overlap is: %.3f\n", mean(overlaps[C-1]));
			printf("- Median max overlap is: %.3f\n", median(overlaps[C-1]));
			printf("- std. err. of max overlaps is: %.3f\n\n", stder(overlaps[C-1]));
		}
		printf("- Mean best crop index is: %.1f\n", mean(indices));
		printf("- Median best crop index is: %.1f\n", median(indices));
	}

	void Chen::getTurkCrops()
	{
		// Reset list
		std::vector<TurkCrop>().swap(turkCrops);

		// Read mat file with Mechanical Turk sourced crops
		MatlabIO mio;
		mio.open("../datasets/Chen/500_image_dataset.mat", "r");
		auto MAT = mio.read();
		mio.close();

		auto img_gt = MAT[0].data<std::vector<std::vector<MatlabIOContainer>>>();

		for (int i = 0; i < img_gt.size(); i++)
			turkCrops.push_back((TurkCrop) {
				img_gt[i][0].data<std::string>(),
				img_gt[i][1].data<Mat>()
			});
	}

	std::pair<Mat, Mat> Chen::getMaps(std::string fname)
	{
		path ipath = path("../datasets/Chen/image/" + fname);

		// Load cached image maps. Abort if invalid image [maps]
		Mat saliency = imread(setSuffix(ipath, "saliency").string(), CV_LOAD_IMAGE_UNCHANGED);
		Mat gradient = imread(setSuffix(ipath, "gradient").string(), CV_LOAD_IMAGE_UNCHANGED);

		if (!saliency.data || !gradient.data)
			throw std::runtime_error("Chen: Error in loading image maps");

		return std::pair<Mat, Mat>(saliency, gradient);
	}

	Rect Chen::getFixedCrop(const Mat& img, const Mat& crop)
	{
		int y    = crop.at<double>(0),
		    x    = crop.at<double>(1),
		    ymax = crop.at<double>(2),
		    xmax = crop.at<double>(3);

		// Correct bad data
		y = y < 0 ? 0 : y;
		x = x < 0 ? 0 : x;
		ymax = ymax < 0 ? 0 : ymax;
		xmax = xmax < 0 ? 0 : xmax;
		ymax = ymax >= img.rows ? img.rows - 1 : ymax;
		xmax = xmax >= img.cols ? img.cols - 1 : xmax;
		int h = ymax - y,
		    w = xmax - x;

		//std::cout << "Current crop: " << crop << std::endl;
		if (h < 2 || w < 2)
		{
			//std::cout << "Bad crop: " << crop << std::endl;
			throw std::runtime_error("Invalid crop");
		}

		return Rect(x, y, w, h);
	}
}

<|endoftext|>


<commit_before>/*===========================================================================*\
*                                                                           *
*                               OpenMesh                                    *
*      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
*                           www.openmesh.org                                *
*                                                                           *
*---------------------------------------------------------------------------*
*  This file is part of OpenMesh.                                           *
*                                                                           *
*  OpenMesh is free software: you can redistribute it and/or modify         *
*  it under the terms of the GNU Lesser General Public License as           *
*  published by the Free Software Foundation, either version 3 of           *
*  the License, or (at your option) any later version with the              *
*  following exceptions:                                                    *
*                                                                           *
*  If other files instantiate templates or use macros                       *
*  or inline functions from this file, or you compile this file and         *
*  link it with other files to produce an executable, this file does        *
*  not by itself cause the resulting executable to be covered by the        *
*  GNU Lesser General Public License. This exception does not however       *
*  invalidate any other reasons why the executable file might be            *
*  covered by the GNU Lesser General Public License.                        *
*                                                                           *
*  OpenMesh is distributed in the hope that it will be useful,              *
*  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
*  GNU Lesser General Public License for more details.                      *
*                                                                           *
*  You should have received a copy of the GNU LesserGeneral Public          *
*  License along with OpenMesh.  If not,                                    *
*  see <http://www.gnu.org/licenses/>.                                      *
*                                                                           *
\*==========================================================================*/

/*==========================================================================*\
*                                                                           *
*   $Revision: 410 $                                                        *
*   $Date: 2010-06-17 12:45:58 +0200 (Do, 17. Jun 2010) $                   *
*                                                                           *
\*==========================================================================*/

/** \file LongestEdgeT.hh

*/

//=============================================================================
//
//  CLASS LongestEdgeT
//
//=============================================================================

#ifndef LINEAR_H
#define LINEAR_H

#include <OpenMesh/Tools/Subdivider/Uniform/SubdividerT.hh>
#include <OpenMesh/Core/Utils/vector_cast.hh>
#include <OpenMesh/Core/Utils/Property.hh>
// -------------------- STL
#include <vector>
#include <queue>
#if defined(OM_CC_MIPS)
#  include <math.h>
#else
#  include <cmath>
#endif

//== NAMESPACE ================================================================

namespace OpenMesh   { // BEGIN_NS_OPENMESH
namespace Subdivider { // BEGIN_NS_DECIMATER
namespace Uniform    { // BEGIN_NS_UNIFORM

//== CLASS DEFINITION =========================================================

template <typename MeshType, typename RealType = float>
class CompareLengthFunction {
  public:

    typedef std::pair<typename MeshType::EdgeHandle, RealType> queueElement;

    bool operator()(const queueElement& t1, const queueElement& t2) // Returns true if t1 is smaller than t2
    {
      return (t1.second < t2.second);
    }
};

/** %Uniform LongestEdgeT subdivision algorithm
 *
 * Very simple algorithm splitting all edges which are longer than given via
 * set_max_edge_length(). The split is always performed on the longest
 * edge in the mesh.
 */
template <typename MeshType, typename RealType = float>
class LongestEdgeT : public SubdividerT<MeshType, RealType>
{
public:

  typedef RealType                                real_t;
  typedef MeshType                                mesh_t;
  typedef SubdividerT< mesh_t, real_t >           parent_t;

  typedef std::vector< std::vector<real_t> >      weights_t;
  typedef std::vector<real_t>                     weight_t;

  typedef std::pair< typename mesh_t::EdgeHandle, real_t > queueElement;

public:

  LongestEdgeT() : parent_t()
  {  }

  LongestEdgeT( mesh_t& _m) : parent_t(_m)
  {  }

  ~LongestEdgeT() {}

public:

  const char *name() const { return "Longest Edge Split"; }

  void set_max_edge_length(double _value) {
    max_edge_length_squared_ = _value * _value;
  }

protected:

  bool prepare( mesh_t& _m )
  {
    return true;
  }

  bool cleanup( mesh_t& _m )
  {
    return true;
  }

  bool subdivide( MeshType& _m, size_t _n , const bool _update_points = true)
  {

    // Sorted queue containing all edges sorted by their decreasing length
    std::priority_queue< queueElement, std::vector< queueElement > , CompareLengthFunction< typename mesh_t, real_t > > queue;

    // Build the initial queue
    // First element should be longest edge
    typename mesh_t::EdgeIter edgesEnd = _m.edges_end();
    for ( typename mesh_t::EdgeIter eit  = _m.edges_begin(); eit != edgesEnd; ++eit) {
      const typename MeshType::Point to   = _m.point(_m.to_vertex_handle(_m.halfedge_handle(eit,0)));
      const typename MeshType::Point from = _m.point(_m.from_vertex_handle(_m.halfedge_handle(eit,0)));

      real_t length = (to - from).sqrnorm();

      // Only push the edges that need to be split
      if ( length > max_edge_length_squared_ )
        queue.push( queueElement(eit.handle(),length) );
    }

    bool stop = false;
    while ( !stop && ! queue.empty() ) {
      queueElement a = queue.top();
      queue.pop();

      if ( a.second < max_edge_length_squared_ ) {
        stop = true;
        break;
      } else {
        const typename MeshType::Point to   = _m.point(_m.to_vertex_handle(_m.halfedge_handle(a.first,0)));
        const typename MeshType::Point from = _m.point(_m.from_vertex_handle(_m.halfedge_handle(a.first,0)));
        const typename MeshType::Point midpoint = 0.5 * ( to + from );

        const typename MeshType::VertexHandle newVertex = _m.add_vertex(midpoint);
        _m.split(a.first,newVertex);

        for ( typename MeshType::VertexOHalfedgeIter voh_it(_m,newVertex); voh_it; ++voh_it) {
          typename MeshType::EdgeHandle eh = _m.edge_handle(voh_it.handle());
          const typename MeshType::Point to   = _m.point(_m.to_vertex_handle(voh_it));
          const typename MeshType::Point from = _m.point(_m.from_vertex_handle(voh_it));
          real_t length = (to - from).sqrnorm();

          // Only push the edges that need to be split
          if ( length > max_edge_length_squared_ )
            queue.push( queueElement(eh,length) );

        }
      }
    }

#if defined(_DEBUG) || defined(DEBUG)
      // Now we have an consistent mesh!
      assert( OpenMesh::Utils::MeshCheckerT<mesh_t>(_m).check() );
#endif

    return true;
  }

private: // data
  real_t max_edge_length_squared_;

};

} // END_NS_UNIFORM
} // END_NS_SUBDIVIDER
} // END_NS_OPENMESH
#endif

<commit_msg>Next try<commit_after>/*===========================================================================*\
*                                                                           *
*                               OpenMesh                                    *
*      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
*                           www.openmesh.org                                *
*                                                                           *
*---------------------------------------------------------------------------*
*  This file is part of OpenMesh.                                           *
*                                                                           *
*  OpenMesh is free software: you can redistribute it and/or modify         *
*  it under the terms of the GNU Lesser General Public License as           *
*  published by the Free Software Foundation, either version 3 of           *
*  the License, or (at your option) any later version with the              *
*  following exceptions:                                                    *
*                                                                           *
*  If other files instantiate templates or use macros                       *
*  or inline functions from this file, or you compile this file and         *
*  link it with other files to produce an executable, this file does        *
*  not by itself cause the resulting executable to be covered by the        *
*  GNU Lesser General Public License. This exception does not however       *
*  invalidate any other reasons why the executable file might be            *
*  covered by the GNU Lesser General Public License.                        *
*                                                                           *
*  OpenMesh is distributed in the hope that it will be useful,              *
*  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
*  GNU Lesser General Public License for more details.                      *
*                                                                           *
*  You should have received a copy of the GNU LesserGeneral Public          *
*  License along with OpenMesh.  If not,                                    *
*  see <http://www.gnu.org/licenses/>.                                      *
*                                                                           *
\*==========================================================================*/

/*==========================================================================*\
*                                                                           *
*   $Revision: 410 $                                                        *
*   $Date: 2010-06-17 12:45:58 +0200 (Do, 17. Jun 2010) $                   *
*                                                                           *
\*==========================================================================*/

/** \file LongestEdgeT.hh

*/

//=============================================================================
//
//  CLASS LongestEdgeT
//
//=============================================================================

#ifndef LINEAR_H
#define LINEAR_H

#include <OpenMesh/Tools/Subdivider/Uniform/SubdividerT.hh>
#include <OpenMesh/Core/Utils/vector_cast.hh>
#include <OpenMesh/Core/Utils/Property.hh>
// -------------------- STL
#include <vector>
#include <queue>
#if defined(OM_CC_MIPS)
#  include <math.h>
#else
#  include <cmath>
#endif

//== NAMESPACE ================================================================

namespace OpenMesh   { // BEGIN_NS_OPENMESH
namespace Subdivider { // BEGIN_NS_DECIMATER
namespace Uniform    { // BEGIN_NS_UNIFORM

//== CLASS DEFINITION =========================================================

template <typename MeshType, typename RealType = float>
class CompareLengthFunction {
  public:

    typedef std::pair<typename MeshType::EdgeHandle, RealType> queueElement;

    bool operator()(const queueElement& t1, const queueElement& t2) // Returns true if t1 is smaller than t2
    {
      return (t1.second < t2.second);
    }
};

/** %Uniform LongestEdgeT subdivision algorithm
 *
 * Very simple algorithm splitting all edges which are longer than given via
 * set_max_edge_length(). The split is always performed on the longest
 * edge in the mesh.
 */
template <typename MeshType, typename RealType = float>
class LongestEdgeT : public SubdividerT<MeshType, RealType>
{
public:

  typedef RealType                                real_t;
  typedef MeshType                                mesh_t;
  typedef SubdividerT< mesh_t, real_t >           parent_t;

  typedef std::vector< std::vector<real_t> >      weights_t;
  typedef std::vector<real_t>                     weight_t;

  typedef std::pair< typename mesh_t::EdgeHandle, real_t > queueElement;

public:

  LongestEdgeT() : parent_t()
  {  }

  LongestEdgeT( mesh_t& _m) : parent_t(_m)
  {  }

  ~LongestEdgeT() {}

public:

  const char *name() const { return "Longest Edge Split"; }

  void set_max_edge_length(double _value) {
    max_edge_length_squared_ = _value * _value;
  }

protected:

  bool prepare( mesh_t& _m )
  {
    return true;
  }

  bool cleanup( mesh_t& _m )
  {
    return true;
  }

  bool subdivide( MeshType& _m, size_t _n , const bool _update_points = true)
  {

    // Sorted queue containing all edges sorted by their decreasing length
    std::priority_queue< queueElement, std::vector< queueElement > , CompareLengthFunction< mesh_t, real_t > > queue;

    // Build the initial queue
    // First element should be longest edge
    typename mesh_t::EdgeIter edgesEnd = _m.edges_end();
    for ( typename mesh_t::EdgeIter eit  = _m.edges_begin(); eit != edgesEnd; ++eit) {
      const typename MeshType::Point to   = _m.point(_m.to_vertex_handle(_m.halfedge_handle(eit,0)));
      const typename MeshType::Point from = _m.point(_m.from_vertex_handle(_m.halfedge_handle(eit,0)));

      real_t length = (to - from).sqrnorm();

      // Only push the edges that need to be split
      if ( length > max_edge_length_squared_ )
        queue.push( queueElement(eit.handle(),length) );
    }

    bool stop = false;
    while ( !stop && ! queue.empty() ) {
      queueElement a = queue.top();
      queue.pop();

      if ( a.second < max_edge_length_squared_ ) {
        stop = true;
        break;
      } else {
        const typename MeshType::Point to   = _m.point(_m.to_vertex_handle(_m.halfedge_handle(a.first,0)));
        const typename MeshType::Point from = _m.point(_m.from_vertex_handle(_m.halfedge_handle(a.first,0)));
        const typename MeshType::Point midpoint = 0.5 * ( to + from );

        const typename MeshType::VertexHandle newVertex = _m.add_vertex(midpoint);
        _m.split(a.first,newVertex);

        for ( typename MeshType::VertexOHalfedgeIter voh_it(_m,newVertex); voh_it; ++voh_it) {
          typename MeshType::EdgeHandle eh = _m.edge_handle(voh_it.handle());
          const typename MeshType::Point to   = _m.point(_m.to_vertex_handle(voh_it));
          const typename MeshType::Point from = _m.point(_m.from_vertex_handle(voh_it));
          real_t length = (to - from).sqrnorm();

          // Only push the edges that need to be split
          if ( length > max_edge_length_squared_ )
            queue.push( queueElement(eh,length) );

        }
      }
    }

#if defined(_DEBUG) || defined(DEBUG)
      // Now we have an consistent mesh!
      assert( OpenMesh::Utils::MeshCheckerT<mesh_t>(_m).check() );
#endif

    return true;
  }

private: // data
  real_t max_edge_length_squared_;

};

} // END_NS_UNIFORM
} // END_NS_SUBDIVIDER
} // END_NS_OPENMESH
#endif

<|endoftext|>


<commit_before>#include "Mocks.hpp"

using namespace blackhole;

TEST(file_t, Class) {
    sink::file_t<> sink("test.log");
    UNUSED(sink);
}

TEST(file_t, WritesToTheFile) {
    sink::file_t<NiceMock<mock::files::backend_t>> sink("test.log");
    EXPECT_CALL(sink.backend(), write(std::string("formatted message"))).
            Times(1);
    sink.consume("formatted message");
}

TEST(file_t, OpensFileIfItClosedWhenWriting) {
    sink::file_t<NiceMock<mock::files::backend_t>> sink("test.log");
    EXPECT_CALL(sink.backend(), opened()).
            Times(1).
            WillOnce(Return(false));
    EXPECT_CALL(sink.backend(), open()).
            Times(1).
            WillOnce(Return(true));
    EXPECT_CALL(sink.backend(), write(_)).
            Times(1);
    sink.consume("message");
}

TEST(file_t, ThrowsExceptionIfFileCannotBeOpened) {
    sink::file_t<NiceMock<mock::files::backend_t>> sink("test.log");
    EXPECT_CALL(sink.backend(), opened())
            .Times(1)
            .WillOnce(Return(false));
    EXPECT_CALL(sink.backend(), open())
            .Times(1)
            .WillOnce(Return(false));
    EXPECT_CALL(sink.backend(), write(_))
            .Times(0);
    EXPECT_THROW(sink.consume("message"), blackhole::error_t);
}

TEST(file_t, AutoFlushIfSpecified) {
    sink::file::config_t<> config("test.log", true);
    sink::file_t<NiceMock<mock::files::backend_t>> sink(config);
    EXPECT_CALL(sink.backend(), flush())
            .Times(1);

    sink.consume("message");
}

TEST(file_t, AutoFlushIsDisabledIfSpecified) {
    sink::file::config_t<> config("test.log", false);
    sink::file_t<NiceMock<mock::files::backend_t>> sink(config);
    EXPECT_CALL(sink.backend(), flush())
            .Times(0);

    sink.consume("message");
}

TEST(file_t, AutoFlushIsEnabledByDefault) {
    sink::file_t<NiceMock<mock::files::backend_t>> sink("test.log");
    EXPECT_CALL(sink.backend(), flush())
            .Times(1);
    sink.consume("message");
}
<commit_msg>Task for log rotation has been added.<commit_after>#include "Mocks.hpp"

using namespace blackhole;

TEST(file_t, Class) {
    sink::file_t<> sink("test.log");
    UNUSED(sink);
}

TEST(file_t, WritesToTheFile) {
    sink::file_t<NiceMock<mock::files::backend_t>> sink("test.log");
    EXPECT_CALL(sink.backend(), write(std::string("formatted message"))).
            Times(1);
    sink.consume("formatted message");
}

TEST(file_t, OpensFileIfItClosedWhenWriting) {
    sink::file_t<NiceMock<mock::files::backend_t>> sink("test.log");
    EXPECT_CALL(sink.backend(), opened()).
            Times(1).
            WillOnce(Return(false));
    EXPECT_CALL(sink.backend(), open()).
            Times(1).
            WillOnce(Return(true));
    EXPECT_CALL(sink.backend(), write(_)).
            Times(1);
    sink.consume("message");
}

TEST(file_t, ThrowsExceptionIfFileCannotBeOpened) {
    sink::file_t<NiceMock<mock::files::backend_t>> sink("test.log");
    EXPECT_CALL(sink.backend(), opened())
            .Times(1)
            .WillOnce(Return(false));
    EXPECT_CALL(sink.backend(), open())
            .Times(1)
            .WillOnce(Return(false));
    EXPECT_CALL(sink.backend(), write(_))
            .Times(0);
    EXPECT_THROW(sink.consume("message"), blackhole::error_t);
}

TEST(file_t, AutoFlushIfSpecified) {
    sink::file::config_t<> config("test.log", true);
    sink::file_t<NiceMock<mock::files::backend_t>> sink(config);
    EXPECT_CALL(sink.backend(), flush())
            .Times(1);

    sink.consume("message");
}

TEST(file_t, AutoFlushIsDisabledIfSpecified) {
    sink::file::config_t<> config("test.log", false);
    sink::file_t<NiceMock<mock::files::backend_t>> sink(config);
    EXPECT_CALL(sink.backend(), flush())
            .Times(0);

    sink.consume("message");
}

TEST(file_t, AutoFlushIsEnabledByDefault) {
    sink::file_t<NiceMock<mock::files::backend_t>> sink("test.log");
    EXPECT_CALL(sink.backend(), flush())
            .Times(1);
    sink.consume("message");
}

//!@todo:
//! Given: size=1024, count=2, pattern='test.log.%N'
//! Condition: `backend.size()`=1025
//! Action: `rotator.rotate()`.
<|endoftext|>


<commit_before>
#include <iostream>
#include <ctime>
#include <cstdlib>
#include "Sorting.hpp"

void displayOptions(void);

int main(int argc, char* argv[]) {
	// Display the welcoming information
	std::cout << "***********************************" << std::endl;
	std::cout << "*           Exercise 10           *" << std::endl;
	std::cout << "*        Sorting Algorithms       *" << std::endl;
	std::cout << "*          1552719 侯剑锋         *" << std::endl;
	displayOptions();

	// Prompt the uset to input the number of the random numbers to generate
	std::cout << "请输入您要产生的随机数的数量：" << std::endl;
	int number = 0;
	std::cin >> number;

	// Generate an array of random numbers
	int* integers = new int[number];
	srand((unsigned int)time(NULL));
	for (int i = 0; i < number; i++) {
		integers[i] = rand() % number;
	}

	// Get the option of the user in loops and deal with every option
	char option = '\0';
	std::cout << "请选择排序算法：" << std::endl;
	while (std::cin >> option) {
		// Bubble sort
		if (option == '1') {
			// Copy the initial array
			int* copyArray = new int[number];
			for (int i = 0; i < number; i++) {
				copyArray[i] = integers[i];
			}

			// Sort the array
			std::clock_t beginTime = std::clock();
			int swapTimes = Sorting::bubble_sort(copyArray, 0, number);
			std::clock_t endTime = std::clock();

			// Release the allocated memory
			delete[] copyArray;

			// Display the result
			std::cout << "Bubble Sort 冒泡排序：" << std::endl;
			std::cout << '\t' << "Time 时间：" << endTime - beginTime << "ms" << std::endl;
			std::cout << '\t' << "Swap Times 交换次数：" << swapTimes << std::endl;
		}

		// Quick sort
		else if (option == '2') {
			// Copy the initial array
			int* copyArray = new int[number];
			for (int i = 0; i < number; i++) {
				copyArray[i] = integers[i];
			}

			// Sort the array
			int swapTimes = 0;
			std::clock_t beginTime = std::clock();
			Sorting::quick_sort(copyArray, 0, number, swapTimes);
			std::clock_t endTime = std::clock();

			// Release the allocated memory
			delete[] copyArray;

			// Display the result
			std::cout << "Quick Sort 快速排序：" << std::endl;
			std::cout << '\t' << "Time 时间：" << endTime - beginTime << "ms" << std::endl;
			std::cout << '\t' << "Swap Times 交换次数：" << swapTimes << std::endl;
		}

		// Sslection sort
		else if (option == '3') {
			// Copy the initial array
			int* copyArray = new int[number];
			for (int i = 0; i < number; i++) {
				copyArray[i] = integers[i];
			}

			// Sort the array
			std::clock_t beginTime = std::clock();
			int swapTimes = Sorting::selection_sort(copyArray, 0, number);
			std::clock_t endTime = std::clock();

			// Release the allocated memory
			delete[] copyArray;

			// Display the result
			std::cout << "Selection Sort 选择排序：" << std::endl;
			std::cout << '\t' << "Time 时间：" << endTime - beginTime << "ms" << std::endl;
			std::cout << '\t' << "Swap Times 交换次数：" << swapTimes << std::endl;
		}

		// Insertion sort
		else if (option == '4') {
			// Copy the initial array
			int* copyArray = new int[number];
			for (int i = 0; i < number; i++) {
				copyArray[i] = integers[i];
			}

			// Sort the array
			std::clock_t beginTime = std::clock();
			int swapTimes = Sorting::insertion_sort(copyArray, 0, number);
			std::clock_t endTime = std::clock();

			// Release the allocated memory
			delete[] copyArray;

			// Display the result
			std::cout << "Insertion Sort 插入排序：" << std::endl;
			std::cout << '\t' << "Time 时间：" << endTime - beginTime << "ms" << std::endl;
			std::cout << '\t' << "Swap Times 交换次数：" << swapTimes << std::endl;
		}

		// Merge sort
		else if (option == '5') {
			// Copy the initial array
			int* copyArray = new int[number];
			for (int i = 0; i < number; i++) {
				copyArray[i] = integers[i];
			}

			// Sort the array
			int compareTimes = 0;
			std::clock_t beginTime = std::clock();
			Sorting::merge_sort(copyArray, 0, number, compareTimes);
			std::clock_t endTime = std::clock();

			// Release the allocated memory
			delete[] copyArray;

			// Display the result
			std::cout << "Merge Sort 归并排序：" << std::endl;
			std::cout << '\t' << "Time 时间：" << endTime - beginTime << "ms" << std::endl;
			std::cout << '\t' << "Compare Times 比较次数：" << compareTimes << std::endl;
		}

		// Radix sort
		else if (option == '6') {

		}

		// Heap sort
		else if (option == '7') {

		}

		// Shell sort
		else if (option == '8') {

		}

		// Exit
		else if (option == '9') {
			break;
		}

		// Exceptions
		else {
			std::cout << "Illegal input!!!\a" << std::endl;
		}

		// Prompt the user select a sorting algorithm for the next loop
		displayOptions();
		std::cout << "请选择排序算法或退出：" << std::endl;
	}

	// Prepare to exit the program
	delete[] integers;
	std::cout << "Exiting... 即将退出程序..." << std::endl;

	return 0;
}

void displayOptions(void) {
	std::cout << std::endl;
	std::cout << "===================================" << std::endl;
	std::cout << "*     1--Bubble Sort 冒泡排序     *" << std::endl;
	std::cout << "*     2--Quick Sort 快速排序      *" << std::endl;
	std::cout << "*     3--Selection Sort 选择排序  *" << std::endl;
	std::cout << "*     4--Insertion Sort 插入排序  *" << std::endl;
	std::cout << "*     5--Merge Sort 归并排序      *" << std::endl;
	std::cout << "*     6--Radix Sort 基数排序      *" << std::endl;
	std::cout << "*     7--Heap Sort 堆排序         *" << std::endl;
	std::cout << "*     8-- Sort 希尔排序           *" << std::endl;
	std::cout << "*     9--Exit 退出程序            *" << std::endl;
	std::cout << "===================================" << std::endl;
}
<commit_msg>Update Exercise10.cpp<commit_after>#include <iostream>
#include <ctime>
#include <cstdlib>
#include "Sorting.hpp"

void displayOptions(void);

int main(int argc, char* argv[]) {
	// Display the welcoming information
	std::cout << "***********************************" << std::endl;
	std::cout << "*           Exercise 10           *" << std::endl;
	std::cout << "*        Sorting Algorithms       *" << std::endl;
	std::cout << "*          1552719 侯剑锋         *" << std::endl;
	displayOptions();

	// Prompt the uset to input the number of the random numbers to generate
	std::cout << "请输入您要产生的随机数的数量：" << std::endl;
	int number = 0;
	std::cin >> number;

	// Generate an array of random numbers
	int* integers = new int[number];
	srand((unsigned int)time(NULL));
	for (int i = 0; i < number; i++) {
		integers[i] = rand() % number;
	}

	// Get the option of the user in loops and deal with every option
	char option = '\0';
	std::cout << "请选择排序算法：" << std::endl;
	while (std::cin >> option) {
		// Bubble sort
		if (option == '1') {
			// Copy the initial array
			int* copyArray = new int[number];
			for (int i = 0; i < number; i++) {
				copyArray[i] = integers[i];
			}

			// Sort the array
			std::clock_t beginTime = std::clock();
			int swapTimes = Sorting::bubble_sort(copyArray, 0, number);
			std::clock_t endTime = std::clock();

			// Release the allocated memory
			delete[] copyArray;

			// Display the result
			std::cout << "Bubble Sort 冒泡排序：" << std::endl;
			std::cout << '\t' << "Time 时间：" << endTime - beginTime << "ms" << std::endl;
			std::cout << '\t' << "Swap Times 交换次数：" << swapTimes << std::endl;
		}

		// Quick sort
		else if (option == '2') {
			// Copy the initial array
			int* copyArray = new int[number];
			for (int i = 0; i < number; i++) {
				copyArray[i] = integers[i];
			}

			// Sort the array
			int swapTimes = 0;
			std::clock_t beginTime = std::clock();
			Sorting::quick_sort(copyArray, 0, number, swapTimes);
			std::clock_t endTime = std::clock();

			// Release the allocated memory
			delete[] copyArray;

			// Display the result
			std::cout << "Quick Sort 快速排序：" << std::endl;
			std::cout << '\t' << "Time 时间：" << endTime - beginTime << "ms" << std::endl;
			std::cout << '\t' << "Swap Times 交换次数：" << swapTimes << std::endl;
		}

		// Sslection sort
		else if (option == '3') {
			// Copy the initial array
			int* copyArray = new int[number];
			for (int i = 0; i < number; i++) {
				copyArray[i] = integers[i];
			}

			// Sort the array
			std::clock_t beginTime = std::clock();
			int swapTimes = Sorting::selection_sort(copyArray, 0, number);
			std::clock_t endTime = std::clock();

			// Release the allocated memory
			delete[] copyArray;

			// Display the result
			std::cout << "Selection Sort 选择排序：" << std::endl;
			std::cout << '\t' << "Time 时间：" << endTime - beginTime << "ms" << std::endl;
			std::cout << '\t' << "Swap Times 交换次数：" << swapTimes << std::endl;
		}

		// Insertion sort
		else if (option == '4') {
			// Copy the initial array
			int* copyArray = new int[number];
			for (int i = 0; i < number; i++) {
				copyArray[i] = integers[i];
			}

			// Sort the array
			std::clock_t beginTime = std::clock();
			int swapTimes = Sorting::insertion_sort(copyArray, 0, number);
			std::clock_t endTime = std::clock();

			// Release the allocated memory
			delete[] copyArray;

			// Display the result
			std::cout << "Insertion Sort 插入排序：" << std::endl;
			std::cout << '\t' << "Time 时间：" << endTime - beginTime << "ms" << std::endl;
			std::cout << '\t' << "Swap Times 交换次数：" << swapTimes << std::endl;
		}

		// Merge sort
		else if (option == '5') {
			// Copy the initial array
			int* copyArray = new int[number];
			for (int i = 0; i < number; i++) {
				copyArray[i] = integers[i];
			}

			// Sort the array
			int compareTimes = 0;
			std::clock_t beginTime = std::clock();
			Sorting::merge_sort(copyArray, 0, number, compareTimes);
			std::clock_t endTime = std::clock();

			// Release the allocated memory
			delete[] copyArray;

			// Display the result
			std::cout << "Merge Sort 归并排序：" << std::endl;
			std::cout << '\t' << "Time 时间：" << endTime - beginTime << "ms" << std::endl;
			std::cout << '\t' << "Compare Times 比较次数：" << compareTimes << std::endl;
		}

		// Radix sort
		else if (option == '6') {
			// Copy the initial array
			int* copyArray = new int[number];
			for (int i = 0; i < number; i++) {
				copyArray[i] = integers[i];
			}

			// Sort the array
			std::clock_t beginTime = std::clock();
			Sorting::radix_sort(copyArray, 0, number);
			std::clock_t endTime = std::clock();

			// Release the allocated memory
			delete[] copyArray;

			// Display the result
			std::cout << "Radix Sort 基数排序：" << std::endl;
			std::cout << '\t' << "Time 时间：" << endTime - beginTime << "ms" << std::endl;
			std::cout << '\t' << "Compare Times 比较次数：" << 0 << std::endl;
		}

		// Heap sort
		else if (option == '7') {
			// Copy the initial array
			int* copyArray = new int[number];
			for (int i = 0; i < number; i++) {
				copyArray[i] = integers[i];
			}

			// Sort the array
			int swapTimes = 0, compareTimes = 0;
			std::clock_t beginTime = std::clock();
			Sorting::heap_sort(copyArray, 0, number, swapTimes, compareTimes);
			std::clock_t endTime = std::clock();

			// Release the allocated memory
			delete[] copyArray;

			// Display the result
			std::cout << "Heap Sort 堆排序：" << std::endl;
			std::cout << '\t' << "Time 时间：" << endTime - beginTime << "ms" << std::endl;
			std::cout << '\t' << "Change Times 交换次数：" << swapTimes << std::endl;
		}

		// Shell sort
		else if (option == '8') {
			// Copy the initial array
			int* copyArray = new int[number];
			for (int i = 0; i < number; i++) {
				copyArray[i] = integers[i];
			}

			int swapTimes = 0;

			// Sort the array
			std::clock_t beginTime = std::clock();
			swapTimes = Sorting::shell_sort(copyArray, 0, number);
			std::clock_t endTime = std::clock();

			// Release the allocated memory
			delete[] copyArray;

			// Display the result
			std::cout << "Shell Sort 希尔排序：" << std::endl;
			std::cout << '\t' << "Time 时间：" << endTime - beginTime << "ms" << std::endl;
			std::cout << '\t' << "Change Times 交换次数：" << swapTimes << std::endl;
		}

		// Exit
		else if (option == '9') {
			break;
		}

		// Exceptions
		else {
			std::cout << "Illegal input!!!\a" << std::endl;
		}

		// Prompt the user select a sorting algorithm for the next loop
		displayOptions();
		std::cout << "请选择排序算法或退出：" << std::endl;
	}

	// Prepare to exit the program
	delete[] integers;
	std::cout << "Exiting... 即将退出程序..." << std::endl;

	return 0;
}

void displayOptions(void) {
	std::cout << std::endl;
	std::cout << "===================================" << std::endl;
	std::cout << "*     1--Bubble Sort 冒泡排序     *" << std::endl;
	std::cout << "*     2--Quick Sort 快速排序      *" << std::endl;
	std::cout << "*     3--Selection Sort 选择排序  *" << std::endl;
	std::cout << "*     4--Insertion Sort 插入排序  *" << std::endl;
	std::cout << "*     5--Merge Sort 归并排序      *" << std::endl;
	std::cout << "*     6--Radix Sort 基数排序      *" << std::endl;
	std::cout << "*     7--Heap Sort 堆排序         *" << std::endl;
	std::cout << "*     8--Shell Sort 希尔排序      *" << std::endl;
	std::cout << "*     9--Exit 退出程序            *" << std::endl;
	std::cout << "===================================" << std::endl;
}
<|endoftext|>


<commit_before>// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -pedantic %s
// C++ [expr.const]p1:
//   In several places, C++ requires expressions that evaluate to an integral
//   or enumeration constant: as array bounds, as case expressions, as
//   bit-field lengths, as enumerator initializers, as static member
//   initializers, and as integral or enumeration non-type template arguments.
//   An integral constant-expression can involve only literals, enumerators,
//   const variables or static data members of integral or enumeration types
//   initialized with constant expressions, and sizeof expressions. Floating
//   literals can appear only if they are cast to integral or enumeration types.

enum Enum { eval = 1 };
const int cval = 2;
const Enum ceval = eval;
struct Struct {
  static const int sval = 3;
  static const Enum seval = eval;
};

template <int itval, Enum etval> struct C {
  enum E {
    v1 = 1,
    v2 = eval,
    v3 = cval,
    v4 = ceval,
    v5 = Struct::sval,
    v6 = Struct::seval,
    v7 = itval,
    v8 = etval,
    v9 = (int)1.5,
    v10 = sizeof(Struct),
    v11 = true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
  };
  unsigned
    b1 : 1,
    b2 : eval,
    b3 : cval,
    b4 : ceval,
    b5 : Struct::sval,
    b6 : Struct::seval,
    b7 : itval,
    b8 : etval,
    b9 : (int)1.5,
    b10 : sizeof(Struct),
    b11 : true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
    ;
  static const int
    i1 = 1,
    i2 = eval,
    i3 = cval,
    i4 = ceval,
    i5 = Struct::sval,
    i6 = Struct::seval,
    i7 = itval,
    i8 = etval,
    i9 = (int)1.5,
    i10 = sizeof(Struct),
    i11 = true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
    ;
  void f(int cond) {
    switch(cond) {
    case    0 + 1:
    case  100 + eval:
    case  200 + cval:
    case  300 + ceval:
    case  400 + Struct::sval:
    case  500 + Struct::seval:
    case  600 + itval:
    case  700 + etval:
    case  800 + (int)1.5:
    case  900 + sizeof(Struct):
    case 1000 + (true? 1 + cval * Struct::sval ^
                 itval / (int)1.5 - sizeof(Struct) : 0):
      ;
    }
  }
  typedef C<itval, etval> T0;
};

template struct C<1, eval>;
template struct C<cval, ceval>;
template struct C<Struct::sval, Struct::seval>;

enum {
  a = sizeof(int) == 8,
  b = a? 8 : 4
};

void diags(int n) {
  switch (n) {
    case (1/0, 1): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
    case (int)(1/0, 2.0): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
    case __imag(1/0): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
    case (int)__imag((double)(1/0)): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
      ;
  }
}

namespace IntOrEnum {
  const int k = 0;
  const int &p = k;
  template<int n> struct S {};
  S<p> s; // expected-error {{not an integral constant expression}}
}

extern const int recurse1;
// recurse2 cannot be used in a constant expression because it is not
// initialized by a constant expression. The same expression appearing later in
// the TU would be a constant expression, but here it is not.
const int recurse2 = recurse1;
const int recurse1 = 1;
int array1[recurse1]; // ok
int array2[recurse2]; // expected-warning {{variable length array}} expected-warning {{integer constant expression}}

namespace FloatConvert {
  typedef int a[(int)42.3];
  typedef int a[(int)42.997];
  typedef int b[(int)4e10]; // expected-warning {{variable length}} expected-warning {{size of static array must be an integer constant expression}}
}

// PR12626
namespace test3 {
  struct X; // expected-note {{forward declaration of 'test3::X'}}
  struct Y { bool b; X x; }; // expected-error {{field has incomplete type 'test3::X'}}
  int f() { return Y().b; }
}
<commit_msg>Fix test so it works the same way on 32-bit and 64-bit.<commit_after>// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -pedantic %s
// C++ [expr.const]p1:
//   In several places, C++ requires expressions that evaluate to an integral
//   or enumeration constant: as array bounds, as case expressions, as
//   bit-field lengths, as enumerator initializers, as static member
//   initializers, and as integral or enumeration non-type template arguments.
//   An integral constant-expression can involve only literals, enumerators,
//   const variables or static data members of integral or enumeration types
//   initialized with constant expressions, and sizeof expressions. Floating
//   literals can appear only if they are cast to integral or enumeration types.

enum Enum { eval = 1 };
const int cval = 2;
const Enum ceval = eval;
struct Struct {
  static const int sval = 3;
  static const Enum seval = eval;
};

template <int itval, Enum etval> struct C {
  enum E {
    v1 = 1,
    v2 = eval,
    v3 = cval,
    v4 = ceval,
    v5 = Struct::sval,
    v6 = Struct::seval,
    v7 = itval,
    v8 = etval,
    v9 = (int)1.5,
    v10 = sizeof(Struct),
    v11 = true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
  };
  unsigned
    b1 : 1,
    b2 : eval,
    b3 : cval,
    b4 : ceval,
    b5 : Struct::sval,
    b6 : Struct::seval,
    b7 : itval,
    b8 : etval,
    b9 : (int)1.5,
    b10 : sizeof(Struct),
    b11 : true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
    ;
  static const int
    i1 = 1,
    i2 = eval,
    i3 = cval,
    i4 = ceval,
    i5 = Struct::sval,
    i6 = Struct::seval,
    i7 = itval,
    i8 = etval,
    i9 = (int)1.5,
    i10 = sizeof(Struct),
    i11 = true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
    ;
  void f(int cond) {
    switch(cond) {
    case    0 + 1:
    case  100 + eval:
    case  200 + cval:
    case  300 + ceval:
    case  400 + Struct::sval:
    case  500 + Struct::seval:
    case  600 + itval:
    case  700 + etval:
    case  800 + (int)1.5:
    case  900 + sizeof(Struct):
    case 1000 + (true? 1 + cval * Struct::sval ^
                 itval / (int)1.5 - sizeof(Struct) : 0):
      ;
    }
  }
  typedef C<itval, etval> T0;
};

template struct C<1, eval>;
template struct C<cval, ceval>;
template struct C<Struct::sval, Struct::seval>;

enum {
  a = sizeof(int) == 8,
  b = a? 8 : 4
};

void diags(int n) {
  switch (n) {
    case (1/0, 1): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
    case (int)(1/0, 2.0): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
    case __imag(1/0): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
    case (int)__imag((double)(1/0)): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
      ;
  }
}

namespace IntOrEnum {
  const int k = 0;
  const int &p = k;
  template<int n> struct S {};
  S<p> s; // expected-error {{not an integral constant expression}}
}

extern const int recurse1;
// recurse2 cannot be used in a constant expression because it is not
// initialized by a constant expression. The same expression appearing later in
// the TU would be a constant expression, but here it is not.
const int recurse2 = recurse1;
const int recurse1 = 1;
int array1[recurse1]; // ok
int array2[recurse2]; // expected-warning {{variable length array}} expected-warning {{integer constant expression}}

namespace FloatConvert {
  typedef int a[(int)42.3];
  typedef int a[(int)42.997];
  typedef int b[(long long)4e20]; // expected-warning {{variable length}} expected-error {{variable length}} expected-warning {{'long long' is an extension}}
}

// PR12626
namespace test3 {
  struct X; // expected-note {{forward declaration of 'test3::X'}}
  struct Y { bool b; X x; }; // expected-error {{field has incomplete type 'test3::X'}}
  int f() { return Y().b; }
}
<|endoftext|>


<commit_before>#pragma once

#include <Eigen/Dense>
#include <Eigen/StdVector>

template <int ROWS>
using VecNd = Eigen::Matrix<double, ROWS, 1>;

template <int ROWS, int COLS>
using MatNd = Eigen::Matrix<double, ROWS, COLS>;

template <int ROWS>
using SquareMatNd = Eigen::Matrix<double, ROWS, ROWS>;

namespace jcc {
using Vec1 = VecNd<1>;
using Vec2 = Eigen::Vector2d;
using Vec3 = Eigen::Vector3d;
using Vec4 = Eigen::Vector4d;
}  // namespace jcc
<commit_msg>Helper for eigen type<commit_after>#pragma once

#include <Eigen/Dense>
#include <Eigen/StdVector>

template <int ROWS>
using VecNd = Eigen::Matrix<double, ROWS, 1>;

template <int ROWS, int COLS>
using MatNd = Eigen::Matrix<double, ROWS, COLS>;

template <int ROWS>
using SquareMatNd = Eigen::Matrix<double, ROWS, ROWS>;

template <typename Eig>
using StdVector = std::vector<Eig, Eigen::aligned_allocator<Eig>>;

namespace jcc {
using Vec1 = VecNd<1>;
using Vec2 = Eigen::Vector2d;
using Vec3 = Eigen::Vector3d;
using Vec4 = Eigen::Vector4d;

}  // namespace jcc
<|endoftext|>


<commit_before>// RUN: %clang_cc1 -std=c++11 -verify %s

template<typename ...T> struct X {};

template<typename T, typename U> struct P {};

namespace Nested {
  template<typename ...T> int f1(X<T, T...>... a); // expected-note +{{conflicting types for parameter 'T'}}
  template<typename ...T> int f2(P<X<T...>, T> ...a); // expected-note +{{conflicting types for parameter 'T'}}

  int a1 = f1(X<int, int, double>(), X<double, int, double>());
  int a2 = f1(X<int, int>());
  int a3 = f1(X<int>(), X<double>()); // expected-error {{no matching}}
  int a4 = f1(X<int, int>(), X<int>()); // expected-error {{no matching}}
  int a5 = f1(X<int>(), X<int, int>()); // expected-error {{no matching}}
  int a6 = f1(X<int, int, int>(), X<int, int, int>(), X<int, int, int, int>()); // expected-error {{no matching}}

  int b1 = f2(P<X<int, double>, int>(), P<X<int, double>, double>());
  int b2 = f2(P<X<int, double>, int>(), P<X<int, double>, double>(), P<X<int, double>, char>()); // expected-error {{no matching}}
}

namespace PR14841 {
  template<typename T, typename U> struct A {};
  template<typename ...Ts> void f(A<Ts...>); // expected-note {{substitution failure [with Ts = <char, short, int>]: too many template arg}}

  void g(A<char, short> a) {
    f(a);
    f<char>(a);
    f<char, short>(a);
    f<char, short, int>(a); // expected-error {{no matching function}}
  }
}

namespace RetainExprPacks {
  int f(int a, int b, int c);
  template<typename ...Ts> struct X {};
  template<typename ...Ts> int g(X<Ts...>, decltype(f(Ts()...)));
  int n = g<int, int>(X<int, int, int>(), 0);
}
<commit_msg>PR14615: add (passing) tests for this already-fixed bug<commit_after>// RUN: %clang_cc1 -std=c++11 -verify %s

template<typename ...T> struct X {};

template<typename T, typename U> struct P {};

namespace Nested {
  template<typename ...T> int f1(X<T, T...>... a); // expected-note +{{conflicting types for parameter 'T'}}
  template<typename ...T> int f2(P<X<T...>, T> ...a); // expected-note +{{conflicting types for parameter 'T'}}

  int a1 = f1(X<int, int, double>(), X<double, int, double>());
  int a2 = f1(X<int, int>());
  int a3 = f1(X<int>(), X<double>()); // expected-error {{no matching}}
  int a4 = f1(X<int, int>(), X<int>()); // expected-error {{no matching}}
  int a5 = f1(X<int>(), X<int, int>()); // expected-error {{no matching}}
  int a6 = f1(X<int, int, int>(), X<int, int, int>(), X<int, int, int, int>()); // expected-error {{no matching}}

  int b1 = f2(P<X<int, double>, int>(), P<X<int, double>, double>());
  int b2 = f2(P<X<int, double>, int>(), P<X<int, double>, double>(), P<X<int, double>, char>()); // expected-error {{no matching}}
}

namespace PR14841 {
  template<typename T, typename U> struct A {};
  template<typename ...Ts> void f(A<Ts...>); // expected-note {{substitution failure [with Ts = <char, short, int>]: too many template arg}}

  void g(A<char, short> a) {
    f(a);
    f<char>(a);
    f<char, short>(a);
    f<char, short, int>(a); // expected-error {{no matching function}}
  }
}

namespace RetainExprPacks {
  int f(int a, int b, int c);
  template<typename ...Ts> struct X {};
  template<typename ...Ts> int g(X<Ts...>, decltype(f(Ts()...)));
  int n = g<int, int>(X<int, int, int>(), 0);
}

namespace PR14615 {
  namespace comment0 {
    template <class A, class...> struct X {};
    template <class... B> struct X<int, B...> {
      typedef int type;
      struct valid {};
    };
    template <typename A, typename... B, typename T = X<A, B...>,
              typename = typename T::valid>
    typename T::type check(int);
    int i = check<int, char>(1);
  }

  namespace comment2 {
    template <class...> struct X;
    template <typename... B, typename X<B...>::type I = 0>
    char check(B...); // expected-note {{undefined template 'PR14615::comment2::X<char, int>'}}
    void f() { check<char>(1, 2); } // expected-error {{no matching function}}
  }

  namespace comment3 {
    template <class...> struct X;
    template <typename... B, typename X<B...>::type I = (typename X<B...>::type)0>
    char check(B...); // expected-note {{undefined template 'PR14615::comment3::X<char, int>'}}
    void f() { check<char>(1, 2); } // expected-error {{no matching function}}
  }
}
<|endoftext|>