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

using namespace graphene::chain;
using namespace boost::multiprecision;

share_type asset_lock_data_object::get_profit(share_type tolocking_balance,uint32_t lock_period,const database &_db)const
{
	return (asset(tolocking_balance, asset_id)*_get_interest(lock_period, _db) - asset(tolocking_balance, asset_id)).amount;
}

Interest asset_lock_data_object::_get_interest(uint32_t lock_period,const database &_db)const{

   asset_object target_asset_obj=asset_id(_db);
   int32_t lock_days=lock_period/FCC_INTEREST_DAY;
   share_type max_to_deposit_balance_year = target_asset_obj.dynamic_data(_db).current_supply - (lock_coin_day / coin_day(FCC_INTEREST_YEAR)).value.to_uint64();
   asset  base_asset(FCC_INTEREST_BASE_SUPPLY, asset_id);

   static Interest top_of_interest = Interest();

   if (top_of_interest == Interest()) // yet not calculated
   {
	   asset result = base_asset;
	   for (uint32_t i = 0; i<FCC_INTEREST_DAYS_YEAR; i++)
	   {
		   result = result*nominal_interest_perday;
	   }
	   top_of_interest = Interest(base_asset, result);
   }

   auto result = base_asset;
   for (uint32_t i = 0; i<lock_days; i++)
   {
	   result = result*nominal_interest_perday;
   }

   int32_t pecent_of_year = (lock_days - FCC_INTEREST_DAYS_YEAR)*GRAPHENE_100_PERCENT / FCC_INTEREST_DAYS_YEAR;

   int64_t reward_rate = GRAPHENE_100_PERCENT + pecent_of_year * reward_coefficient / GRAPHENE_100_PERCENT;

   uint128_t pre_profile = uint128_t((result - base_asset).amount.value)*uint128_t(reward_rate) / GRAPHENE_100_PERCENT;

   auto actual_profile = pre_profile * interest_pool.value / (asset(max_to_deposit_balance_year, asset_id) * top_of_interest).amount.value;

   asset res_asset = asset(actual_profile.convert_to<uint64_t>(), asset_id) + base_asset;

   return Interest(base_asset,res_asset);
}

share_type asset_bitasset_data_object::max_force_settlement_volume(share_type current_supply) const
{
   if( options.maximum_force_settlement_volume == 0 )
      return 0;
   if( options.maximum_force_settlement_volume == GRAPHENE_100_PERCENT )
      return current_supply + force_settled_volume;

   fc::uint128 volume = current_supply.value + force_settled_volume.value;
   volume *= options.maximum_force_settlement_volume;
   volume /= GRAPHENE_100_PERCENT;
   return volume.to_uint64();
}

void graphene::chain::asset_bitasset_data_object::update_median_feeds(time_point_sec current_time)
{
   current_feed_publication_time = current_time;
   vector<std::reference_wrapper<const price_feed>> current_feeds;
   for( const pair<account_id_type, pair<time_point_sec,price_feed>>& f : feeds )
   {
      if( (current_time - f.second.first).to_seconds() < options.feed_lifetime_sec &&
          f.second.first != time_point_sec() )
      {
         current_feeds.emplace_back(f.second.second);
         current_feed_publication_time = std::min(current_feed_publication_time, f.second.first);
      }
   }

   // If there are no valid feeds, or the number available is less than the minimum to calculate a median...
   if( current_feeds.size() < options.minimum_feeds )
   {
      //... don't calculate a median, and set a null feed
      current_feed_publication_time = current_time;
      current_feed = price_feed();
      return;
   }
   if( current_feeds.size() == 1 )
   {
      current_feed = std::move(current_feeds.front());
      return;
   }

   // *** Begin Median Calculations ***
   price_feed median_feed;
   const auto median_itr = current_feeds.begin() + current_feeds.size() / 2;
#define CALCULATE_MEDIAN_VALUE(r, data, field_name) \
   std::nth_element( current_feeds.begin(), median_itr, current_feeds.end(), \
                     [](const price_feed& a, const price_feed& b) { \
      return a.field_name < b.field_name; \
   }); \
   median_feed.field_name = median_itr->get().field_name;

   BOOST_PP_SEQ_FOR_EACH( CALCULATE_MEDIAN_VALUE, ~, GRAPHENE_PRICE_FEED_FIELDS )
#undef CALCULATE_MEDIAN_VALUE
   // *** End Median Calculations ***

   current_feed = median_feed;
}

asset asset_object::amount_from_string(string amount_string) const
{ try {
   bool negative_found = false;
   bool decimal_found = false;
   for( const char c : amount_string )
   {
      if( isdigit( c ) )
         continue;

      if( c == '-' && !negative_found )
      {
         negative_found = true;
         continue;
      }

      if( c == '.' && !decimal_found )
      {
         decimal_found = true;
         continue;
      }

      FC_THROW( (amount_string) );
   }

   share_type satoshis = 0;

   share_type scaled_precision = asset::scaled_precision( precision );

   const auto decimal_pos = amount_string.find( '.' );
   const string lhs = amount_string.substr( negative_found, decimal_pos );
   if( !lhs.empty() )
      satoshis += fc::safe<int64_t>(std::stoll(lhs)) *= scaled_precision;

   if( decimal_found )
   {
      const size_t max_rhs_size = std::to_string( scaled_precision.value ).substr( 1 ).size();

      string rhs = amount_string.substr( decimal_pos + 1 );
      FC_ASSERT( rhs.size() <= max_rhs_size );

      while( rhs.size() < max_rhs_size )
         rhs += '0';

      if( !rhs.empty() )
         satoshis += std::stoll( rhs );
   }

   FC_ASSERT( satoshis <= GRAPHENE_MAX_SHARE_SUPPLY );

   if( negative_found )
      satoshis *= -1;

   return amount(satoshis);
   } FC_CAPTURE_AND_RETHROW( (amount_string) ) }

string asset_object::amount_to_string(share_type amount) const
{
   share_type scaled_precision = 1;
   for( uint8_t i = 0; i < precision; ++i )
      scaled_precision *= 10;
   assert(scaled_precision > 0);

   string result = fc::to_string(amount.value / scaled_precision.value);
   auto decimals = amount.value % scaled_precision.value;
   if( decimals )
      result += "." + fc::to_string(scaled_precision.value + decimals).erase(0,1);
   return result;
}
<commit_msg>fix asset overflow issue<commit_after>/*
 * Copyright (c) 2015 Cryptonomex, Inc., and contributors.
 *
 * The MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include <graphene/chain/asset_object.hpp>
#include <graphene/chain/database.hpp>

using namespace graphene::chain;
using namespace boost::multiprecision;

share_type asset_lock_data_object::get_profit(share_type tolocking_balance,uint32_t lock_period,const database &_db)const
{
	return (asset(tolocking_balance, asset_id)*_get_interest(lock_period, _db) - asset(tolocking_balance, asset_id)).amount;
}

Interest asset_lock_data_object::_get_interest(uint32_t lock_period,const database &_db)const{

   asset_object target_asset_obj=asset_id(_db);
   int32_t lock_days=lock_period/FCC_INTEREST_DAY;
   share_type max_to_deposit_balance_year = target_asset_obj.dynamic_data(_db).current_supply - (lock_coin_day / coin_day(FCC_INTEREST_YEAR)).value.to_uint64();
   asset  base_asset(FCC_INTEREST_BASE_SUPPLY, asset_id);

   static Interest top_of_interest = Interest();

   if (top_of_interest == Interest()) // yet not calculated
   {
	   asset result = base_asset;
	   for (uint32_t i = 0; i<FCC_INTEREST_DAYS_YEAR; i++)
	   {
		   result = result*nominal_interest_perday;
	   }
	   top_of_interest = Interest(base_asset, result);
   }

   auto result = base_asset;
   for (uint32_t i = 0; i<lock_days; i++)
   {
	   result = result*nominal_interest_perday;
   }

   int32_t pecent_of_year = (lock_days - FCC_INTEREST_DAYS_YEAR)*GRAPHENE_100_PERCENT / FCC_INTEREST_DAYS_YEAR;

   int64_t reward_rate = GRAPHENE_100_PERCENT + pecent_of_year * reward_coefficient / GRAPHENE_100_PERCENT;

   uint128_t pre_profile = uint128_t((result - base_asset).amount.value)*uint128_t(reward_rate) / GRAPHENE_100_PERCENT;

   auto actual_profile = pre_profile * interest_pool.value / (asset(max_to_deposit_balance_year / 10, asset_id) * top_of_interest).amount.value /10;

   asset res_asset = asset(actual_profile.convert_to<uint64_t>(), asset_id) + base_asset;

   return Interest(base_asset,res_asset);
}

share_type asset_bitasset_data_object::max_force_settlement_volume(share_type current_supply) const
{
   if( options.maximum_force_settlement_volume == 0 )
      return 0;
   if( options.maximum_force_settlement_volume == GRAPHENE_100_PERCENT )
      return current_supply + force_settled_volume;

   fc::uint128 volume = current_supply.value + force_settled_volume.value;
   volume *= options.maximum_force_settlement_volume;
   volume /= GRAPHENE_100_PERCENT;
   return volume.to_uint64();
}

void graphene::chain::asset_bitasset_data_object::update_median_feeds(time_point_sec current_time)
{
   current_feed_publication_time = current_time;
   vector<std::reference_wrapper<const price_feed>> current_feeds;
   for( const pair<account_id_type, pair<time_point_sec,price_feed>>& f : feeds )
   {
      if( (current_time - f.second.first).to_seconds() < options.feed_lifetime_sec &&
          f.second.first != time_point_sec() )
      {
         current_feeds.emplace_back(f.second.second);
         current_feed_publication_time = std::min(current_feed_publication_time, f.second.first);
      }
   }

   // If there are no valid feeds, or the number available is less than the minimum to calculate a median...
   if( current_feeds.size() < options.minimum_feeds )
   {
      //... don't calculate a median, and set a null feed
      current_feed_publication_time = current_time;
      current_feed = price_feed();
      return;
   }
   if( current_feeds.size() == 1 )
   {
      current_feed = std::move(current_feeds.front());
      return;
   }

   // *** Begin Median Calculations ***
   price_feed median_feed;
   const auto median_itr = current_feeds.begin() + current_feeds.size() / 2;
#define CALCULATE_MEDIAN_VALUE(r, data, field_name) \
   std::nth_element( current_feeds.begin(), median_itr, current_feeds.end(), \
                     [](const price_feed& a, const price_feed& b) { \
      return a.field_name < b.field_name; \
   }); \
   median_feed.field_name = median_itr->get().field_name;

   BOOST_PP_SEQ_FOR_EACH( CALCULATE_MEDIAN_VALUE, ~, GRAPHENE_PRICE_FEED_FIELDS )
#undef CALCULATE_MEDIAN_VALUE
   // *** End Median Calculations ***

   current_feed = median_feed;
}

asset asset_object::amount_from_string(string amount_string) const
{ try {
   bool negative_found = false;
   bool decimal_found = false;
   for( const char c : amount_string )
   {
      if( isdigit( c ) )
         continue;

      if( c == '-' && !negative_found )
      {
         negative_found = true;
         continue;
      }

      if( c == '.' && !decimal_found )
      {
         decimal_found = true;
         continue;
      }

      FC_THROW( (amount_string) );
   }

   share_type satoshis = 0;

   share_type scaled_precision = asset::scaled_precision( precision );

   const auto decimal_pos = amount_string.find( '.' );
   const string lhs = amount_string.substr( negative_found, decimal_pos );
   if( !lhs.empty() )
      satoshis += fc::safe<int64_t>(std::stoll(lhs)) *= scaled_precision;

   if( decimal_found )
   {
      const size_t max_rhs_size = std::to_string( scaled_precision.value ).substr( 1 ).size();

      string rhs = amount_string.substr( decimal_pos + 1 );
      FC_ASSERT( rhs.size() <= max_rhs_size );

      while( rhs.size() < max_rhs_size )
         rhs += '0';

      if( !rhs.empty() )
         satoshis += std::stoll( rhs );
   }

   FC_ASSERT( satoshis <= GRAPHENE_MAX_SHARE_SUPPLY );

   if( negative_found )
      satoshis *= -1;

   return amount(satoshis);
   } FC_CAPTURE_AND_RETHROW( (amount_string) ) }

string asset_object::amount_to_string(share_type amount) const
{
   share_type scaled_precision = 1;
   for( uint8_t i = 0; i < precision; ++i )
      scaled_precision *= 10;
   assert(scaled_precision > 0);

   string result = fc::to_string(amount.value / scaled_precision.value);
   auto decimals = amount.value % scaled_precision.value;
   if( decimals )
      result += "." + fc::to_string(scaled_precision.value + decimals).erase(0,1);
   return result;
}
<|endoftext|>


<commit_before>/**
 * @file   Severity.hpp
 * @brief  Severity class prototype.
 * @author zer0
 * @date   2016-07-09
 */

#ifndef __INCLUDE_LIBTBAG__LIBTBAG_LOG_DETAILS_SEVERITY_HPP__
#define __INCLUDE_LIBTBAG__LIBTBAG_LOG_DETAILS_SEVERITY_HPP__

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif

#include <libtbag/config.h>
#include <libtbag/predef.hpp>

#include <string>
#include <numeric>
#include <type_traits>

// -------------------
NAMESPACE_LIBTBAG_OPEN
// -------------------

namespace log     {
namespace details {

/**
 * Severity class prototype.
 *
 * @author zer0
 * @date   2016-07-09
 */
class Severity
{
public:
    char const * text;
    int level;

public:
    // @formatter:off
    Severity() : text(), level()
    { /* EMPTY */ }
    Severity(char const * t, int l) : text(t), level(l)
    { /* EMPTY */ }
    Severity(Severity const & obj) : text(obj.text), level(obj.level)
    { /* EMPTY */ }
    ~Severity()
    { /* EMPTY */ }
    // @formatter:on

public:
    Severity & operator =(Severity const & obj)
    {
        if (this != &obj) {
            level = obj.level;
            text  = obj.text;
        }
        return *this;
    }

public:
    // @formatter:off
    inline operator int() const TBAG_NOEXCEPT
    { return level; }
    inline operator std::string() const TBAG_NOEXCEPT
    { return std::string(text); }

    inline bool operator ==(Severity const & obj) const TBAG_NOEXCEPT
    { return level == obj.level; }
    inline bool operator !=(Severity const & obj) const TBAG_NOEXCEPT
    { return level != obj.level; }

    inline bool operator <(Severity const & obj) const TBAG_NOEXCEPT
    { return level < obj.level; }
    inline bool operator >(Severity const & obj) const TBAG_NOEXCEPT
    { return level > obj.level; }

    inline bool operator <=(Severity const & obj) const TBAG_NOEXCEPT
    { return level <= obj.level; }
    inline bool operator >=(Severity const & obj) const TBAG_NOEXCEPT
    { return level >= obj.level; }

    inline bool isContain(Severity const & obj) const TBAG_NOEXCEPT
    { return level >= obj.level; }
    // @formatter:on
};

Severity const           OFF_SEVERITY("OFF"      ,   0); // Hide all messages.
Severity const     EMERGENCY_SEVERITY("EMERGENCY", 100); // System is unusable.
Severity const         ALERT_SEVERITY("ALERT"    , 200); // Action must be taken immediately.
Severity const      CRITICAL_SEVERITY("CRITICAL" , 300); // Critical conditions.
Severity const         ERROR_SEVERITY("ERROR"    , 400); // Error conditions.
Severity const       WARNING_SEVERITY("WARNING"  , 500); // Warning conditions.
Severity const        NOTICE_SEVERITY("NOTICE"   , 600); // Normal but significant condition.
Severity const INFORMATIONAL_SEVERITY("INFO"     , 700); // Informational messages.
Severity const         DEBUG_SEVERITY("DEBUG"    , 800); // Debug-level messages.

} // namespace details
} // namespace log

// --------------------
NAMESPACE_LIBTBAG_CLOSE
// --------------------

#endif // __INCLUDE_LIBTBAG__LIBTBAG_LOG_DETAILS_SEVERITY_HPP__

<commit_msg>Refactoring Severity class.<commit_after>/**
 * @file   Severity.hpp
 * @brief  Severity class prototype.
 * @author zer0
 * @date   2016-07-09
 */

#ifndef __INCLUDE_LIBTBAG__LIBTBAG_LOG_DETAILS_SEVERITY_HPP__
#define __INCLUDE_LIBTBAG__LIBTBAG_LOG_DETAILS_SEVERITY_HPP__

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif

#include <libtbag/config.h>
#include <libtbag/predef.hpp>
#include <string>

// -------------------
NAMESPACE_LIBTBAG_OPEN
// -------------------

namespace log     {
namespace details {

/**
 * Severity class prototype.
 *
 * @author zer0
 * @date   2016-07-09
 */
class Severity
{
public:
    char const * text;
    int level;

public:
    // @formatter:off
    Severity() : text(), level()
    { /* EMPTY */ }
    Severity(char const * t, int l) : text(t), level(l)
    { /* EMPTY */ }
    Severity(Severity const & obj) : text(obj.text), level(obj.level)
    { /* EMPTY */ }
    ~Severity()
    { /* EMPTY */ }
    // @formatter:on

public:
    Severity & operator =(Severity const & obj)
    {
        if (this != &obj) {
            level = obj.level;
            text  = obj.text;
        }
        return *this;
    }

public:
    // @formatter:off
    inline operator int() const TBAG_NOEXCEPT
    { return level; }
    inline operator char const *() const TBAG_NOEXCEPT
    { return text; }

    inline friend bool operator ==(Severity const & lh, Severity const & rh) TBAG_NOEXCEPT
    { return lh.level == rh.level; }
    inline friend bool operator !=(Severity const & lh, Severity const & rh) TBAG_NOEXCEPT
    { return lh.level != rh.level; }

    inline friend bool operator <(Severity const & lh, Severity const & rh) TBAG_NOEXCEPT
    { return lh.level < rh.level; }
    inline friend bool operator >(Severity const & lh, Severity const & rh) TBAG_NOEXCEPT
    { return lh.level > rh.level; }

    inline friend bool operator <=(Severity const & lh, Severity const & rh) TBAG_NOEXCEPT
    { return lh.level <= rh.level; }
    inline friend bool operator >=(Severity const & lh, Severity const & rh) TBAG_NOEXCEPT
    { return lh.level >= rh.level; }

    inline bool isContain(Severity const & obj) const TBAG_NOEXCEPT
    { return level >= obj.level; }
    // @formatter:on
};

Severity const           OFF_SEVERITY("OFF"      ,   0); // Hide all messages.
Severity const     EMERGENCY_SEVERITY("EMERGENCY", 100); // System is unusable.
Severity const         ALERT_SEVERITY("ALERT"    , 200); // Action must be taken immediately.
Severity const      CRITICAL_SEVERITY("CRITICAL" , 300); // Critical conditions.
Severity const         ERROR_SEVERITY("ERROR"    , 400); // Error conditions.
Severity const       WARNING_SEVERITY("WARNING"  , 500); // Warning conditions.
Severity const        NOTICE_SEVERITY("NOTICE"   , 600); // Normal but significant condition.
Severity const INFORMATIONAL_SEVERITY("INFO"     , 700); // Informational messages.
Severity const         DEBUG_SEVERITY("DEBUG"    , 800); // Debug-level messages.

} // namespace details
} // namespace log

// --------------------
NAMESPACE_LIBTBAG_CLOSE
// --------------------

#endif // __INCLUDE_LIBTBAG__LIBTBAG_LOG_DETAILS_SEVERITY_HPP__

<|endoftext|>


<commit_before>/**
 * @file   SignalHandler.hpp
 * @brief  SignalHandler class prototype.
 * @author zer0
 * @date   2016-12-24
 */

#ifndef __INCLUDE_LIBTBAG__LIBTBAG_SIGNAL_SIGNALHANDLER_HPP__
#define __INCLUDE_LIBTBAG__LIBTBAG_SIGNAL_SIGNALHANDLER_HPP__

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif

#include <libtbag/config.h>
#include <libtbag/predef.hpp>

#include <csignal>
#include <climits>
#include <cstdlib>

#include <string>
#include <exception>
#include <functional>

// -------------------
NAMESPACE_LIBTBAG_OPEN
// -------------------

namespace signal {

// ==================
namespace __impl {
/** @warning Don't use this method from user level developers. */
TBAG_API void createInstance();
TBAG_API void releaseInstance();
} // namespace __impl
// ==================

#ifndef TBAG_SIGNAL_MAP
#define TBAG_SIGNAL_MAP(_TBAG_XX) \
    _TBAG_XX(SIGNAL_INTERRUPT               , SIGINT /*  2 */, "interrupt") \
    _TBAG_XX(SIGNAL_ILLEGAL_INSTRUCTION     , SIGILL /*  4 */, "illegal instruction (not reset when caught)") \
    _TBAG_XX(SIGNAL_FLOATING_POINT_EXCEPTION, SIGFPE /*  8 */, "floating point exception") \
    _TBAG_XX(SIGNAL_SEGMENTATION_VIOLATION  , SIGSEGV/* 11 */, "segmentation violation") \
    _TBAG_XX(SIGNAL_TERMINATION             , SIGTERM/* 15 */, "software termination signal from kill") \
    _TBAG_XX(SIGNAL_ABORT                   , SIGABRT/* ?? */, "abort()") /* Windows(22), OSX(6) */ \
    /* -- END -- */
#endif

#define _TBAG_XX(name, signal, message) TBAG_CONSTEXPR int const TBAG_##name = signal;
TBAG_SIGNAL_MAP(_TBAG_XX)
#undef _TBAG_XX

// Don't use the std::numeric_limits class.
// Avoid collisions of min & max symbol in MSVC.
TBAG_CONSTEXPR int const SIGNAL_STD_TERMINATE = INT_MAX; // C++ terminate signal.
TBAG_CONSTEXPR int const FIRST_ORDER = INT_MAX;
TBAG_CONSTEXPR int const LAST_ORDER  = INT_MIN;

inline bool existSignalNumber(int signal_number) TBAG_NOEXCEPT
{
    switch (signal_number) {
#define _TBAG_XX(name, signal, message) case TBAG_##name: return true;
    TBAG_SIGNAL_MAP(_TBAG_XX)
#undef _TBAG_XX
    default: return false;
    }
}

inline char const * const getSignalName(int signal_number) TBAG_NOEXCEPT
{
    switch (signal_number) {
#define _TBAG_XX(name, signal, message) case TBAG_##name: return #signal;
    TBAG_SIGNAL_MAP(_TBAG_XX)
#undef _TBAG_XX
    default: return "UNKNOWN";
    }
}

/**
 * Signal handler interface.
 *
 * @author zer0
 * @date   2016-12-24
 */
struct SignalHandler
{
    virtual void run(int signal) = 0;
};

using SignalCallback = std::function<void(int)>;

/**
 * FunctionalSignalHandler handler interface.
 *
 * @author zer0
 * @date   2017-07-14
 */
struct FunctionalSignalHandler : public SignalHandler
{
public:
    SignalCallback signal_cb;

public:
    FunctionalSignalHandler() : signal_cb()
    { /* EMPTY. */ }
    FunctionalSignalHandler(SignalCallback const & cb) : signal_cb(cb)
    { /* EMPTY. */ }

public:
    virtual ~FunctionalSignalHandler()
    { /* EMPTY. */ }

public:
    void setRun(SignalCallback const & cb)
    { signal_cb = cb; }

public:
    virtual void run(int signal) override
    {
        if (signal_cb) {
            signal_cb(signal);
        }
    }
};

/**
 * FuncSignalHandler typedef.
 *
 * @author zer0
 * @date   2017-07-14
 */
using FuncSignalHandler = FunctionalSignalHandler;

TBAG_API void registerStdTerminateHandler(SignalHandler * handler, int order = 0);
TBAG_API void registerStdTerminateFunctionalHandler(SignalCallback const & cb, int order = 0);
TBAG_API void registerHandler(int signal, SignalHandler * handler, int order = 0);
TBAG_API void registerFunctionalHandler(int signal, SignalCallback const & cb, int order = 0);

TBAG_API void registerDefaultStdTerminateHandler(std::string const & logger_name = std::string());
TBAG_API void registerDefaultErrorHandler(std::string const & logger_name = std::string());
TBAG_API void registerDefaultHandler(std::string const & logger_name = std::string());

TBAG_API SignalHandler * createDefaultSignalHandler(std::string const & logger_name = std::string());

// clang-format off
inline int raise(int signal)
{ return std::raise(signal); }

[[ noreturn ]] inline void terminate() TBAG_NOEXCEPT_SP_OP(std::terminate())
{ std::terminate(); }

[[ noreturn ]] inline void exit(int code) TBAG_NOEXCEPT_SP_OP(std::exit(code))
{ std::exit(code); }

[[ noreturn ]] inline void exitForce(int code) TBAG_NOEXCEPT_SP_OP(std::_Exit(code))
{ std::_Exit(code); }
// clang-format on

} // namespace signal

// --------------------
NAMESPACE_LIBTBAG_CLOSE
// --------------------

#endif // __INCLUDE_LIBTBAG__LIBTBAG_SIGNAL_SIGNALHANDLER_HPP__

<commit_msg>Add TBAG_SIGNAL_KILL const.<commit_after>/**
 * @file   SignalHandler.hpp
 * @brief  SignalHandler class prototype.
 * @author zer0
 * @date   2016-12-24
 */

#ifndef __INCLUDE_LIBTBAG__LIBTBAG_SIGNAL_SIGNALHANDLER_HPP__
#define __INCLUDE_LIBTBAG__LIBTBAG_SIGNAL_SIGNALHANDLER_HPP__

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif

#include <libtbag/config.h>
#include <libtbag/predef.hpp>

#include <csignal>
#include <climits>
#include <cstdlib>

#include <string>
#include <exception>
#include <functional>

// -------------------
NAMESPACE_LIBTBAG_OPEN
// -------------------

namespace signal {

// ==================
namespace __impl {
/** @warning Don't use this method from user level developers. */
TBAG_API void createInstance();
TBAG_API void releaseInstance();
} // namespace __impl
// ==================

#ifndef TBAG_SIGNAL_MAP
#define TBAG_SIGNAL_MAP(_TBAG_XX) \
    _TBAG_XX(SIGNAL_INTERRUPT               , SIGINT /*  2 */, "interrupt") \
    _TBAG_XX(SIGNAL_ILLEGAL_INSTRUCTION     , SIGILL /*  4 */, "illegal instruction (not reset when caught)") \
    _TBAG_XX(SIGNAL_FLOATING_POINT_EXCEPTION, SIGFPE /*  8 */, "floating point exception") \
    _TBAG_XX(SIGNAL_SEGMENTATION_VIOLATION  , SIGSEGV/* 11 */, "segmentation violation") \
    _TBAG_XX(SIGNAL_TERMINATION             , SIGTERM/* 15 */, "software termination signal from kill") \
    _TBAG_XX(SIGNAL_ABORT                   , SIGABRT/* ?? */, "abort()") /* Windows(22), OSX(6) */ \
    /* -- END -- */
#endif

#define _TBAG_XX(name, signal, message) TBAG_CONSTEXPR int const TBAG_##name = signal;
TBAG_SIGNAL_MAP(_TBAG_XX)
#undef _TBAG_XX

// Don't use the std::numeric_limits class.
// Avoid collisions of min & max symbol in MSVC.
TBAG_CONSTEXPR int const SIGNAL_STD_TERMINATE = INT_MAX; // C++ terminate signal.
TBAG_CONSTEXPR int const FIRST_ORDER = INT_MAX;
TBAG_CONSTEXPR int const LAST_ORDER  = INT_MIN;

#ifndef TBAG_SIGNAL_KILL_NUMBER
# if defined(TBAG_PLATFORM_WINDOWS)
#  define TBAG_SIGNAL_KILL_NUMBER SIGTERM // Windows does not have SIGKILL.
# elif defined(SIGKILL)
#  define TBAG_SIGNAL_KILL_NUMBER SIGKILL // kill (cannot be caught or ignored)
# else
#  define TBAG_SIGNAL_KILL_NUMBER 9 // SIGKILL is often numbered 9.
# endif
#endif

TBAG_CONSTEXPR int const TBAG_SIGNAL_KILL = TBAG_SIGNAL_KILL_NUMBER;

inline bool existSignalNumber(int signal_number) TBAG_NOEXCEPT
{
    switch (signal_number) {
#define _TBAG_XX(name, signal, message) case TBAG_##name: return true;
    TBAG_SIGNAL_MAP(_TBAG_XX)
#undef _TBAG_XX
    default: return false;
    }
}

inline char const * const getSignalName(int signal_number) TBAG_NOEXCEPT
{
    switch (signal_number) {
#define _TBAG_XX(name, signal, message) case TBAG_##name: return #signal;
    TBAG_SIGNAL_MAP(_TBAG_XX)
#undef _TBAG_XX
    default: return "UNKNOWN";
    }
}

/**
 * Signal handler interface.
 *
 * @author zer0
 * @date   2016-12-24
 */
struct SignalHandler
{
    virtual void run(int signal) = 0;
};

using SignalCallback = std::function<void(int)>;

/**
 * FunctionalSignalHandler handler interface.
 *
 * @author zer0
 * @date   2017-07-14
 */
struct FunctionalSignalHandler : public SignalHandler
{
public:
    SignalCallback signal_cb;

public:
    FunctionalSignalHandler() : signal_cb()
    { /* EMPTY. */ }
    FunctionalSignalHandler(SignalCallback const & cb) : signal_cb(cb)
    { /* EMPTY. */ }

public:
    virtual ~FunctionalSignalHandler()
    { /* EMPTY. */ }

public:
    void setRun(SignalCallback const & cb)
    { signal_cb = cb; }

public:
    virtual void run(int signal) override
    {
        if (signal_cb) {
            signal_cb(signal);
        }
    }
};

/**
 * FuncSignalHandler typedef.
 *
 * @author zer0
 * @date   2017-07-14
 */
using FuncSignalHandler = FunctionalSignalHandler;

TBAG_API void registerStdTerminateHandler(SignalHandler * handler, int order = 0);
TBAG_API void registerStdTerminateFunctionalHandler(SignalCallback const & cb, int order = 0);
TBAG_API void registerHandler(int signal, SignalHandler * handler, int order = 0);
TBAG_API void registerFunctionalHandler(int signal, SignalCallback const & cb, int order = 0);

TBAG_API void registerDefaultStdTerminateHandler(std::string const & logger_name = std::string());
TBAG_API void registerDefaultErrorHandler(std::string const & logger_name = std::string());
TBAG_API void registerDefaultHandler(std::string const & logger_name = std::string());

TBAG_API SignalHandler * createDefaultSignalHandler(std::string const & logger_name = std::string());

// clang-format off
inline int raise(int signal)
{ return std::raise(signal); }

[[ noreturn ]] inline void terminate() TBAG_NOEXCEPT_SP_OP(std::terminate())
{ std::terminate(); }

[[ noreturn ]] inline void exit(int code) TBAG_NOEXCEPT_SP_OP(std::exit(code))
{ std::exit(code); }

[[ noreturn ]] inline void exitForce(int code) TBAG_NOEXCEPT_SP_OP(std::_Exit(code))
{ std::_Exit(code); }
// clang-format on

} // namespace signal

// --------------------
NAMESPACE_LIBTBAG_CLOSE
// --------------------

#endif // __INCLUDE_LIBTBAG__LIBTBAG_SIGNAL_SIGNALHANDLER_HPP__

<|endoftext|>


<commit_before>/****************************************************************************

    atom.hpp - support file for writing LV2 plugins in C++

    Copyright (C) 2012 Michael Fisher <mfisher31@gmail.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307  USA

****************************************************************************/

#ifndef LVTK_LV2_ATOM_HPP
#define LVTK_LV2_ATOM_HPP

#include <lv2/lv2plug.in/ns/ext/atom/atom.h>
#include <lv2/lv2plug.in/ns/ext/atom/forge.h>
#include <lv2/lv2plug.in/ns/ext/atom/util.h>

namespace lvtk {

} /* namespace lvtk */

#endif /* LVTK_LV2_ATOM_HPP */
<commit_msg>Added some typedefs and an AtomForge(basic) wrapper beginning<commit_after>/****************************************************************************

    atom.hpp - support file for writing LV2 plugins in C++

    Copyright (C) 2012 Michael Fisher <mfisher31@gmail.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307  USA

****************************************************************************/

#ifndef LVTK_LV2_ATOM_HPP
#define LVTK_LV2_ATOM_HPP

#include <lv2/lv2plug.in/ns/ext/atom/atom.h>
#include <lv2/lv2plug.in/ns/ext/atom/forge.h>
#include <lv2/lv2plug.in/ns/ext/atom/util.h>

#include <lvtk/ext/midi.hpp>
#include <lvtk/ext/patch.hpp>

namespace lvtk {

   /** Typedef for an Atom */
   typedef LV2_Atom             Atom;

   /** Typedef for an Atom Forge */
   typedef LV2_Atom_Forge_Frame AtomForgeFrame;

   typedef uint32_t     (*MapFunc)(const char* symbol);
   typedef const char*  (*UnmapFunc)(uint32_t id);

   class AtomForge
   {
      LV2_Atom_Forge forge;
      LV2_URID midi_MidiEvent, patch_Set, patch_Get, patch_body;

   public:

      AtomForge()
      : midi_MidiEvent(0)
      , patch_Set(0), patch_Get(0), patch_body(0)
      { }

      AtomForge (MapFunc map)
      {
         init (map);
      }

      /**
       * Initialize the underlying atom forge
       * @param map The mapping function needed for init
       */
      inline void
      init (MapFunc map)
      {
         assert (map != NULL);

         midi_MidiEvent = map(LV2_MIDI__MidiEvent);
         patch_Set      = map(LV2_PATCH__Set);
         patch_Get      = map(LV2_PATCH__Get);

         lv2_atom_forge_set_buffer (&forge, NULL, 0);
         forge.Blank    = map(LV2_ATOM__Blank);
         forge.Bool     = map(LV2_ATOM__Bool);
         forge.Chunk    = map(LV2_ATOM__Chunk);
         forge.Double   = map(LV2_ATOM__Double);
         forge.Float    = map(LV2_ATOM__Float);
         forge.Int      = map(LV2_ATOM__Int);
         forge.Long     = map(LV2_ATOM__Long);
         forge.Literal  = map(LV2_ATOM__Literal);
         forge.Path     = map(LV2_ATOM__Path);
         forge.Property = map(LV2_ATOM__Property);
         forge.Resource = map(LV2_ATOM__Resource);
         forge.Sequence = map(LV2_ATOM__Sequence);
         forge.String   = map(LV2_ATOM__String);
         forge.Tuple    = map(LV2_ATOM__Tuple);
         forge.URI      = map(LV2_ATOM__URI);
         forge.URID     = map(LV2_ATOM__URID);
         forge.Vector   = map(LV2_ATOM__Vector);
      }

      inline LV2_Atom_Forge*
      cobj()
      {
         return &forge;
      }

      inline void
      set_buffer(uint8_t* buf, uint32_t size)
      {
         lv2_atom_forge_set_buffer (&forge, buf, size);
      }

      uint32_t
      atom_total_size (const LV2_Atom* atom)
      {
         return lv2_atom_total_size (atom);
      }

      /* MIDI Related */

      const LV2_Atom* note_on (uint8_t key, uint8_t velocity)
      {
         uint8_t midi[3];
         midi[0] = 0x90;
         midi[1] = key;
         midi[2] = velocity;

         LV2_Atom* atom = (LV2_Atom*) lv2_atom_forge_atom (&forge, 3, midi_MidiEvent);
         lv2_atom_forge_raw (&forge, midi, 3);
         return atom;
      }

      const LV2_Atom* note_off (uint8_t key)
      {
         uint8_t midi[3];
         midi[0] = 0x80;
         midi[1] = key;
         midi[2] = 0x00;

         LV2_Atom* atom = (LV2_Atom*) lv2_atom_forge_atom (&forge, 3, midi_MidiEvent);
         lv2_atom_forge_raw (&forge, midi, 3);
         return atom;
      }

      inline LV2_Atom_Forge_Ref
      path (const std::string& path)
      {
         return lv2_atom_forge_path(&forge,path.c_str(),path.size());
      }

      inline LV2_Atom_Forge_Ref
      resource (AtomForgeFrame *frame, uint32_t id, uint32_t otype)
      {
         // Write object header
         return lv2_atom_forge_resource (&forge, frame, id, otype);
      }

      inline LV2_Atom_Forge_Ref
      blank (AtomForgeFrame *frame, uint32_t id, uint32_t otype)
      {
         // Write object header
         return lv2_atom_forge_blank (&forge, frame, id, otype);
      }

      inline LV2_Atom_Forge_Ref
      property_head (uint32_t key, uint32_t context)
      {
         return lv2_atom_forge_property_head (&forge, key, context);
      }

      inline void
      pop (AtomForgeFrame *frame)
      {
         lv2_atom_forge_pop(&forge, frame);
      }

      inline LV2_Atom_Forge_Ref
      raw (const void* data, uint32_t size)
      {
         return lv2_atom_forge_raw (&forge, data, size);
      }

   };
} /* namespace lvtk */

#endif /* LVTK_LV2_ATOM_HPP */
<|endoftext|>


<commit_before>
/*!
	\file

	\author Igor Mironchik (igor.mironchik at gmail dot com).

	Copyright (c) 2014 Igor Mironchik

	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.
*/

// Qt include.
#include <QObject>
#include <QtTest/QtTest>
#include <QSharedPointer>
#include <QLabel>

// QtMWidgets include.
#include <QtMWidgets/PageView>

class TestPageView
	:	public QObject
{
	Q_OBJECT

private slots:

	void testView()
	{
		QtMWidgets::PageView p;
		p.show();

		QVERIFY( QTest::qWaitForWindowActive( &p ) );

		QVERIFY( p.currentIndex() == -1 );
		QVERIFY( p.count() == 0 );
		QVERIFY( p.showPageControl() == true );

		p.setShowPageControl( false );

		QVERIFY( p.showPageControl() == false );

		p.resize( 300, 300 );

		QLabel w1( QStringLiteral( "1" ) );

		auto f = w1.font();
		f.setPixelSize( 100 );
		f.setBold( true );

		w1.setFont( f );
		w1.setAlignment( Qt::AlignCenter );

		p.addWidget( &w1 );

		QVERIFY( p.count() == 1 );
		QVERIFY( p.currentIndex() == 0 );
		QVERIFY( p.currentWidget() == &w1 );
		QVERIFY( p.indexOf( &w1 ) == 0 );
		QVERIFY( p.widget( 0 ) == &w1 );

		QLabel w2( QStringLiteral( "2" ) );
		w2.setFont( f );
		w2.setAlignment( Qt::AlignCenter );

		p.addWidget( &w2 );

		p.setCurrentWidget( &w2 );

		QVERIFY( p.currentIndex() == 1 );

		QLabel w3( QStringLiteral( "3" ) );
		w3.setFont( f );
		w3.setAlignment( Qt::AlignCenter );

		QTest::qWait( 350 );

		p.addWidget( &w3 );

		{
			const auto c = p.rect().center() - QPoint( p.rect().width() / 3, 0 );
			QTest::mousePress( &p, Qt::LeftButton, {}, c, 20 );
			const auto pos = c -
				QPoint( p.rect().width() - p.rect().width() / 4, 0 );
			QMouseEvent me( QEvent::MouseMove, pos, Qt::LeftButton, Qt::LeftButton, {} );
			QApplication::sendEvent( &p, &me );
			QTest::mouseRelease( &p, Qt::LeftButton, {}, pos, 20 );
		}

		QTest::qWait( 350 );

		QVERIFY( p.currentWidget() == &w3 );

		{
			const auto c = p.rect().center() - QPoint( p.rect().width() / 3, 0 );
			QTest::mousePress( &p, Qt::LeftButton, {}, c, 20 );
			const auto pos = c +
				QPoint( p.rect().width() - p.rect().width() / 4, 0 );
			QMouseEvent me( QEvent::MouseMove, pos, Qt::LeftButton, Qt::LeftButton, {} );
			QApplication::sendEvent( &p, &me );
			QTest::mouseRelease( &p, Qt::LeftButton, {}, pos, 20 );
		}

		QTest::qWait( 350 );

		QVERIFY( p.currentIndex() == 1 );

		p.removeWidget( &w3 );

		QVERIFY( p.count() == 2 );

		QVERIFY( p.widget( 1 ) == &w2 );
	}
};

QTEST_MAIN( TestPageView )

#include "main.moc"
<commit_msg>Set bigger delays.<commit_after>
/*!
	\file

	\author Igor Mironchik (igor.mironchik at gmail dot com).

	Copyright (c) 2014 Igor Mironchik

	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.
*/

// Qt include.
#include <QObject>
#include <QtTest/QtTest>
#include <QSharedPointer>
#include <QLabel>

// QtMWidgets include.
#include <QtMWidgets/PageView>

class TestPageView
	:	public QObject
{
	Q_OBJECT

private slots:

	void testView()
	{
		QtMWidgets::PageView p;
		p.show();

		QVERIFY( QTest::qWaitForWindowActive( &p ) );

		QVERIFY( p.currentIndex() == -1 );
		QVERIFY( p.count() == 0 );
		QVERIFY( p.showPageControl() == true );

		p.setShowPageControl( false );

		QVERIFY( p.showPageControl() == false );

		p.resize( 300, 300 );

		QLabel w1( QStringLiteral( "1" ) );

		auto f = w1.font();
		f.setPixelSize( 100 );
		f.setBold( true );

		w1.setFont( f );
		w1.setAlignment( Qt::AlignCenter );

		p.addWidget( &w1 );

		QVERIFY( p.count() == 1 );
		QVERIFY( p.currentIndex() == 0 );
		QVERIFY( p.currentWidget() == &w1 );
		QVERIFY( p.indexOf( &w1 ) == 0 );
		QVERIFY( p.widget( 0 ) == &w1 );

		QLabel w2( QStringLiteral( "2" ) );
		w2.setFont( f );
		w2.setAlignment( Qt::AlignCenter );

		p.addWidget( &w2 );

		p.setCurrentWidget( &w2 );

		QVERIFY( p.currentIndex() == 1 );

		QLabel w3( QStringLiteral( "3" ) );
		w3.setFont( f );
		w3.setAlignment( Qt::AlignCenter );

		QTest::qWait( 350 );

		p.addWidget( &w3 );

		{
			const auto c = p.rect().center() - QPoint( p.rect().width() / 3, 0 );
			QTest::mousePress( &p, Qt::LeftButton, {}, c, 20 );
			const auto pos = c -
				QPoint( p.rect().width() - p.rect().width() / 4, 0 );
			QMouseEvent me( QEvent::MouseMove, pos, Qt::LeftButton, Qt::LeftButton, {} );
			QApplication::sendEvent( &p, &me );
			QTest::mouseRelease( &p, Qt::LeftButton, {}, pos, 20 );
		}

		QTest::qWait( 1000 );

		QVERIFY( p.currentWidget() == &w3 );

		{
			const auto c = p.rect().center() - QPoint( p.rect().width() / 3, 0 );
			QTest::mousePress( &p, Qt::LeftButton, {}, c, 20 );
			const auto pos = c +
				QPoint( p.rect().width() - p.rect().width() / 4, 0 );
			QMouseEvent me( QEvent::MouseMove, pos, Qt::LeftButton, Qt::LeftButton, {} );
			QApplication::sendEvent( &p, &me );
			QTest::mouseRelease( &p, Qt::LeftButton, {}, pos, 20 );
		}

		QTest::qWait( 1000 );

		QVERIFY( p.currentIndex() == 1 );

		p.removeWidget( &w3 );

		QVERIFY( p.count() == 2 );

		QVERIFY( p.widget( 1 ) == &w2 );
	}
};

QTEST_MAIN( TestPageView )

#include "main.moc"
<|endoftext|>


<commit_before>#include <stan/math/prim/mat.hpp>
#include <stan/math/prim/arr.hpp>
#include <gtest/gtest.h>

TEST(ErrorHandlingOpenCL, checkThrows) {
  const char* function = "test_func";
  const char* msg = "test";
  EXPECT_THROW(stan::math::throw_openCL(function, msg), std::domain_error);
}
<commit_msg>ignore opencl test on travis<commit_after>#ifdef STAN_OPENCL
#include <stan/math/prim/mat.hpp>
#include <stan/math/prim/arr.hpp>
#include <gtest/gtest.h>

TEST(ErrorHandlingOpenCL, checkThrows) {
  const char* function = "test_func";
  const char* msg = "test";
  EXPECT_THROW(stan::math::throw_openCL(function, msg), std::domain_error);
}
#else
TEST(ErrorHandlingOpenCL, checkThrows) {
  int a;
  EXPECT_NO_THROW(a = 1);
}
#endif
<|endoftext|>


<commit_before>/*
   Copyright 2017 Thomas Krause <thomaskrause@posteo.de>

   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 "queryconfig.h"
#include "annis/types.h"  // for Component

annis::QueryConfig::QueryConfig()
  : optimize(true), forceFallback(false), avoidNestedBySwitch(true) ,
    numOfBackgroundTasks(0), enableTaskIndexJoin(false), enableThreadIndexJoin(false), enableSIMDIndexJoin(false), threadPool(nullptr)

{
//  size_t numOfCPUs = std::thread::hardware_concurrency();
//  if(numOfCPUs > 0)
//  {
//    numOfBackgroundTasks = numOfCPUs-1;
//    threadPool = std::make_shared<ThreadPool>(numOfBackgroundTasks);
//  }
}
<commit_msg>Automatically enable SIMDIndexJoin in QueryConfig if current hardware supports it.<commit_after>/*
   Copyright 2017 Thomas Krause <thomaskrause@posteo.de>

   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 "queryconfig.h"
#include "annis/types.h"  // for Component

#include <Vc/global.h>
#include <Vc/support.h>

annis::QueryConfig::QueryConfig()
  : optimize(true), forceFallback(false), avoidNestedBySwitch(true) ,
    numOfBackgroundTasks(0), enableTaskIndexJoin(false), enableThreadIndexJoin(false), enableSIMDIndexJoin(false), threadPool(nullptr)

{
  if(Vc::isImplementationSupported(Vc::Implementation::AVX2Impl))
  {
    enableSIMDIndexJoin = true;
  }

//  size_t numOfCPUs = std::thread::hardware_concurrency();
//  if(numOfCPUs > 0)
//  {
//    numOfBackgroundTasks = numOfCPUs-1;
//    threadPool = std::make_shared<ThreadPool>(numOfBackgroundTasks);
//  }
}
<|endoftext|>


<commit_before>#ifndef VEXCL_UTIL_HPP
#define VEXCL_UTIL_HPP

/*
The MIT License

Copyright (c) 2012-2014 Denis Demidov <dennis.demidov@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
 * \file   vexcl/util.hpp
 * \author Denis Demidov <dennis.demidov@gmail.com>
 * \brief  OpenCL general utilities.
 */

#if defined(_MSC_VER) && ( defined(min) || defined(max) )
#  error Please define NOMINMAX macro globally in your project
#endif

#include <iostream>
#include <string>
#include <vector>
#include <array>
#include <tuple>
#include <map>
#include <stdexcept>
#include <algorithm>
#include <type_traits>

#include <boost/config.hpp>

#ifdef BOOST_NO_VARIADIC_TEMPLATES
#  include <boost/proto/proto.hpp>
#  include <boost/preprocessor/repetition.hpp>
#  ifndef VEXCL_MAX_ARITY
#    define VEXCL_MAX_ARITY BOOST_PROTO_MAX_ARITY
#  endif
#endif

namespace vex {

/// Check run-time condition.
/** Throws std::runtime_error if condition is false */
template <class Condition, class Message>
inline void precondition(const Condition &condition, const Message &fail_message) {
#ifdef _MSC_VER
#  pragma warning(push)
#  pragma warning(disable: 4800)
#endif
    if (!condition) throw std::runtime_error(fail_message);
#ifdef _MSC_VER
#  pragma warning(pop)
#endif
}

/// Return next power of 2.
inline size_t nextpow2(size_t x) {
    --x;
    x |= x >> 1U;
    x |= x >> 2U;
    x |= x >> 4U;
    x |= x >> 8U;
    x |= x >> 16U;
    return ++x;
}

/// Align n to the next multiple of m.
inline size_t alignup(size_t n, size_t m = 16U) {
    return (n + m - 1) / m * m;
}

template <class T>
struct is_tuple : std::false_type {};

#ifndef BOOST_NO_VARIADIC_TEMPLATES

template <class... Elem>
struct is_tuple < std::tuple<Elem...> > : std::true_type {};

#else

#define VEXCL_IS_TUPLE(z, n, unused)                                           \
  template <BOOST_PP_ENUM_PARAMS(n, class Elem)>                               \
  struct is_tuple<                                                             \
      std::tuple<BOOST_PP_ENUM_PARAMS(n, Elem)> > : std::true_type {           \
  };

BOOST_PP_REPEAT_FROM_TO(1, VEXCL_MAX_ARITY, VEXCL_IS_TUPLE, ~)

#undef VEXCL_IS_TUPLE

#endif

#ifndef BOOST_NO_VARIADIC_TEMPLATES
/// Create std::array from arguments
template <class T, class... Tail>
std::array<T, 1 + sizeof...(Tail)>
make_array(T t, Tail... tail) {
    std::array<T, 1 + sizeof...(Tail)> a = {{t, static_cast<T>(tail)...}};
    return a;
}
#else

#define VEXCL_PRINT_PARAM(z, n, data) T ## n t ## n
#define VEXCL_INIT_ARRAY(z, n, data) static_cast<T0>(t ## n)
#define VEXCL_MAKE_ARRAY(z, n, data)                                           \
  template <BOOST_PP_ENUM_PARAMS(n, class T)>                                  \
  std::array<T0, n> make_array(BOOST_PP_ENUM(n, VEXCL_PRINT_PARAM, ~)) {       \
    std::array<T0, n> a = { { BOOST_PP_ENUM(n, VEXCL_INIT_ARRAY, ~) } };       \
    return a;                                                                  \
  }

BOOST_PP_REPEAT_FROM_TO(1, VEXCL_MAX_ARITY, VEXCL_MAKE_ARRAY, ~)

#undef VEXCL_MAKE_ARRAY
#undef VEXCL_INIT_ARRAY
#undef VEXCL_PRINT_PARAM

#endif

struct column_owner {
    const std::vector<size_t> ∂

    column_owner(const std::vector<size_t> &part) : part(part) {}

    size_t operator()(size_t c) const {
        return std::upper_bound(part.begin(), part.end(), c)
            - part.begin() - 1;
    }
};

} // namespace vex

#endif
<commit_msg>Check that _VARIADIC_MAX is at least 10<commit_after>#ifndef VEXCL_UTIL_HPP
#define VEXCL_UTIL_HPP

/*
The MIT License

Copyright (c) 2012-2014 Denis Demidov <dennis.demidov@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
 * \file   vexcl/util.hpp
 * \author Denis Demidov <dennis.demidov@gmail.com>
 * \brief  OpenCL general utilities.
 */

#if defined(_MSC_VER)
#  if defined(min) || defined(max)
#    error Please define NOMINMAX macro globally in your project
#  endif
#  if defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 10)
#    error Please define _VARIADIC_MAX=10 or greater in your project
#  endif
#endif

#include <iostream>
#include <string>
#include <vector>
#include <array>
#include <tuple>
#include <map>
#include <stdexcept>
#include <algorithm>
#include <type_traits>

#include <boost/config.hpp>

#ifdef BOOST_NO_VARIADIC_TEMPLATES
#  include <boost/proto/proto.hpp>
#  include <boost/preprocessor/repetition.hpp>
#  ifndef VEXCL_MAX_ARITY
#    define VEXCL_MAX_ARITY BOOST_PROTO_MAX_ARITY
#  endif
#endif

namespace vex {

/// Check run-time condition.
/** Throws std::runtime_error if condition is false */
template <class Condition, class Message>
inline void precondition(const Condition &condition, const Message &fail_message) {
#ifdef _MSC_VER
#  pragma warning(push)
#  pragma warning(disable: 4800)
#endif
    if (!condition) throw std::runtime_error(fail_message);
#ifdef _MSC_VER
#  pragma warning(pop)
#endif
}

/// Return next power of 2.
inline size_t nextpow2(size_t x) {
    --x;
    x |= x >> 1U;
    x |= x >> 2U;
    x |= x >> 4U;
    x |= x >> 8U;
    x |= x >> 16U;
    return ++x;
}

/// Align n to the next multiple of m.
inline size_t alignup(size_t n, size_t m = 16U) {
    return (n + m - 1) / m * m;
}

template <class T>
struct is_tuple : std::false_type {};

#ifndef BOOST_NO_VARIADIC_TEMPLATES

template <class... Elem>
struct is_tuple < std::tuple<Elem...> > : std::true_type {};

#else

#define VEXCL_IS_TUPLE(z, n, unused)                                           \
  template <BOOST_PP_ENUM_PARAMS(n, class Elem)>                               \
  struct is_tuple<                                                             \
      std::tuple<BOOST_PP_ENUM_PARAMS(n, Elem)> > : std::true_type {           \
  };

BOOST_PP_REPEAT_FROM_TO(1, VEXCL_MAX_ARITY, VEXCL_IS_TUPLE, ~)

#undef VEXCL_IS_TUPLE

#endif

#ifndef BOOST_NO_VARIADIC_TEMPLATES
/// Create std::array from arguments
template <class T, class... Tail>
std::array<T, 1 + sizeof...(Tail)>
make_array(T t, Tail... tail) {
    std::array<T, 1 + sizeof...(Tail)> a = {{t, static_cast<T>(tail)...}};
    return a;
}
#else

#define VEXCL_PRINT_PARAM(z, n, data) T ## n t ## n
#define VEXCL_INIT_ARRAY(z, n, data) static_cast<T0>(t ## n)
#define VEXCL_MAKE_ARRAY(z, n, data)                                           \
  template <BOOST_PP_ENUM_PARAMS(n, class T)>                                  \
  std::array<T0, n> make_array(BOOST_PP_ENUM(n, VEXCL_PRINT_PARAM, ~)) {       \
    std::array<T0, n> a = { { BOOST_PP_ENUM(n, VEXCL_INIT_ARRAY, ~) } };       \
    return a;                                                                  \
  }

BOOST_PP_REPEAT_FROM_TO(1, VEXCL_MAX_ARITY, VEXCL_MAKE_ARRAY, ~)

#undef VEXCL_MAKE_ARRAY
#undef VEXCL_INIT_ARRAY
#undef VEXCL_PRINT_PARAM

#endif

struct column_owner {
    const std::vector<size_t> ∂

    column_owner(const std::vector<size_t> &part) : part(part) {}

    size_t operator()(size_t c) const {
        return std::upper_bound(part.begin(), part.end(), c)
            - part.begin() - 1;
    }
};

} // namespace vex

#endif
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2010-2011 Dmitry Marakasov
 *
 * This file is part of glosm.
 *
 * glosm is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * glosm 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with glosm.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <err.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

#if defined(__APPLE__)
#	include <OpenGL/gl.h>
#	include <GLUT/glut.h>
#else
#	include <GL/gl.h>
#	include <GL/glut.h>
#endif

#include <vector>
#include <map>

#include <glosm/geomath.h>

#include <glosm/Math.hh>

#include <glosm/SphericalProjection.hh>
#include <glosm/MercatorProjection.hh>
#include <glosm/PreloadedXmlDatasource.hh>
#include <glosm/GeometryGenerator.hh>
#include <glosm/FirstPersonViewer.hh>
#include <glosm/GeometryLayer.hh>

/* as glut has no OO concept and no feature like setUserData,
 * please forgive me using global variables pointing to
 * stack data for now */
FirstPersonViewer viewer;
GeometryLayer* layer_p = NULL;

int screenw = 1;
int screenh = 1;
int movementflags = 0;
float speed = 200.0f;
int lockheight = 0;

struct timeval prevtime, curtime, fpstime;
int nframes = 0;

/* stuff that may eb changed with args */
Projection proj = MercatorProjection();
int tilelevel = -1;

void Display(void) {
	/* update scene */
	gettimeofday(&curtime, NULL);
	float dt = (float)(curtime.tv_sec - prevtime.tv_sec) + (float)(curtime.tv_usec - prevtime.tv_usec)/1000000.0f;

	/* render frame */
	glClearColor(0.5, 0.5, 0.5, 0.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	if (layer_p) {
		if (tilelevel >= 0) {
			int radius = 5000000;
			layer_p->RequestVisible(BBoxi(viewer.GetPos(MercatorProjection()) - Vector2i(radius, radius), viewer.GetPos(MercatorProjection()) + Vector2i(radius, radius)), 0);
			layer_p->GarbageCollect();
		}
		layer_p->Render(viewer);
	}

	glFlush();
	glutSwapBuffers();

	/* movement */
	if (movementflags) {
		float myspeed = speed;
		float height = viewer.MutablePos().z / GEOM_UNITSINMETER;

		/* don't scale down under 100 meters */
		if (height > 100.0)
			myspeed *= height / 100.0;

		viewer.Move(movementflags, myspeed, dt);
	}
	if (lockheight != 0)
		viewer.MutablePos().z = lockheight;

	/* update FPS */
	float fpst = (float)(curtime.tv_sec - fpstime.tv_sec) + (float)(curtime.tv_usec - fpstime.tv_usec)/1000000.0f;

	if (fpst > 10.0) {
		fprintf(stderr, "FPS: %.3f\n", (float)nframes/fpst);
		fpstime = curtime;
		nframes = 0;
	}

	prevtime = curtime;
	nframes++;

	/* frame limiter */
	usleep(10000);
}

void Reshape(int w, int h) {
	if (w <= 0)
		w = 1;
	if (h <= 0)
		h = 1;

	screenw = w;
	screenh = h;

	float wanted_fov = 70.0f/180.0f*M_PI;
	float wanted_aspect = 4.0f/3.0f;

	float fov, aspect;

	if ((float)w/(float)h > wanted_aspect) { // wider than wanted
		fov = wanted_fov;
	} else { // narrower than wanted
		float wanted_h = (float)w/wanted_aspect;
		fov = 2.0f*atanf((float)h / wanted_h * tanf(wanted_fov/2.0f));
	}
	fov = wanted_fov;
	aspect = (float)w/(float)h;

	glViewport(0, 0, w, h);

	viewer.SetFov(fov);
	viewer.SetAspect(aspect);

	glutWarpPointer(screenw/2, screenh/2);
}

void Mouse(int x, int y) {
	int dx = x - screenw/2;
	int dy = y - screenh/2;

	float YawDelta = (float)dx / 500.0;
	float PitchDelta = -(float)dy / 500.0;

	viewer.HardRotate(YawDelta, PitchDelta);

	if (dx != 0 || dy != 0)
		glutWarpPointer(screenw/2, screenh/2);
}

void SpecialDown(int key, int, int) {
	switch (key) {
	case GLUT_KEY_UP: movementflags |= FirstPersonViewer::FORWARD; break;
	case GLUT_KEY_DOWN: movementflags |= FirstPersonViewer::BACKWARD; break;
	case GLUT_KEY_LEFT: movementflags |= FirstPersonViewer::LEFT; break;
	case GLUT_KEY_RIGHT: movementflags |= FirstPersonViewer::RIGHT; break;
	default:
		break;
	}
}

void SpecialUp(int key, int, int) {
	switch (key) {
	case GLUT_KEY_UP: movementflags &= ~FirstPersonViewer::FORWARD; break;
	case GLUT_KEY_DOWN: movementflags &= ~FirstPersonViewer::BACKWARD; break;
	case GLUT_KEY_LEFT: movementflags &= ~FirstPersonViewer::LEFT; break;
	case GLUT_KEY_RIGHT: movementflags &= ~FirstPersonViewer::RIGHT; break;
	default:
		break;
	}
}

void KeyDown(unsigned char key, int, int) {
	switch (key) {
	case 27: case 'q': exit(0); break;
	case 'w': movementflags |= FirstPersonViewer::FORWARD; break;
	case 's': movementflags |= FirstPersonViewer::BACKWARD; break;
	case 'a': movementflags |= FirstPersonViewer::LEFT; break;
	case 'd': movementflags |= FirstPersonViewer::RIGHT; break;
	case 'c': movementflags |= FirstPersonViewer::LOWER; break;
	case ' ': movementflags |= FirstPersonViewer::HIGHER; break;
	case 'l': lockheight = (lockheight == 0 ? viewer.MutablePos().z : 0); break;
	case 'h': lockheight = (lockheight == 0 ? 1750 : 0); break;
	case '+': speed *= 5.0f; break;
	case '-': speed /= 5.0f; break;
	default:
		break;
	}
}

void KeyUp(unsigned char key, int, int) {
	switch (key) {
	case 'w': movementflags &= ~FirstPersonViewer::FORWARD; break;
	case 's': movementflags &= ~FirstPersonViewer::BACKWARD; break;
	case 'a': movementflags &= ~FirstPersonViewer::LEFT; break;
	case 'd': movementflags &= ~FirstPersonViewer::RIGHT; break;
	case 'c': movementflags &= ~FirstPersonViewer::LOWER; break;
	case ' ': movementflags &= ~FirstPersonViewer::HIGHER; break;
	default:
		break;
	}
}

void usage(const char* progname) {
	fprintf(stderr, "Usage: %s [-s] file.osm\n", progname);
	exit(1);
}

int real_main(int argc, char** argv) {
	glutInit(&argc, argv);

	/* argument parsing */
	int c;
	const char* progname = argv[0];
	while ((c = getopt(argc, argv, "st:")) != -1) {
		switch (c) {
		case 's': proj = SphericalProjection(); break;
		case 't': tilelevel = strtol(optarg, NULL, 10); break;
		default:
			usage(progname);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc != 1)
		usage(progname);

	/* load data */
	fprintf(stderr, "Loading...\n");
	PreloadedXmlDatasource osm_datasource;
	gettimeofday(&prevtime, NULL);
	osm_datasource.Load(argv[0]);
	gettimeofday(&curtime, NULL);
	fprintf(stderr, "Loaded XML in %.3f seconds\n", (float)(curtime.tv_sec - prevtime.tv_sec) + (float)(curtime.tv_usec - prevtime.tv_usec)/1000000.0f);
	prevtime = curtime;
	fpstime = curtime;

	/* glut init */
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA | GLUT_MULTISAMPLE);
	glutInitWindowSize(800, 600);
	glutCreateWindow("glosm viewer");

	glutIgnoreKeyRepeat(1);
	glutSetCursor(GLUT_CURSOR_NONE);

	glutDisplayFunc(Display);
	glutIdleFunc(Display);
	glutReshapeFunc(Reshape);
	glutPassiveMotionFunc(Mouse);
	glutKeyboardFunc(KeyDown);
	glutKeyboardUpFunc(KeyUp);
	glutSpecialFunc(SpecialDown);
	glutSpecialUpFunc(SpecialUp);

	/* glosm init */
	GeometryGenerator geometry_generator(osm_datasource);
	GeometryLayer layer(proj, geometry_generator);
	if (tilelevel >= 0)
		layer.SetTargetLevel(tilelevel);
	else
		layer.RequestVisible(geometry_generator.GetBBox(), TileManager::EXPLICIT);
	layer_p = &layer;

	int height = fabs((float)geometry_generator.GetBBox().top - (float)geometry_generator.GetBBox().bottom) / GEOM_LONSPAN * WGS84_EARTH_EQ_LENGTH * GEOM_UNITSINMETER / 10.0;
	viewer.SetPos(Vector3i(geometry_generator.GetCenter(), height));
	viewer.HardRotate(0, -M_PI_4);

	/* main loop */
	/* note that this never returns and objects created above
	 * are never properly destroyed; should dump GLUT ASAP */
	glutMainLoop();

	return 0;
}

int main(int argc, char** argv) {
	try {
		return real_main(argc, argv);
	} catch (std::exception &e) {
		fprintf(stderr, "Exception: %s\n", e.what());
	} catch (...) {
		fprintf(stderr, "Unknown exception\n");
	}

	return 1;
}
<commit_msg>Remove unused include<commit_after>/*
 * Copyright (C) 2010-2011 Dmitry Marakasov
 *
 * This file is part of glosm.
 *
 * glosm is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * glosm 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with glosm.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

#if defined(__APPLE__)
#	include <OpenGL/gl.h>
#	include <GLUT/glut.h>
#else
#	include <GL/gl.h>
#	include <GL/glut.h>
#endif

#include <vector>
#include <map>

#include <glosm/geomath.h>

#include <glosm/Math.hh>

#include <glosm/SphericalProjection.hh>
#include <glosm/MercatorProjection.hh>
#include <glosm/PreloadedXmlDatasource.hh>
#include <glosm/GeometryGenerator.hh>
#include <glosm/FirstPersonViewer.hh>
#include <glosm/GeometryLayer.hh>

/* as glut has no OO concept and no feature like setUserData,
 * please forgive me using global variables pointing to
 * stack data for now */
FirstPersonViewer viewer;
GeometryLayer* layer_p = NULL;

int screenw = 1;
int screenh = 1;
int movementflags = 0;
float speed = 200.0f;
int lockheight = 0;

struct timeval prevtime, curtime, fpstime;
int nframes = 0;

/* stuff that may eb changed with args */
Projection proj = MercatorProjection();
int tilelevel = -1;

void Display(void) {
	/* update scene */
	gettimeofday(&curtime, NULL);
	float dt = (float)(curtime.tv_sec - prevtime.tv_sec) + (float)(curtime.tv_usec - prevtime.tv_usec)/1000000.0f;

	/* render frame */
	glClearColor(0.5, 0.5, 0.5, 0.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	if (layer_p) {
		if (tilelevel >= 0) {
			int radius = 5000000;
			layer_p->RequestVisible(BBoxi(viewer.GetPos(MercatorProjection()) - Vector2i(radius, radius), viewer.GetPos(MercatorProjection()) + Vector2i(radius, radius)), 0);
			layer_p->GarbageCollect();
		}
		layer_p->Render(viewer);
	}

	glFlush();
	glutSwapBuffers();

	/* movement */
	if (movementflags) {
		float myspeed = speed;
		float height = viewer.MutablePos().z / GEOM_UNITSINMETER;

		/* don't scale down under 100 meters */
		if (height > 100.0)
			myspeed *= height / 100.0;

		viewer.Move(movementflags, myspeed, dt);
	}
	if (lockheight != 0)
		viewer.MutablePos().z = lockheight;

	/* update FPS */
	float fpst = (float)(curtime.tv_sec - fpstime.tv_sec) + (float)(curtime.tv_usec - fpstime.tv_usec)/1000000.0f;

	if (fpst > 10.0) {
		fprintf(stderr, "FPS: %.3f\n", (float)nframes/fpst);
		fpstime = curtime;
		nframes = 0;
	}

	prevtime = curtime;
	nframes++;

	/* frame limiter */
	usleep(10000);
}

void Reshape(int w, int h) {
	if (w <= 0)
		w = 1;
	if (h <= 0)
		h = 1;

	screenw = w;
	screenh = h;

	float wanted_fov = 70.0f/180.0f*M_PI;
	float wanted_aspect = 4.0f/3.0f;

	float fov, aspect;

	if ((float)w/(float)h > wanted_aspect) { // wider than wanted
		fov = wanted_fov;
	} else { // narrower than wanted
		float wanted_h = (float)w/wanted_aspect;
		fov = 2.0f*atanf((float)h / wanted_h * tanf(wanted_fov/2.0f));
	}
	fov = wanted_fov;
	aspect = (float)w/(float)h;

	glViewport(0, 0, w, h);

	viewer.SetFov(fov);
	viewer.SetAspect(aspect);

	glutWarpPointer(screenw/2, screenh/2);
}

void Mouse(int x, int y) {
	int dx = x - screenw/2;
	int dy = y - screenh/2;

	float YawDelta = (float)dx / 500.0;
	float PitchDelta = -(float)dy / 500.0;

	viewer.HardRotate(YawDelta, PitchDelta);

	if (dx != 0 || dy != 0)
		glutWarpPointer(screenw/2, screenh/2);
}

void SpecialDown(int key, int, int) {
	switch (key) {
	case GLUT_KEY_UP: movementflags |= FirstPersonViewer::FORWARD; break;
	case GLUT_KEY_DOWN: movementflags |= FirstPersonViewer::BACKWARD; break;
	case GLUT_KEY_LEFT: movementflags |= FirstPersonViewer::LEFT; break;
	case GLUT_KEY_RIGHT: movementflags |= FirstPersonViewer::RIGHT; break;
	default:
		break;
	}
}

void SpecialUp(int key, int, int) {
	switch (key) {
	case GLUT_KEY_UP: movementflags &= ~FirstPersonViewer::FORWARD; break;
	case GLUT_KEY_DOWN: movementflags &= ~FirstPersonViewer::BACKWARD; break;
	case GLUT_KEY_LEFT: movementflags &= ~FirstPersonViewer::LEFT; break;
	case GLUT_KEY_RIGHT: movementflags &= ~FirstPersonViewer::RIGHT; break;
	default:
		break;
	}
}

void KeyDown(unsigned char key, int, int) {
	switch (key) {
	case 27: case 'q': exit(0); break;
	case 'w': movementflags |= FirstPersonViewer::FORWARD; break;
	case 's': movementflags |= FirstPersonViewer::BACKWARD; break;
	case 'a': movementflags |= FirstPersonViewer::LEFT; break;
	case 'd': movementflags |= FirstPersonViewer::RIGHT; break;
	case 'c': movementflags |= FirstPersonViewer::LOWER; break;
	case ' ': movementflags |= FirstPersonViewer::HIGHER; break;
	case 'l': lockheight = (lockheight == 0 ? viewer.MutablePos().z : 0); break;
	case 'h': lockheight = (lockheight == 0 ? 1750 : 0); break;
	case '+': speed *= 5.0f; break;
	case '-': speed /= 5.0f; break;
	default:
		break;
	}
}

void KeyUp(unsigned char key, int, int) {
	switch (key) {
	case 'w': movementflags &= ~FirstPersonViewer::FORWARD; break;
	case 's': movementflags &= ~FirstPersonViewer::BACKWARD; break;
	case 'a': movementflags &= ~FirstPersonViewer::LEFT; break;
	case 'd': movementflags &= ~FirstPersonViewer::RIGHT; break;
	case 'c': movementflags &= ~FirstPersonViewer::LOWER; break;
	case ' ': movementflags &= ~FirstPersonViewer::HIGHER; break;
	default:
		break;
	}
}

void usage(const char* progname) {
	fprintf(stderr, "Usage: %s [-s] file.osm\n", progname);
	exit(1);
}

int real_main(int argc, char** argv) {
	glutInit(&argc, argv);

	/* argument parsing */
	int c;
	const char* progname = argv[0];
	while ((c = getopt(argc, argv, "st:")) != -1) {
		switch (c) {
		case 's': proj = SphericalProjection(); break;
		case 't': tilelevel = strtol(optarg, NULL, 10); break;
		default:
			usage(progname);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc != 1)
		usage(progname);

	/* load data */
	fprintf(stderr, "Loading...\n");
	PreloadedXmlDatasource osm_datasource;
	gettimeofday(&prevtime, NULL);
	osm_datasource.Load(argv[0]);
	gettimeofday(&curtime, NULL);
	fprintf(stderr, "Loaded XML in %.3f seconds\n", (float)(curtime.tv_sec - prevtime.tv_sec) + (float)(curtime.tv_usec - prevtime.tv_usec)/1000000.0f);
	prevtime = curtime;
	fpstime = curtime;

	/* glut init */
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA | GLUT_MULTISAMPLE);
	glutInitWindowSize(800, 600);
	glutCreateWindow("glosm viewer");

	glutIgnoreKeyRepeat(1);
	glutSetCursor(GLUT_CURSOR_NONE);

	glutDisplayFunc(Display);
	glutIdleFunc(Display);
	glutReshapeFunc(Reshape);
	glutPassiveMotionFunc(Mouse);
	glutKeyboardFunc(KeyDown);
	glutKeyboardUpFunc(KeyUp);
	glutSpecialFunc(SpecialDown);
	glutSpecialUpFunc(SpecialUp);

	/* glosm init */
	GeometryGenerator geometry_generator(osm_datasource);
	GeometryLayer layer(proj, geometry_generator);
	if (tilelevel >= 0)
		layer.SetTargetLevel(tilelevel);
	else
		layer.RequestVisible(geometry_generator.GetBBox(), TileManager::EXPLICIT);
	layer_p = &layer;

	int height = fabs((float)geometry_generator.GetBBox().top - (float)geometry_generator.GetBBox().bottom) / GEOM_LONSPAN * WGS84_EARTH_EQ_LENGTH * GEOM_UNITSINMETER / 10.0;
	viewer.SetPos(Vector3i(geometry_generator.GetCenter(), height));
	viewer.HardRotate(0, -M_PI_4);

	/* main loop */
	/* note that this never returns and objects created above
	 * are never properly destroyed; should dump GLUT ASAP */
	glutMainLoop();

	return 0;
}

int main(int argc, char** argv) {
	try {
		return real_main(argc, argv);
	} catch (std::exception &e) {
		fprintf(stderr, "Exception: %s\n", e.what());
	} catch (...) {
		fprintf(stderr, "Unknown exception\n");
	}

	return 1;
}
<|endoftext|>


<commit_before>/*
    Copyright (C) 2016 Volker Krause <vkrause@kde.org>

    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This program 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 Library General Public
    License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "syntaxhighlighter.h"
#include "abstracthighlighter_p.h"
#include "definition.h"
#include "foldingregion.h"
#include "format.h"
#include "state.h"
#include "theme.h"

#include <QDebug>

Q_DECLARE_METATYPE(QTextBlock)

using namespace KSyntaxHighlighting;

namespace KSyntaxHighlighting {
class TextBlockUserData : public QTextBlockUserData
{
public:
    State state;
    QVector<FoldingRegion> foldingRegions;
};

class SyntaxHighlighterPrivate : public AbstractHighlighterPrivate
{
public:
    static FoldingRegion foldingRegion(const QTextBlock &startBlock);
    QVector<FoldingRegion> foldingRegions;
};

}

FoldingRegion SyntaxHighlighterPrivate::foldingRegion(const QTextBlock& startBlock)
{
    const auto data = dynamic_cast<TextBlockUserData*>(startBlock.userData());
    if (!data)
        return FoldingRegion();
    for (int i = data->foldingRegions.size() - 1; i >= 0; --i) {
        if (data->foldingRegions.at(i).type() == FoldingRegion::Begin)
            return data->foldingRegions.at(i);
    }
    return FoldingRegion();
}

SyntaxHighlighter::SyntaxHighlighter(QObject* parent) :
    QSyntaxHighlighter(parent),
    AbstractHighlighter(new SyntaxHighlighterPrivate)
{
    qRegisterMetaType<QTextBlock>();
}

SyntaxHighlighter::SyntaxHighlighter(QTextDocument *document) :
    QSyntaxHighlighter(document),
    AbstractHighlighter(new SyntaxHighlighterPrivate)
{
    qRegisterMetaType<QTextBlock>();
}

SyntaxHighlighter::~SyntaxHighlighter()
{
}

void SyntaxHighlighter::setDefinition(const Definition& def)
{
    const auto needsRehighlight = definition() != def;
    AbstractHighlighter::setDefinition(def);
    if (needsRehighlight)
        rehighlight();
}

bool SyntaxHighlighter::startsFoldingRegion(const QTextBlock &startBlock) const
{
    return SyntaxHighlighterPrivate::foldingRegion(startBlock).type() == FoldingRegion::Begin;
}

QTextBlock SyntaxHighlighter::findFoldingRegionEnd(const QTextBlock &startBlock) const
{
    const auto region = SyntaxHighlighterPrivate::foldingRegion(startBlock);

    auto block = startBlock;
    int depth = 1;
    while (block.isValid()) {
        block = block.next();
        const auto data = dynamic_cast<TextBlockUserData*>(block.userData());
        if (!data)
            continue;
        for (auto it = data->foldingRegions.constBegin(); it != data->foldingRegions.constEnd(); ++it) {
            if ((*it).id() != region.id())
                continue;
            if ((*it).type() == FoldingRegion::End)
                --depth;
            else if ((*it).type() == FoldingRegion::Begin)
                ++depth;
            if (depth == 0)
                return block;
        }
    }

    return QTextBlock();
}

void SyntaxHighlighter::highlightBlock(const QString& text)
{
    Q_D(SyntaxHighlighter);

    State state;
    if (currentBlock().position() > 0) {
        const auto prevBlock = currentBlock().previous();
        const auto prevData = dynamic_cast<TextBlockUserData*>(prevBlock.userData());
        if (prevData)
            state = prevData->state;
    }
    d->foldingRegions.clear();
    state = highlightLine(text, state);

    auto data = dynamic_cast<TextBlockUserData*>(currentBlockUserData());
    if (!data) { // first time we highlight this
        data = new TextBlockUserData;
        data->state = state;
        data->foldingRegions = d->foldingRegions;
        setCurrentBlockUserData(data);
        return;
    }

    if (data->state == state && data->foldingRegions == d->foldingRegions) // we ended up in the same state, so we are done here
        return;
    data->state = state;
    data->foldingRegions = d->foldingRegions;

    const auto nextBlock = currentBlock().next();
    if (nextBlock.isValid())
        QMetaObject::invokeMethod(this, "rehighlightBlock", Qt::QueuedConnection, Q_ARG(QTextBlock, nextBlock));
}

void SyntaxHighlighter::applyFormat(int offset, int length, const KSyntaxHighlighting::Format& format)
{
    if (format.isDefaultTextStyle(theme()) || length == 0)
        return;

    QTextCharFormat tf;
    if (format.hasTextColor(theme()))
        tf.setForeground(format.textColor(theme()));
    if (format.hasBackgroundColor(theme()))
        tf.setBackground(format.backgroundColor(theme()));

    if (format.isBold(theme()))
        tf.setFontWeight(QFont::Bold);
    if (format.isItalic(theme()))
        tf.setFontItalic(true);
    if (format.isUnderline(theme()))
        tf.setFontUnderline(true);
    if (format.isStrikeThrough(theme()))
        tf.setFontStrikeOut(true);

    QSyntaxHighlighter::setFormat(offset, length, tf);
}

void SyntaxHighlighter::applyFolding(int offset, int length, FoldingRegion region)
{
    Q_UNUSED(offset);
    Q_UNUSED(length);
    Q_D(SyntaxHighlighter);

    if (region.type() == FoldingRegion::Begin)
        d->foldingRegions.push_back(region);

    if (region.type() == FoldingRegion::End) {
        for (int i = d->foldingRegions.size() - 1; i >= 0; --i) {
            if (d->foldingRegions.at(i).id() != region.id() || d->foldingRegions.at(i).type() != FoldingRegion::End)
                continue;
            d->foldingRegions.remove(i);
            return;
        }
        d->foldingRegions.push_back(region);
    }
}
<commit_msg>Fix folding region merging<commit_after>/*
    Copyright (C) 2016 Volker Krause <vkrause@kde.org>

    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This program 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 Library General Public
    License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "syntaxhighlighter.h"
#include "abstracthighlighter_p.h"
#include "definition.h"
#include "foldingregion.h"
#include "format.h"
#include "state.h"
#include "theme.h"

#include <QDebug>

Q_DECLARE_METATYPE(QTextBlock)

using namespace KSyntaxHighlighting;

namespace KSyntaxHighlighting {
class TextBlockUserData : public QTextBlockUserData
{
public:
    State state;
    QVector<FoldingRegion> foldingRegions;
};

class SyntaxHighlighterPrivate : public AbstractHighlighterPrivate
{
public:
    static FoldingRegion foldingRegion(const QTextBlock &startBlock);
    QVector<FoldingRegion> foldingRegions;
};

}

FoldingRegion SyntaxHighlighterPrivate::foldingRegion(const QTextBlock& startBlock)
{
    const auto data = dynamic_cast<TextBlockUserData*>(startBlock.userData());
    if (!data)
        return FoldingRegion();
    for (int i = data->foldingRegions.size() - 1; i >= 0; --i) {
        if (data->foldingRegions.at(i).type() == FoldingRegion::Begin)
            return data->foldingRegions.at(i);
    }
    return FoldingRegion();
}

SyntaxHighlighter::SyntaxHighlighter(QObject* parent) :
    QSyntaxHighlighter(parent),
    AbstractHighlighter(new SyntaxHighlighterPrivate)
{
    qRegisterMetaType<QTextBlock>();
}

SyntaxHighlighter::SyntaxHighlighter(QTextDocument *document) :
    QSyntaxHighlighter(document),
    AbstractHighlighter(new SyntaxHighlighterPrivate)
{
    qRegisterMetaType<QTextBlock>();
}

SyntaxHighlighter::~SyntaxHighlighter()
{
}

void SyntaxHighlighter::setDefinition(const Definition& def)
{
    const auto needsRehighlight = definition() != def;
    AbstractHighlighter::setDefinition(def);
    if (needsRehighlight)
        rehighlight();
}

bool SyntaxHighlighter::startsFoldingRegion(const QTextBlock &startBlock) const
{
    return SyntaxHighlighterPrivate::foldingRegion(startBlock).type() == FoldingRegion::Begin;
}

QTextBlock SyntaxHighlighter::findFoldingRegionEnd(const QTextBlock &startBlock) const
{
    const auto region = SyntaxHighlighterPrivate::foldingRegion(startBlock);

    auto block = startBlock;
    int depth = 1;
    while (block.isValid()) {
        block = block.next();
        const auto data = dynamic_cast<TextBlockUserData*>(block.userData());
        if (!data)
            continue;
        for (auto it = data->foldingRegions.constBegin(); it != data->foldingRegions.constEnd(); ++it) {
            if ((*it).id() != region.id())
                continue;
            if ((*it).type() == FoldingRegion::End)
                --depth;
            else if ((*it).type() == FoldingRegion::Begin)
                ++depth;
            if (depth == 0)
                return block;
        }
    }

    return QTextBlock();
}

void SyntaxHighlighter::highlightBlock(const QString& text)
{
    Q_D(SyntaxHighlighter);

    State state;
    if (currentBlock().position() > 0) {
        const auto prevBlock = currentBlock().previous();
        const auto prevData = dynamic_cast<TextBlockUserData*>(prevBlock.userData());
        if (prevData)
            state = prevData->state;
    }
    d->foldingRegions.clear();
    state = highlightLine(text, state);

    auto data = dynamic_cast<TextBlockUserData*>(currentBlockUserData());
    if (!data) { // first time we highlight this
        data = new TextBlockUserData;
        data->state = state;
        data->foldingRegions = d->foldingRegions;
        setCurrentBlockUserData(data);
        return;
    }

    if (data->state == state && data->foldingRegions == d->foldingRegions) // we ended up in the same state, so we are done here
        return;
    data->state = state;
    data->foldingRegions = d->foldingRegions;

    const auto nextBlock = currentBlock().next();
    if (nextBlock.isValid())
        QMetaObject::invokeMethod(this, "rehighlightBlock", Qt::QueuedConnection, Q_ARG(QTextBlock, nextBlock));
}

void SyntaxHighlighter::applyFormat(int offset, int length, const KSyntaxHighlighting::Format& format)
{
    if (format.isDefaultTextStyle(theme()) || length == 0)
        return;

    QTextCharFormat tf;
    if (format.hasTextColor(theme()))
        tf.setForeground(format.textColor(theme()));
    if (format.hasBackgroundColor(theme()))
        tf.setBackground(format.backgroundColor(theme()));

    if (format.isBold(theme()))
        tf.setFontWeight(QFont::Bold);
    if (format.isItalic(theme()))
        tf.setFontItalic(true);
    if (format.isUnderline(theme()))
        tf.setFontUnderline(true);
    if (format.isStrikeThrough(theme()))
        tf.setFontStrikeOut(true);

    QSyntaxHighlighter::setFormat(offset, length, tf);
}

void SyntaxHighlighter::applyFolding(int offset, int length, FoldingRegion region)
{
    Q_UNUSED(offset);
    Q_UNUSED(length);
    Q_D(SyntaxHighlighter);

    if (region.type() == FoldingRegion::Begin)
        d->foldingRegions.push_back(region);

    if (region.type() == FoldingRegion::End) {
        for (int i = d->foldingRegions.size() - 1; i >= 0; --i) {
            if (d->foldingRegions.at(i).id() != region.id() || d->foldingRegions.at(i).type() != FoldingRegion::Begin)
                continue;
            d->foldingRegions.remove(i);
            return;
        }
        d->foldingRegions.push_back(region);
    }
}
<|endoftext|>