<commit_before>///
/// @file  pmath.hpp
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#ifndef PMATH_HPP
#define PMATH_HPP

#include <stdint.h>
#include <algorithm>
#include <limits>
#include <cassert>
#include <cmath>
#include <vector>

#if __cplusplus >= 201103L
#include <type_traits>
#endif

namespace primecount {

/// Convenience min function for different types.
/// @pre numeric_limits<A>::max() >= numeric_limits<B>::max(),
///      a >= 0, b >= 0.
///
template <typename A, typename B>
inline B min(A a, B b)
{
#if __cplusplus >= 201103L
  static_assert(std::numeric_limits<A>::max() >= std::numeric_limits<B>::max(),
                "max(type A) must not be < max(type B)");

  // a < (unsigned) b, is correct only if b >= 0
  assert(std::is_unsigned<B>::value || (
         std::make_signed<B>::type) b >= 0);
#endif
  return (B) std::min(a, (A) b);
}

/// Convenience min function for different types.
/// @pre numeric_limits<A>::max() >= numeric_limits<B>::max(),
///      a >= 0, b >= 0.
///
template <typename A, typename B>
inline B min3(A a, B b, B c)
{
#if __cplusplus >= 201103L
  static_assert(std::numeric_limits<A>::max() >= std::numeric_limits<B>::max(),
                "max(type A) must not be < max(type B)");
#endif
  return (B) std::min(a, (A) std::min(b, c));
}

/// Convenience max function for different types.
/// @pre numeric_limits<A>::max() >= numeric_limits<B>::max(),
///      a >= 0, b >= 0.
///
template <typename A, typename B>
inline A max(A a, B b)
{
#if __cplusplus >= 201103L
  static_assert(std::numeric_limits<A>::max() >= std::numeric_limits<B>::max(),
                "max(type A) must not be < max(type B)");

  // a > (unsigned) b, is correct only if b >= 0
  assert(std::is_unsigned<B>::value || (
         std::make_signed<B>::type) b >= 0);
#endif
  return std::max(a, (A) b);
}

/// Convenience max function for different types.
/// @pre numeric_limits<A>::max() >= numeric_limits<B>::max(),
///      a >= 0, b >= 0.
///
template <typename A, typename B>
inline A max3(A a, B b, B c)
{
#if __cplusplus >= 201103L
  static_assert(std::numeric_limits<A>::max() >= std::numeric_limits<B>::max(),
                "max(type A) must not be < max(type B)");
#endif
  return std::max(a, (A) std::max(b, c));
}

inline int64_t isquare(int32_t x)
{
  return x * (int64_t) x;
}

template <typename A, typename B>
inline A ceil_div(A a, B b)
{
  assert(b > 0);
  return (A) ((a + b - 1) / b);
}

template <typename T>
inline T number_of_bits(T)
{
  return (T) (sizeof(T) * 8);
}

/// @brief  Check if an integer is a power of 2.
/// @see    Book "Hacker's Delight".
///
template <typename T>
inline bool is_power_of_2(T x)
{
  return (x != 0 && (x & (x - 1)) == 0);
}

/// @brief  Round up to the next power of 2.
/// @see    Book "Hacker's Delight".
///
template <typename T>
inline T next_power_of_2(T x)
{
  if (x == 0)
    return 1;

  x--;
  for (T i = 1; i < number_of_bits(x); i += i)
    x |= (x >> i);

  return ++x;
}

template <typename T>
inline int ilog(T x)
{
  return (int) std::log((double) x);
}

/// Raise to power
template <typename T>
inline T ipow(T x, int n)
{
  T r = 1;
  for (int i = 0; i < n; i++)
    r *= x;

  return r;
}

/// Integer suare root
template <typename T>
inline T isqrt(T x)
{
  T r = (T) std::sqrt((double) x);
  r = std::min(r, (T) std::numeric_limits<T>::max() >> (sizeof(T) / 2));

  while (r * r > x)
    r--;
  while (x - r * r > r * 2)
    r++;
  return r;
}

/// Check if ipow(x, n) <= limit
template <typename T>
inline bool ipow_less_equal(T x, int n, T limit)
{
  if (limit <= 0)
    return false;

  for (T r = 1; n > 0; n--, r *= x)
    if (r > limit / x)
      return false;

  return true;
}

/// Integer nth root
template <int N, typename T>
inline T iroot(T x)
{
  T r = (T) std::pow((double) x, 1.0 / N);
  while (ipow(r, N) > x)
    r--;
  while (ipow_less_equal(r + 1, N, x))
    r++;
  return r;
}

/// Calculate the number of primes below x using binary search.
/// @pre primes[1] = 2, primes[3] = 3, ...
/// @pre x <= primes.back()
///
template <typename T1, typename T2>
inline T2 pi_bsearch(const std::vector<T1>& primes, T2 x)
{
  // primecount uses 1-indexing
  assert(primes[0] == 0);
  return (T2) (std::upper_bound(primes.begin() + 1, primes.end(), x)
      - (primes.begin() + 1));
}

/// Calculate the number of primes below x using binary search.
/// @pre primes[1] = 2, primes[3] = 3, ...
/// @pre x <= primes.back()
///
template <typename T1, typename T2, typename T3>
inline T3 pi_bsearch(const std::vector<T1>& primes, T2 len, T3 x)
{
  // primecount uses 1-indexing
  assert(primes[0] == 0);
  return (T3) (std::upper_bound(primes.begin() + 1, primes.begin() + len + 1, x)
      - (primes.begin() + 1));
}

template <typename T1, typename T2, typename T3>
inline T2 in_between(T1 min, T2 x, T3 max)
{
  if (x < min)
    return (T2) min;
  if (x > max)
    return (T2) max;

  return x;
}

} // namespace

#endif
<commit_msg>Remove C++11 type_traits<commit_after>///
/// @file  pmath.hpp
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#ifndef PMATH_HPP
#define PMATH_HPP

#include <stdint.h>
#include <algorithm>
#include <limits>
#include <cassert>
#include <cmath>
#include <vector>

namespace primecount {

/// Convenience min function for different types.
/// @pre sizeof(A) >= sizeof(B),
///      if A is unsigned then b >= 0.
///
template <typename A, typename B>
inline B min(A a, B b)
{
#if __cplusplus >= 201103L
  static_assert(sizeof(A) >= sizeof(B),
               "sizeof(A) >= sizeof(B)");
#endif
  return (B) std::min(a, (A) b);
}

/// Convenience min function for different types.
/// @pre sizeof(A) >= sizeof(B),
///      if A is unsigned then b >= 0.
///
template <typename A, typename B>
inline B min3(A a, B b, B c)
{
#if __cplusplus >= 201103L
  static_assert(sizeof(A) >= sizeof(B),
               "sizeof(A) >= sizeof(B)");
#endif
  return (B) std::min(a, (A) std::min(b, c));
}

/// Convenience max function for different types.
/// @pre sizeof(A) >= sizeof(B),
///      if A is unsigned then b >= 0.
///
template <typename A, typename B>
inline A max(A a, B b)
{
#if __cplusplus >= 201103L
  static_assert(sizeof(A) >= sizeof(B),
               "sizeof(A) >= sizeof(B)");
#endif
  return std::max(a, (A) b);
}

/// Convenience max function for different types.
/// @pre sizeof(A) >= sizeof(B),
///      if A is unsigned then b >= 0.
///
template <typename A, typename B>
inline A max3(A a, B b, B c)
{
#if __cplusplus >= 201103L
  static_assert(sizeof(A) >= sizeof(B),
               "sizeof(A) >= sizeof(B)");
#endif
  return std::max(a, (A) std::max(b, c));
}

inline int64_t isquare(int32_t x)
{
  return x * (int64_t) x;
}

template <typename A, typename B>
inline A ceil_div(A a, B b)
{
  assert(b > 0);
  return (A) ((a + b - 1) / b);
}

template <typename T>
inline T number_of_bits(T)
{
  return (T) (sizeof(T) * 8);
}

/// @brief  Check if an integer is a power of 2.
/// @see    Book "Hacker's Delight".
///
template <typename T>
inline bool is_power_of_2(T x)
{
  return (x != 0 && (x & (x - 1)) == 0);
}

/// @brief  Round up to the next power of 2.
/// @see    Book "Hacker's Delight".
///
template <typename T>
inline T next_power_of_2(T x)
{
  if (x == 0)
    return 1;

  x--;
  for (T i = 1; i < number_of_bits(x); i += i)
    x |= (x >> i);

  return ++x;
}

template <typename T>
inline int ilog(T x)
{
  return (int) std::log((double) x);
}

/// Raise to power
template <typename T>
inline T ipow(T x, int n)
{
  T r = 1;
  for (int i = 0; i < n; i++)
    r *= x;

  return r;
}

/// Integer suare root
template <typename T>
inline T isqrt(T x)
{
  T r = (T) std::sqrt((double) x);
  r = std::min(r, (T) std::numeric_limits<T>::max() >> (sizeof(T) / 2));

  while (r * r > x)
    r--;
  while (x - r * r > r * 2)
    r++;
  return r;
}

/// Check if ipow(x, n) <= limit
template <typename T>
inline bool ipow_less_equal(T x, int n, T limit)
{
  if (limit <= 0)
    return false;

  for (T r = 1; n > 0; n--, r *= x)
    if (r > limit / x)
      return false;

  return true;
}

/// Integer nth root
template <int N, typename T>
inline T iroot(T x)
{
  T r = (T) std::pow((double) x, 1.0 / N);
  while (ipow(r, N) > x)
    r--;
  while (ipow_less_equal(r + 1, N, x))
    r++;
  return r;
}

/// Calculate the number of primes below x using binary search.
/// @pre primes[1] = 2, primes[3] = 3, ...
/// @pre x <= primes.back()
///
template <typename T1, typename T2>
inline T2 pi_bsearch(const std::vector<T1>& primes, T2 x)
{
  // primecount uses 1-indexing
  assert(primes[0] == 0);
  return (T2) (std::upper_bound(primes.begin() + 1, primes.end(), x)
      - (primes.begin() + 1));
}

/// Calculate the number of primes below x using binary search.
/// @pre primes[1] = 2, primes[3] = 3, ...
/// @pre x <= primes.back()
///
template <typename T1, typename T2, typename T3>
inline T3 pi_bsearch(const std::vector<T1>& primes, T2 len, T3 x)
{
  // primecount uses 1-indexing
  assert(primes[0] == 0);
  return (T3) (std::upper_bound(primes.begin() + 1, primes.begin() + len + 1, x)
      - (primes.begin() + 1));
}

template <typename T1, typename T2, typename T3>
inline T2 in_between(T1 min, T2 x, T3 max)
{
  if (x < min)
    return (T2) min;
  if (x > max)
    return (T2) max;

  return x;
}

} // namespace

#endif
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <string>
#include <iostream>

#include "Options.hpp"

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>

using namespace eddic;

bool eddic::OptimizeStrings;
bool eddic::OptimizeUnused;

bool eddic::WarningUnused;

po::variables_map eddic::options;

po::options_description desc("Usage : edic [options]");

bool eddic::parseOptions(int argc, const char* argv[]) {
    try {
        desc.add_options()
            ("help,h", "Generate this help message")
            ("assembly,S", "Generate only the assembly")
            ("version", "Print the version of eddic")
            ("output,o", po::value<std::string>()->default_value("a.out"), "Set the name of the executable")

            ("optimize-all", "Enable all optimizations")
            ("optimize-strings", po::bool_switch(&OptimizeStrings), "Enable the optimizations on strings")
            ("optimize-unused", po::bool_switch(&OptimizeUnused), "Enable the removal of unused variables and functions")

            ("debug,g", "Add debugging symbols")

            ("warning-all", "Enable all the warnings")
            ("warning-unused", po::bool_switch(&WarningUnused), "Enable warnings for unused variables, parameters and functions")

            ("input", po::value<std::string>(), "Input file");

        po::positional_options_description p;
        p.add("input", -1);

        po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), options);
        po::notify(options);

        if(options.count("optimize-all")){
            OptimizeStrings = OptimizeUnused = true;
        }

        if(options.count("warning-all")){
            WarningUnused = true;
        }
    } catch (const po::ambiguous_option& e) {
        std::cout << "Invalid command line options : " << e.what() << std::endl;

        return false;
    } catch (const po::unknown_option& e) {
        std::cout << "Invalid command line options : " << e.what() << std::endl;

        return false;
    } catch (const po::multiple_occurrences& e) {
        std::cout << "Only one file can be compiled" << std::endl;

        return false;
    }

    return true;
}

void eddic::printHelp(){
    std::cout << desc << std::endl;
}

void eddic::printVersion(){
    std::cout << "eddic version 0.7.0" << std::endl;
}
<commit_msg>Add an options to keep the assembly file<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <string>
#include <iostream>

#include "Options.hpp"

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>

using namespace eddic;

bool eddic::OptimizeStrings;
bool eddic::OptimizeUnused;

bool eddic::WarningUnused;

po::variables_map eddic::options;

po::options_description desc("Usage : edic [options]");

bool eddic::parseOptions(int argc, const char* argv[]) {
    try {
        desc.add_options()
            ("help,h", "Generate this help message")
            ("assembly,S", "Generate only the assembly")
            ("keep,k", "Keep the assembly file")
            ("version", "Print the version of eddic")
            ("output,o", po::value<std::string>()->default_value("a.out"), "Set the name of the executable")

            ("optimize-all", "Enable all optimizations")
            ("optimize-strings", po::bool_switch(&OptimizeStrings), "Enable the optimizations on strings")
            ("optimize-unused", po::bool_switch(&OptimizeUnused), "Enable the removal of unused variables and functions")

            ("debug,g", "Add debugging symbols")

            ("warning-all", "Enable all the warnings")
            ("warning-unused", po::bool_switch(&WarningUnused), "Enable warnings for unused variables, parameters and functions")

            ("input", po::value<std::string>(), "Input file");

        po::positional_options_description p;
        p.add("input", -1);

        po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), options);
        po::notify(options);

        if(options.count("optimize-all")){
            OptimizeStrings = OptimizeUnused = true;
        }

        if(options.count("warning-all")){
            WarningUnused = true;
        }
    } catch (const po::ambiguous_option& e) {
        std::cout << "Invalid command line options : " << e.what() << std::endl;

        return false;
    } catch (const po::unknown_option& e) {
        std::cout << "Invalid command line options : " << e.what() << std::endl;

        return false;
    } catch (const po::multiple_occurrences& e) {
        std::cout << "Only one file can be compiled" << std::endl;

        return false;
    }

    return true;
}

void eddic::printHelp(){
    std::cout << desc << std::endl;
}

void eddic::printVersion(){
    std::cout << "eddic version 0.7.0" << std::endl;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int N;
ll C;
ll L[100010];
multiset<ll> S;
ll infty;

int main () {
  cin >> N >> C;
  for (auto i = 0; i < N; ++i) {
    cin >> L[i];
    S.insert(L[i]);
  }
  infty = C + 10;
  int ans = 0;
  while (!S.empty()) {
    auto it = S.end();
    it--;
    ll size = *it;
    cerr << "size = " << size << endl;
    S.erase(it);
    ans++;
    ll yoyu = C - size - 1;
    cerr << "yoyu = " << yoyu << endl;
    if (!S.empty()) {
      auto itt = S.lower_bound(yoyu);
      cerr << "itt = " << *itt << endl;
      if (itt == S.end()) {
        //
      } else {
        S.erase(itt);
      }
    }
  }
  cout << ans << endl;
}
<commit_msg>tried C.cpp to 'C'<commit_after>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int N;
ll C;
ll L[100010];
multiset<ll> S;
ll infty;

int main () {
  cin >> N >> C;
  for (auto i = 0; i < N; ++i) {
    cin >> L[i];
    S.insert(L[i]);
  }
  infty = C + 10;
  int ans = 0;
  while (!S.empty()) {
    auto it = S.end();
    it--;
    ll size = *it;
    // cerr << "size = " << size << endl;
    S.erase(it);
    ans++;
    ll yoyu = C - size - 1;
    // cerr << "yoyu = " << yoyu << endl;
    if (!S.empty()) {
      auto itt = S.lower_bound(yoyu);
      if (itt == S.begin()) {
        //
      } else {
        itt--;
        S.erase(itt);
      }
    }
  }
  cout << ans << endl;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <climits>
#include <cassert>

#include "search.hpp"
#include "movegen.hpp"
#include "move.hpp"
#include "options.hpp"

void alphabeta(Hashtable *tt, Options *options, const Position &pos, bool *stop, int depth, int movetime)
{
    assert(tt != NULL);
    assert(stop != NULL);

    uint64_t node_total = 0ULL;

    PV last_pv;

    search_stack ss[MAX_DEPTH];
    for(int n = 0; n < MAX_DEPTH; ++n)
    {
        ss[n].ply = n;
#ifdef KILLER_MOVES
        ss[n].killer = NO_MOVE;
#endif
#ifdef NULLMOVE
        ss[n].nullmove = true;
#endif
    }

    search_info info;
    info.start = clock();
    info.end = clock();
    info.stop = stop;
    info.tt = tt;
    info.options = options;

    if(depth == 0)
    {
        depth = MAX_DEPTH;
        info.end = info.start + ((double)movetime/1000.0)*CLOCKS_PER_SEC;
    }
    else if(movetime == 0)
    {
        info.end = INT_MAX;
    }

    int last_score = 0;
    for(int d = 1; d <= depth; ++d)
    {
        PV pv;

#ifdef ASPIRATION_WINDOWS
        int score = 0;
        if(depth < 3)
        {
            score = alphabeta_search(pos, info, ss, pv, -INF, INF, d);
        }
        else
        {
            for(auto r : {50, 200, INF})
            {
                int lower = last_score - r;
                int upper = last_score + r;
                score = alphabeta_search(pos, info, ss, pv, lower, upper, d);

                if(lower < score && score < upper)
                {
                    break;
                }
            }
        }
#else
        int score = alphabeta_search(pos, info, ss, pv, -INF, INF, d);
#endif
        last_score = score;

        clock_t end = clock();
        double time_spent = (double)(end - info.start)/CLOCKS_PER_SEC;

        // Throw away the result if we ran out of time or were asked to stop
        if(*info.stop == true || end >= info.end)
        if(d > 1 && (*info.stop == true || end >= info.end))
        {
            break;
        }

        node_total += info.nodes;

        std::cout << "info"
                  << " depth " << d
                  << " nodes " << info.nodes
                  << " score " << score
                  << " time " << (uint64_t)(1000.0*time_spent);

        if(pv.num_moves > 0)
        {
            std::cout << " pv";
            for(int n = 0; n < pv.num_moves; ++n)
            {
                std::cout << " " << move_string(pv.moves[n]);
            }
        }

        std::cout << std::endl;

        last_pv = pv;
    }

#ifndef NDEBUG
    std::cout << std::endl;

    uint64_t total = 0ULL;
    for(int i = 0; i < 256; ++i)
    {
        total += info.cutoffs[i];
    }
    for(int i = 0; i < 8; ++i)
    {
        std::cout << "info "
                  << "move " << i+1 << " "
                  << "cutoffs " << info.cutoffs[i] << " "
                  << "(" << 100.0*info.cutoffs[i]/total << "%)"
                  << std::endl;
    }
    std::cout << std::endl;

    std::cout << "Single cutoffs: " << info.single_cutoffs << std::endl;
    std::cout << "Double cutoffs: " << info.double_cutoffs << std::endl;
    std::cout << std::endl;

    std::cout << "Hash table hits: " << info.hash_hits << std::endl;
    std::cout << "Collisions: " << info.hash_collisions << std::endl;
    std::cout << "Percent: " << 100.0*(double)info.hash_collisions/info.hash_hits << "%" <<  std::endl;
    std::cout << std::endl;

    std::cout << "tt->num_entries: " << tt->num_entries << std::endl;
    std::cout << "tt->max_entries: " << tt->max_entries << std::endl;
    std::cout << std::endl;
#endif

    if(last_pv.num_moves == 0)
    {
        // If we somehow don't have a move from the PV, try play a random one
        Move moves[256];
        int num_moves = movegen(pos, moves);

        if(num_moves == 0)
        {
            std::cout << "bestmove 0000" << std::endl;
        }
        else
        {
            int n = rand() % num_moves;
            assert(legal_move(pos, moves[n]) == true);
            std::cout << "bestmove " << move_string(moves[n]) << std::endl;
        }
    }
    else
    {
        assert(legal_move(pos, last_pv.moves[0]) == true);
        std::cout << "bestmove " << move_string(last_pv.moves[0]) << std::endl;
    }
}
<commit_msg>Fix typo<commit_after>#include <iostream>
#include <climits>
#include <cassert>

#include "search.hpp"
#include "movegen.hpp"
#include "move.hpp"
#include "options.hpp"

void alphabeta(Hashtable *tt, Options *options, const Position &pos, bool *stop, int depth, int movetime)
{
    assert(tt != NULL);
    assert(stop != NULL);

    uint64_t node_total = 0ULL;

    PV last_pv;

    search_stack ss[MAX_DEPTH];
    for(int n = 0; n < MAX_DEPTH; ++n)
    {
        ss[n].ply = n;
#ifdef KILLER_MOVES
        ss[n].killer = NO_MOVE;
#endif
#ifdef NULLMOVE
        ss[n].nullmove = true;
#endif
    }

    search_info info;
    info.start = clock();
    info.end = clock();
    info.stop = stop;
    info.tt = tt;
    info.options = options;

    if(depth == 0)
    {
        depth = MAX_DEPTH;
        info.end = info.start + ((double)movetime/1000.0)*CLOCKS_PER_SEC;
    }
    else if(movetime == 0)
    {
        info.end = INT_MAX;
    }

    int last_score = 0;
    for(int d = 1; d <= depth; ++d)
    {
        PV pv;

#ifdef ASPIRATION_WINDOWS
        int score = 0;
        if(depth < 3)
        {
            score = alphabeta_search(pos, info, ss, pv, -INF, INF, d);
        }
        else
        {
            for(auto r : {50, 200, INF})
            {
                int lower = last_score - r;
                int upper = last_score + r;
                score = alphabeta_search(pos, info, ss, pv, lower, upper, d);

                if(lower < score && score < upper)
                {
                    break;
                }
            }
        }
#else
        int score = alphabeta_search(pos, info, ss, pv, -INF, INF, d);
#endif
        last_score = score;

        clock_t end = clock();
        double time_spent = (double)(end - info.start)/CLOCKS_PER_SEC;

        // Throw away the result if we ran out of time or were asked to stop
        if(d > 1 && (*info.stop == true || end >= info.end))
        {
            break;
        }

        node_total += info.nodes;

        std::cout << "info"
                  << " depth " << d
                  << " nodes " << info.nodes
                  << " score " << score
                  << " time " << (uint64_t)(1000.0*time_spent);

        if(pv.num_moves > 0)
        {
            std::cout << " pv";
            for(int n = 0; n < pv.num_moves; ++n)
            {
                std::cout << " " << move_string(pv.moves[n]);
            }
        }

        std::cout << std::endl;

        last_pv = pv;
    }

#ifndef NDEBUG
    std::cout << std::endl;

    uint64_t total = 0ULL;
    for(int i = 0; i < 256; ++i)
    {
        total += info.cutoffs[i];
    }
    for(int i = 0; i < 8; ++i)
    {
        std::cout << "info "
                  << "move " << i+1 << " "
                  << "cutoffs " << info.cutoffs[i] << " "
                  << "(" << 100.0*info.cutoffs[i]/total << "%)"
                  << std::endl;
    }
    std::cout << std::endl;

    std::cout << "Single cutoffs: " << info.single_cutoffs << std::endl;
    std::cout << "Double cutoffs: " << info.double_cutoffs << std::endl;
    std::cout << std::endl;

    std::cout << "Hash table hits: " << info.hash_hits << std::endl;
    std::cout << "Collisions: " << info.hash_collisions << std::endl;
    std::cout << "Percent: " << 100.0*(double)info.hash_collisions/info.hash_hits << "%" <<  std::endl;
    std::cout << std::endl;

    std::cout << "tt->num_entries: " << tt->num_entries << std::endl;
    std::cout << "tt->max_entries: " << tt->max_entries << std::endl;
    std::cout << std::endl;
#endif

    if(last_pv.num_moves == 0)
    {
        // If we somehow don't have a move from the PV, try play a random one
        Move moves[256];
        int num_moves = movegen(pos, moves);

        if(num_moves == 0)
        {
            std::cout << "bestmove 0000" << std::endl;
        }
        else
        {
            int n = rand() % num_moves;
            assert(legal_move(pos, moves[n]) == true);
            std::cout << "bestmove " << move_string(moves[n]) << std::endl;
        }
    }
    else
    {
        assert(legal_move(pos, last_pv.moves[0]) == true);
        std::cout << "bestmove " << move_string(last_pv.moves[0]) << std::endl;
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2011-2015 Zeex
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#include <cassert>
#include "amx_utils.h"
#include "function.h"
#include "function_call.h"
#include "function_statistics.h"
#include "profiler.h"

namespace amxprof {

Profiler::Profiler(AMX *amx, bool enable_call_graph)
 : amx_(amx),
   debug_info_(0),
   call_graph_enabled_(enable_call_graph)
{
}

Profiler::~Profiler() {
  for (std::set<Function*>::const_iterator iterator = functions_.begin();
       iterator != functions_.end(); ++iterator) {
    delete *iterator;
  }
}

int Profiler::DebugHook(AMX_DEBUG debug) {
  Address prev_frame = call_stack_.is_empty()
    ? amx_->stp
    : prev_frame = call_stack_.top()->frame();

  if (amx_->frm < prev_frame) {
    if (prev_frame != amx_->frm) {
      Address address = GetCalleeAddress(amx_, amx_->frm);
      if (address != 0) {
        Function *fn = stats_.GetFunction(address);
        if (fn == 0) {
          fn = Function::Normal(address, debug_info_);
          functions_.insert(fn);
          stats_.AddFunction(fn);
        }
        EnterFunction(address, amx_->frm);
      }
    }
  } else if (amx_->frm > prev_frame) {
    if (call_stack_.top()->function()->type() == Function::NORMAL) {
      LeaveFunction(0, amx_->frm);
    }
  }

  if (debug != 0) {
    return debug(amx_);
  }

  return AMX_ERR_NONE;
}

int Profiler::CallbackHook(cell index, cell *result, cell *params, AMX_CALLBACK callback) {
  if (callback == 0) {
    callback = ::amx_Callback;
  }

  if (index >= 0) {
    Address address = GetNativeAddress(amx_, index);
    if (address != 0) {
      Function *fn = stats_.GetFunction(address);
      if (fn == 0) {
        fn = Function::Native(amx_, index);
        functions_.insert(fn);
        stats_.AddFunction(fn);
      }
      EnterFunction(address, amx_->frm);
    }
    int error = callback(amx_, index, result, params);
    if (address != 0) {
      LeaveFunction(address, 0);
    }
    return error;
  }

  return callback(amx_, index, result, params);
}

int Profiler::ExecHook(cell *retval, int index, AMX_EXEC exec) {
  if (exec == 0) {
    exec = ::amx_Exec;
  }

  if (index >= 0 || index == AMX_EXEC_MAIN) {
    Address address = GetPublicAddress(amx_, index);
    if (address != 0) {
      Function *fn = stats_.GetFunction(address);
      if (fn == 0) {
        fn = Function::Public(amx_, index);
        functions_.insert(fn);
        stats_.AddFunction(fn);
      }
      EnterFunction(address, amx_->stk - 3 * sizeof(cell));
    }
    int error = exec(amx_, retval, index);
    if (address != 0) {
      LeaveFunction(address, 0);
    }
    return error;
  }

  return exec(amx_, retval, index);
}

void Profiler::EnterFunction(Address address, Address frame) {
  assert(address != 0);

  FunctionStatistics *fn_stats = stats_.GetFunctionStatistics(address);
  assert(fn_stats != 0);
  printf("Entering %s\n", fn_stats->function()->name().c_str());

  fn_stats->AdjustNumCalls(1);

  call_stack_.Push(fn_stats->function(), frame);
  if (call_graph_enabled_) {
    call_graph_.PushCall(fn_stats);
  }
}

void Profiler::LeaveFunction(Address address, Address frame) {
  assert(!call_stack_.is_empty());
  assert(address == 0 || stats_.GetFunction(address) != 0);

  while (!call_stack_.is_empty()) {
    FunctionCall call = call_stack_.Pop();
    FunctionCall *next_call = call_stack_.is_empty() ? 0 : call_stack_.top();

    FunctionStatistics *fn_stats =
      stats_.GetFunctionStatistics(call.function()->address());
    assert(fn_stats != 0);
    printf("Leaving %s\n", fn_stats->function()->name().c_str());

    fn_stats->AdjustSelfTime(call.timer()->self_time());
    fn_stats->AdjustTotalTime(call.timer()->total_time());

    Nanoseconds total_time = call.timer()->latest_total_time();
    if (total_time > fn_stats->worst_total_time()) {
      fn_stats->set_worst_total_time(total_time);
    }

    Nanoseconds self_time = call.timer()->latest_self_time();
    if (self_time > fn_stats->worst_self_time()) {
      fn_stats->set_worst_self_time(self_time);
    }

    if (call_graph_enabled_) {
      call_graph_.PopCall();
    }

    if (call.function()->address() == address
        || (frame != 0 && next_call != 0 && next_call->frame() >= frame)) {
      break;
    }
  }
}

} // namespace amxprof
<commit_msg>Remove debug prints<commit_after>// Copyright (c) 2011-2015 Zeex
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#include <cassert>
#include "amx_utils.h"
#include "function.h"
#include "function_call.h"
#include "function_statistics.h"
#include "profiler.h"

namespace amxprof {

Profiler::Profiler(AMX *amx, bool enable_call_graph)
 : amx_(amx),
   debug_info_(0),
   call_graph_enabled_(enable_call_graph)
{
}

Profiler::~Profiler() {
  for (std::set<Function*>::const_iterator iterator = functions_.begin();
       iterator != functions_.end(); ++iterator) {
    delete *iterator;
  }
}

int Profiler::DebugHook(AMX_DEBUG debug) {
  Address prev_frame = call_stack_.is_empty()
    ? amx_->stp
    : prev_frame = call_stack_.top()->frame();

  if (amx_->frm < prev_frame) {
    if (prev_frame != amx_->frm) {
      Address address = GetCalleeAddress(amx_, amx_->frm);
      if (address != 0) {
        Function *fn = stats_.GetFunction(address);
        if (fn == 0) {
          fn = Function::Normal(address, debug_info_);
          functions_.insert(fn);
          stats_.AddFunction(fn);
        }
        EnterFunction(address, amx_->frm);
      }
    }
  } else if (amx_->frm > prev_frame) {
    if (call_stack_.top()->function()->type() == Function::NORMAL) {
      LeaveFunction(0, amx_->frm);
    }
  }

  if (debug != 0) {
    return debug(amx_);
  }

  return AMX_ERR_NONE;
}

int Profiler::CallbackHook(cell index, cell *result, cell *params, AMX_CALLBACK callback) {
  if (callback == 0) {
    callback = ::amx_Callback;
  }

  if (index >= 0) {
    Address address = GetNativeAddress(amx_, index);
    if (address != 0) {
      Function *fn = stats_.GetFunction(address);
      if (fn == 0) {
        fn = Function::Native(amx_, index);
        functions_.insert(fn);
        stats_.AddFunction(fn);
      }
      EnterFunction(address, amx_->frm);
    }
    int error = callback(amx_, index, result, params);
    if (address != 0) {
      LeaveFunction(address, 0);
    }
    return error;
  }

  return callback(amx_, index, result, params);
}

int Profiler::ExecHook(cell *retval, int index, AMX_EXEC exec) {
  if (exec == 0) {
    exec = ::amx_Exec;
  }

  if (index >= 0 || index == AMX_EXEC_MAIN) {
    Address address = GetPublicAddress(amx_, index);
    if (address != 0) {
      Function *fn = stats_.GetFunction(address);
      if (fn == 0) {
        fn = Function::Public(amx_, index);
        functions_.insert(fn);
        stats_.AddFunction(fn);
      }
      EnterFunction(address, amx_->stk - 3 * sizeof(cell));
    }
    int error = exec(amx_, retval, index);
    if (address != 0) {
      LeaveFunction(address, 0);
    }
    return error;
  }

  return exec(amx_, retval, index);
}

void Profiler::EnterFunction(Address address, Address frame) {
  assert(address != 0);

  FunctionStatistics *fn_stats = stats_.GetFunctionStatistics(address);
  assert(fn_stats != 0);

  fn_stats->AdjustNumCalls(1);

  call_stack_.Push(fn_stats->function(), frame);
  if (call_graph_enabled_) {
    call_graph_.PushCall(fn_stats);
  }
}

void Profiler::LeaveFunction(Address address, Address frame) {
  assert(!call_stack_.is_empty());
  assert(address == 0 || stats_.GetFunction(address) != 0);

  while (!call_stack_.is_empty()) {
    FunctionCall call = call_stack_.Pop();
    FunctionCall *next_call = call_stack_.is_empty() ? 0 : call_stack_.top();

    FunctionStatistics *fn_stats =
      stats_.GetFunctionStatistics(call.function()->address());
    assert(fn_stats != 0);

    fn_stats->AdjustSelfTime(call.timer()->self_time());
    fn_stats->AdjustTotalTime(call.timer()->total_time());

    Nanoseconds total_time = call.timer()->latest_total_time();
    if (total_time > fn_stats->worst_total_time()) {
      fn_stats->set_worst_total_time(total_time);
    }

    Nanoseconds self_time = call.timer()->latest_self_time();
    if (self_time > fn_stats->worst_self_time()) {
      fn_stats->set_worst_self_time(self_time);
    }

    if (call_graph_enabled_) {
      call_graph_.PopCall();
    }

    if (call.function()->address() == address
        || (frame != 0 && next_call != 0 && next_call->frame() >= frame)) {
      break;
    }
  }
}

} // namespace amxprof
<|endoftext|>


<commit_before>///
/// @file  PhiTiny.cpp
/// @brief phi_tiny(x, a) calculates the partial sieve function in
///        constant time (using lookup tables) for small values of
///        a <= 6 using the formula below:
///
///        phi(x, a) = (x / pp) * φ(pp) + phi(x % pp, a)
///        with pp = 2 * 3 * ... * prime[a]
///
/// Copyright (C) 2015 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <PhiTiny.hpp>
#include <int128.hpp>

#include <stdint.h>
#include <vector>

namespace primecount {

extern const PhiTiny phiTiny = PhiTiny();

const int PhiTiny::pi[20] = { 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 8 };

const int PhiTiny::primes[7] = { 0, 2, 3, 5, 7, 11, 13 };

/// prime_products[n] = \prod_{i=1}^{n} primes[i]
const int PhiTiny::prime_products[7] = { 1, 2, 6, 30, 210, 2310, 30030 };

/// totients[n] = \prod_{i=1}^{n} (primes[i] - 1)
const int PhiTiny::totients[7] = { 1, 1, 2, 8, 48, 480, 5760 };

PhiTiny::PhiTiny()
{
  phi_cache_[0].push_back(0);

  // Initialize the phi_cache_ lookup tables
  for (int a = 1; a <= max_a(); a++)
  {
    int size = prime_products[a];
    std::vector<int16_t>& cache = phi_cache_[a];
    cache.reserve(size);

    for (int x = 0; x < size; x++)
    {
      int16_t phi_xa = (int16_t) (phi(x, a - 1) - phi(x / primes[a], a - 1));
      cache.push_back(phi_xa);
    }
  }
}

} // namespace primecount
<commit_msg>Refactoring<commit_after>///
/// @file  PhiTiny.cpp
/// @brief phi_tiny(x, a) calculates the partial sieve function in
///        constant time (using lookup tables) for small values of
///        a <= 6 using the formula below:
///
///        phi(x, a) = (x / pp) * φ(pp) + phi(x % pp, a)
///        with pp = 2 * 3 * ... * prime[a]
///
/// Copyright (C) 2016 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <PhiTiny.hpp>
#include <int128.hpp>

#include <stdint.h>
#include <vector>

namespace primecount {

extern const PhiTiny phiTiny = PhiTiny();

const int PhiTiny::pi[20] = { 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 8 };

const int PhiTiny::primes[7] = { 0, 2, 3, 5, 7, 11, 13 };

/// prime_products[n] = \prod_{i=1}^{n} primes[i]
const int PhiTiny::prime_products[7] = { 1, 2, 6, 30, 210, 2310, 30030 };

/// totients[n] = \prod_{i=1}^{n} (primes[i] - 1)
const int PhiTiny::totients[7] = { 1, 1, 2, 8, 48, 480, 5760 };

PhiTiny::PhiTiny()
{
  phi_cache_[0].push_back(0);

  // Initialize the phi_cache_ lookup tables
  for (int a = 1; a <= max_a(); a++)
  {
    int size = prime_products[a];
    std::vector<int16_t>& cache = phi_cache_[a];
    cache.reserve(size);

    for (int x = 0; x < size; x++)
    {
      int64_t phi_xa = phi(x, a - 1) - phi(x / primes[a], a - 1);
      cache.push_back((int16_t) phi_xa);
    }
  }
}

} // namespace primecount
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library 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 2.1 of the License, or (at your option) any later version.
 *
 * This library 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 Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id: geometry.hpp 39 2005-04-10 20:39:53Z pavlenko $

#ifndef GEOMETRY_HPP
#define GEOMETRY_HPP

// boost
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
// mapnik
#include <mapnik/vertex_vector.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/geom_util.hpp>

namespace mapnik {
    enum {
    	Point = 1,
    	LineString = 2,
    	Polygon = 3
    };

    template <typename T>
    class geometry : private boost::noncopyable
    {
    public:
        typedef T vertex_type;
        typedef typename vertex_type::type value_type;
    private:
        int srid_;
    public:
        geometry (int srid=-1)
            : srid_(srid) {}

        int srid() const
        {
            return srid_;
        }

        Envelope<double> envelope()
        {
            Envelope<double> result;
            double x,y;
            for (unsigned i=0;i<num_points();++i)
            {
                vertex(&x,&y);
                if (i==0)
                {
                    result.init(x,y,x,y);
                }
                else
                {
                    result.expand_to_include(x,y);
                }
            }
            return result;
        }

        virtual int type() const=0;
        virtual bool hit_test(value_type x,value_type y, double tol) const=0;
        virtual void label_position(double *x, double *y) const=0;
        virtual void move_to(value_type x,value_type y)=0;
        virtual void line_to(value_type x,value_type y)=0;
        virtual unsigned num_points() const = 0;
        virtual unsigned vertex(double* x, double* y)=0;
        virtual void rewind(unsigned )=0;
        virtual void set_capacity(size_t size)=0;
        virtual ~geometry() {}
    };

    template <typename T>
    class point : public geometry<T>
    {
        typedef geometry<T> geometry_base;
        typedef typename geometry<T>::vertex_type vertex_type;
        typedef typename geometry<T>::value_type value_type;
    private:
        vertex_type pt_;
    public:
        point(int srid)
            : geometry<T>(srid)
        {}

        int type() const
        {
            return Point;
        }
        void label_position(double *x, double *y) const
        {
            *x = pt_.x;
            *y = pt_.y;
        }

        void move_to(value_type x,value_type y)
        {
            pt_.x = x;
            pt_.y = y;
        }

        void line_to(value_type ,value_type ) {}

        unsigned num_points() const
        {
            return 1;
        }

        unsigned vertex(double* x, double* y)
        {
            *x = pt_.x;
            *y = pt_.y;
            return SEG_LINETO;
        }

        void rewind(unsigned ) {}

        bool hit_test(value_type x,value_type y, double tol) const
        {
            return point_in_circle(pt_.x,pt_.y, x,y,tol);
        }

        void set_capacity(size_t) {}
        virtual ~point() {}
    };

    template <typename T, template <typename> class Container=vertex_vector2>
    class polygon : public geometry<T>
    {
        typedef geometry<T> geometry_base;
        typedef typename geometry<T>::vertex_type vertex_type;
        typedef typename geometry_base::value_type value_type;
        typedef Container<vertex_type> container_type;
    private:
        container_type cont_;
        mutable unsigned itr_;
    public:
        polygon(int srid)
            : geometry_base(srid),
              itr_(0)
        {}

        int type() const
        {
            return Polygon;
        }

        void label_position(double *x, double *y) const
        {

            unsigned size = cont_.size();
            if (size < 3)
            {
                cont_.get_vertex(0,x,y);
                return;
            }

            double ai;
            double atmp = 0;
            double xtmp = 0;
            double ytmp = 0;
            double x0 =0;
            double y0 =0;
            double x1 =0;
            double y1 =0;

            unsigned i,j;
            for (i = size-1,j = 0; j < size; i = j, ++j)
            {
                cont_.get_vertex(i,&x0,&y0);
                cont_.get_vertex(j,&x1,&y1);
                ai = x0 * y1 - x1 * y0;
                atmp += ai;
                xtmp += (x1 + x0) * ai;
                ytmp += (y1 + y0) * ai;
            }
            if (atmp != 0)
            {
                *x = xtmp/(3*atmp);
                *y = ytmp /(3*atmp);
                return;
            }
            *x=x0;
            *y=y0;
        }

        void line_to(value_type x,value_type y)
        {
            cont_.push_back(x,y,SEG_LINETO);
        }

        void move_to(value_type x,value_type y)
        {
            cont_.push_back(x,y,SEG_MOVETO);
        }

        unsigned num_points() const
        {
            return cont_.size();
        }

        unsigned vertex(double* x, double* y)
        {
            return cont_.get_vertex(itr_++,x,y);
        }

        void rewind(unsigned )
        {
            itr_=0;
        }

        bool hit_test(value_type x,value_type y, double) const
        {
            return point_inside_path(x,y,cont_.begin(),cont_.end());
        }

        void set_capacity(size_t size)
        {
            cont_.set_capacity(size);
        }
        virtual ~polygon() {}
    };

    template <typename T, template <typename> class Container=vertex_vector2>
    class line_string : public geometry<T>
    {
        typedef geometry<T> geometry_base;
        typedef typename geometry_base::value_type value_type;
        typedef typename geometry<T>::vertex_type vertex_type;
        typedef Container<vertex_type> container_type;
    private:
        container_type cont_;
        mutable unsigned itr_;
    public:
        line_string(int srid)
            : geometry_base(srid),
              itr_(0)
        {}

        int type() const
        {
            return LineString;
        }
        void label_position(double *x, double *y) const
        {
            // calculate mid point on line string
            double x0=0;
            double y0=0;
            double x1=0;
            double y1=0;

            unsigned size = cont_.size();
            if (size == 1)
            {
                cont_.get_vertex(0,x,y);
            }
            else if (size == 2)
            {

                cont_.get_vertex(0,&x0,&y0);
                cont_.get_vertex(1,&x1,&y1);
                *x = 0.5 * (x1 + x0);
                *y = 0.5 * (y1 + y0);
            }
            else
            {
                double len=0.0;
                for (unsigned pos = 1; pos < size; ++pos)
                {
                    cont_.get_vertex(pos-1,&x0,&y0);
                    cont_.get_vertex(pos,&x1,&y1);
                    double dx = x1 - x0;
                    double dy = y1 - y0;
                    len += sqrt(dx * dx + dy * dy);
                }
                double midlen = 0.5 * len;
                double dist = 0.0;
                for (unsigned pos = 1; pos < size;++pos)
                {
                    cont_.get_vertex(pos-1,&x0,&y0);
                    cont_.get_vertex(pos,&x1,&y1);
                    double dx = x1 - x0;
                    double dy = y1 - y0;
                    double seg_len = sqrt(dx * dx + dy * dy);
                    if (( dist + seg_len) >= midlen)
                    {
                        double r = (midlen - dist)/seg_len;
                        *x = x0 + (x1 - x0) * r;
                        *y = y0 + (y1 - y0) * r;
                        break;
                    }
                    dist += seg_len;
                }
            }

        }
        void line_to(value_type x,value_type y)
        {
            cont_.push_back(x,y,SEG_LINETO);
        }

        void move_to(value_type x,value_type y)
        {
            cont_.push_back(x,y,SEG_MOVETO);
        }

        unsigned num_points() const
        {
            return cont_.size();
        }

        unsigned vertex(double* x, double* y)
        {
            return cont_.get_vertex(itr_++,x,y);
        }

        void rewind(unsigned )
        {
            itr_=0;
        }

        bool hit_test(value_type x,value_type y, double tol) const
        {
            return point_on_path(x,y,cont_.begin(),cont_.end(),tol);
        }

        void set_capacity(size_t size)
        {
            cont_.set_capacity(size);
        }
        virtual ~line_string() {}
    };

    typedef point<vertex2d> point_impl;
    typedef line_string<vertex2d,vertex_vector2> line_string_impl;
    typedef polygon<vertex2d,vertex_vector2> polygon_impl;

    typedef geometry<vertex2d> geometry_type;
    typedef boost::shared_ptr<geometry_type> geometry_ptr;
}

#endif //GEOMETRY_HPP
<commit_msg>rewind path in envelope() method<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library 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 2.1 of the License, or (at your option) any later version.
 *
 * This library 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 Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id: geometry.hpp 39 2005-04-10 20:39:53Z pavlenko $

#ifndef GEOMETRY_HPP
#define GEOMETRY_HPP

// boost
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
// mapnik
#include <mapnik/vertex_vector.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/geom_util.hpp>

namespace mapnik {
    enum {
    	Point = 1,
    	LineString = 2,
    	Polygon = 3
    };

    template <typename T>
    class geometry : private boost::noncopyable
    {
    public:
        typedef T vertex_type;
        typedef typename vertex_type::type value_type;
    private:
        int srid_;
    public:
        geometry (int srid=-1)
            : srid_(srid) {}

        int srid() const
        {
            return srid_;
        }

        Envelope<double> envelope()
        {
            Envelope<double> result;
            double x,y;
            rewind(0);
            for (unsigned i=0;i<num_points();++i)
            {
                vertex(&x,&y);
                if (i==0)
                {
                    result.init(x,y,x,y);
                }
                else
                {
                    result.expand_to_include(x,y);
                }
            }
            return result;
        }

        virtual int type() const=0;
        virtual bool hit_test(value_type x,value_type y, double tol) const=0;
        virtual void label_position(double *x, double *y) const=0;
        virtual void move_to(value_type x,value_type y)=0;
        virtual void line_to(value_type x,value_type y)=0;
        virtual unsigned num_points() const = 0;
        virtual unsigned vertex(double* x, double* y)=0;
        virtual void rewind(unsigned )=0;
        virtual void set_capacity(size_t size)=0;
        virtual ~geometry() {}
    };

    template <typename T>
    class point : public geometry<T>
    {
        typedef geometry<T> geometry_base;
        typedef typename geometry<T>::vertex_type vertex_type;
        typedef typename geometry<T>::value_type value_type;
    private:
        vertex_type pt_;
    public:
        point(int srid)
            : geometry<T>(srid)
        {}

        int type() const
        {
            return Point;
        }
        void label_position(double *x, double *y) const
        {
            *x = pt_.x;
            *y = pt_.y;
        }

        void move_to(value_type x,value_type y)
        {
            pt_.x = x;
            pt_.y = y;
        }

        void line_to(value_type ,value_type ) {}

        unsigned num_points() const
        {
            return 1;
        }

        unsigned vertex(double* x, double* y)
        {
            *x = pt_.x;
            *y = pt_.y;
            return SEG_LINETO;
        }

        void rewind(unsigned ) {}

        bool hit_test(value_type x,value_type y, double tol) const
        {
            return point_in_circle(pt_.x,pt_.y, x,y,tol);
        }

        void set_capacity(size_t) {}
        virtual ~point() {}
    };

    template <typename T, template <typename> class Container=vertex_vector2>
    class polygon : public geometry<T>
    {
        typedef geometry<T> geometry_base;
        typedef typename geometry<T>::vertex_type vertex_type;
        typedef typename geometry_base::value_type value_type;
        typedef Container<vertex_type> container_type;
    private:
        container_type cont_;
        mutable unsigned itr_;
    public:
        polygon(int srid)
            : geometry_base(srid),
              itr_(0)
        {}

        int type() const
        {
            return Polygon;
        }

        void label_position(double *x, double *y) const
        {
            unsigned size = cont_.size();
            if (size < 4)
            {
               x=0;y=0;
               return;
            }

            double ai;
            double atmp = 0;
            double xtmp = 0;
            double ytmp = 0;
            double x0 =0;
            double y0 =0;
            double x1 =0;
            double y1 =0;

            unsigned i,j;
            for (i = size-2,j = 0; j < size-1; i = j, ++j)
            {
                cont_.get_vertex(i,&x0,&y0);
                cont_.get_vertex(j,&x1,&y1);
                ai = x0 * y1 - x1 * y0;
                atmp += ai;
                xtmp += (x1 + x0) * ai;
                ytmp += (y1 + y0) * ai;
            }
            if (atmp != 0)
            {
                *x = xtmp/(3*atmp);
                *y = ytmp /(3*atmp);
                return;
            }
            *x=x0;
            *y=y0;
        }

        void line_to(value_type x,value_type y)
        {
            cont_.push_back(x,y,SEG_LINETO);
        }

        void move_to(value_type x,value_type y)
        {
            cont_.push_back(x,y,SEG_MOVETO);
        }

        unsigned num_points() const
        {
            return cont_.size();
        }

        unsigned vertex(double* x, double* y)
        {
            return cont_.get_vertex(itr_++,x,y);
        }

        void rewind(unsigned )
        {
            itr_=0;
        }

        bool hit_test(value_type x,value_type y, double) const
        {
            return point_inside_path(x,y,cont_.begin(),cont_.end());
        }

        void set_capacity(size_t size)
        {
            cont_.set_capacity(size);
        }
        virtual ~polygon() {}
    };

    template <typename T, template <typename> class Container=vertex_vector2>
    class line_string : public geometry<T>
    {
        typedef geometry<T> geometry_base;
        typedef typename geometry_base::value_type value_type;
        typedef typename geometry<T>::vertex_type vertex_type;
        typedef Container<vertex_type> container_type;
    private:
        container_type cont_;
        mutable unsigned itr_;
    public:
        line_string(int srid)
            : geometry_base(srid),
              itr_(0)
        {}

        int type() const
        {
            return LineString;
        }
        void label_position(double *x, double *y) const
        {
            // calculate mid point on line string
            double x0=0;
            double y0=0;
            double x1=0;
            double y1=0;

            unsigned size = cont_.size();
            if (size == 1)
            {
                cont_.get_vertex(0,x,y);
            }
            else if (size == 2)
            {

                cont_.get_vertex(0,&x0,&y0);
                cont_.get_vertex(1,&x1,&y1);
                *x = 0.5 * (x1 + x0);
                *y = 0.5 * (y1 + y0);
            }
            else
            {
                double len=0.0;
                for (unsigned pos = 1; pos < size; ++pos)
                {
                    cont_.get_vertex(pos-1,&x0,&y0);
                    cont_.get_vertex(pos,&x1,&y1);
                    double dx = x1 - x0;
                    double dy = y1 - y0;
                    len += sqrt(dx * dx + dy * dy);
                }
                double midlen = 0.5 * len;
                double dist = 0.0;
                for (unsigned pos = 1; pos < size;++pos)
                {
                    cont_.get_vertex(pos-1,&x0,&y0);
                    cont_.get_vertex(pos,&x1,&y1);
                    double dx = x1 - x0;
                    double dy = y1 - y0;
                    double seg_len = sqrt(dx * dx + dy * dy);
                    if (( dist + seg_len) >= midlen)
                    {
                        double r = (midlen - dist)/seg_len;
                        *x = x0 + (x1 - x0) * r;
                        *y = y0 + (y1 - y0) * r;
                        break;
                    }
                    dist += seg_len;
                }
            }

        }
        void line_to(value_type x,value_type y)
        {
            cont_.push_back(x,y,SEG_LINETO);
        }

        void move_to(value_type x,value_type y)
        {
            cont_.push_back(x,y,SEG_MOVETO);
        }

        unsigned num_points() const
        {
            return cont_.size();
        }

        unsigned vertex(double* x, double* y)
        {
            return cont_.get_vertex(itr_++,x,y);
        }

        void rewind(unsigned )
        {
            itr_=0;
        }

        bool hit_test(value_type x,value_type y, double tol) const
        {
            return point_on_path(x,y,cont_.begin(),cont_.end(),tol);
        }

        void set_capacity(size_t size)
        {
            cont_.set_capacity(size);
        }
        virtual ~line_string() {}
    };

    typedef point<vertex2d> point_impl;
    typedef line_string<vertex2d,vertex_vector2> line_string_impl;
    typedef polygon<vertex2d,vertex_vector2> polygon_impl;

    typedef geometry<vertex2d> geometry_type;
    typedef boost::shared_ptr<geometry_type> geometry_ptr;
}

#endif //GEOMETRY_HPP
<|endoftext|>


<commit_before>#ifndef QTAEL_HPP
#define QTAEL_HPP

#include <functional>
#include <memory>
#include <tuple>
#include <utility>

#include <QtCore/QObject>
#include <QtCore/QVariantList>

#ifdef QTAEL_LIBRARY
#define QTAEL_DLL Q_DECL_EXPORT
#else
#define QTAEL_DLL Q_DECL_IMPORT
#endif

namespace qtael {

class Await;
using Function = std::function<void (const Await &)>;

class QTAEL_DLL Async : public QObject {
    Q_OBJECT
public:
    explicit Async (Function task, QObject * parent = 0);

    void start ();
    void stop ();

signals:
    void finished ();

private:
    friend class Await;
    class Private;
    Private * d;
};

namespace detail {

class SignalIsolator : public QObject {
    Q_OBJECT
public:
    template<typename ...Args>
    void proxy (Args&&... args) {
        this->_args = {args...};
        emit this->resolved();
    }

    const QVariantList & getResult () const {
        return this->_args;
    }

signals:
    void resolved ();

private:
    QVariantList _args;
};

template<typename T>
using DecayType = typename std::decay<T>::type;

template<typename ...Args, std::size_t ...Indices>
auto argsToTupleImpl (const QVariantList & args, std::index_sequence<Indices...>) {
    return std::make_tuple(args.at(Indices).value<detail::DecayType<Args>>()...);
}

template<typename ...Args>
auto argsToTuple (const QVariantList & args) {
    return argsToTupleImpl<Args...>(args, std::make_index_sequence<sizeof...(Args)>());
}

}

class QTAEL_DLL Await {
public:
    template<typename T, typename R, typename ...Args>
    using SignalType = R (T::*)(Args...);

    void operator () (int interval) const;

    template<typename T, typename R, typename ...Args>
    auto operator () (T * object, SignalType<T, R, Args...> signal_) const {
        detail::SignalIsolator proxy;
        QObject::connect(object, signal_, &proxy, &detail::SignalIsolator::proxy<Args...>);
        this->yield(&proxy);
        return detail::argsToTuple<Args...>(proxy.getResult());
    }

private:
    friend class Async;
    class Private;

    Await (std::shared_ptr<Private> d);
    Await (const Await &);
    Await & operator = (const Await &);
    Await (Await &&);
    Await & operator = (Await &&);
    ~Await ();

    void yield(QObject * object) const;

    std::shared_ptr<Private> d;
};

}

#endif
<commit_msg>extract helper templates<commit_after>#ifndef QTAEL_HPP
#define QTAEL_HPP

#include <functional>
#include <memory>
#include <tuple>
#include <utility>

#include <QtCore/QObject>
#include <QtCore/QVariantList>

#ifdef QTAEL_LIBRARY
#define QTAEL_DLL Q_DECL_EXPORT
#else
#define QTAEL_DLL Q_DECL_IMPORT
#endif

namespace qtael {

class Await;
using Function = std::function<void (const Await &)>;

class QTAEL_DLL Async : public QObject {
    Q_OBJECT
public:
    explicit Async (Function task, QObject * parent = 0);

    void start ();
    void stop ();

signals:
    void finished ();

private:
    friend class Await;
    class Private;
    Private * d;
};

namespace detail {

class SignalIsolator : public QObject {
    Q_OBJECT
public:
    template<typename ...Args>
    void proxy (Args&&... args) {
        this->_args = {args...};
        emit this->resolved();
    }

    const QVariantList & getResult () const {
        return this->_args;
    }

signals:
    void resolved ();

private:
    QVariantList _args;
};

template<typename T>
using DecayType = typename std::decay<T>::type;

template<typename ...Args>
using MIS = std::make_index_sequence<sizeof...(Args)>;

template<std::size_t ...Indices>
using IS = std::index_sequence<Indices...>;

template<typename ...Args, std::size_t ...Indices>
auto argsToTupleImpl (const QVariantList & args, IS<Indices...>) {
    return std::make_tuple(args.at(Indices).value<DecayType<Args>>()...);
}

template<typename ...Args>
auto argsToTuple (const QVariantList & args) {
    return argsToTupleImpl<Args...>(args, MIS<Args...>());
}

}

class QTAEL_DLL Await {
public:
    template<typename T, typename R, typename ...Args>
    using SignalType = R (T::*)(Args...);

    void operator () (int interval) const;

    template<typename T, typename R, typename ...Args>
    auto operator () (T * object, SignalType<T, R, Args...> signal_) const {
        detail::SignalIsolator proxy;
        QObject::connect(object, signal_, &proxy, &detail::SignalIsolator::proxy<Args...>);
        this->yield(&proxy);
        return detail::argsToTuple<Args...>(proxy.getResult());
    }

private:
    friend class Async;
    class Private;

    Await (std::shared_ptr<Private> d);
    Await (const Await &);
    Await & operator = (const Await &);
    Await (Await &&);
    Await & operator = (Await &&);
    ~Await ();

    void yield(QObject * object) const;

    std::shared_ptr<Private> d;
};

}

#endif
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library 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 2.1 of the License, or (at your option) any later version.
 *
 * This library 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 Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id: geometry.hpp 39 2005-04-10 20:39:53Z pavlenko $

#ifndef GEOMETRY_HPP
#define GEOMETRY_HPP

// mapnik
#include <mapnik/vertex_vector.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/geom_util.hpp>
// boost
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <boost/ptr_container/ptr_vector.hpp>

namespace mapnik {
enum GeomType {
    Point = 1,
    LineString = 2,
    Polygon = 3
};

template <typename T>
class geometry : private boost::noncopyable
{
public:
    typedef T vertex_type;
    typedef typename vertex_type::type value_type;
public:
    geometry () {}

    box2d<double> envelope() const
    {
        box2d<double> result;
        double x(0);
        double y(0);
        rewind(0);
        for (unsigned i=0;i<num_points();++i)
        {
            vertex(&x,&y);
            if (i==0)
            {
                result.init(x,y,x,y);
            }
            else
            {
                result.expand_to_include(x,y);
            }
        }
        return result;
    }

    virtual int type() const=0;
    virtual double area() const=0;
    virtual bool hit_test(value_type x,value_type y, double tol) const=0;
    virtual void label_position(double *x, double *y) const=0;
    virtual void move_to(value_type x,value_type y)=0;
    virtual void line_to(value_type x,value_type y)=0;
    virtual unsigned num_points() const = 0;
    virtual unsigned vertex(double* x, double* y) const=0;
    virtual void rewind(unsigned) const=0;
    virtual void set_capacity(size_t size)=0;
    virtual ~geometry() {}
};

template <typename T>
class point : public geometry<T>
{
    typedef geometry<T> geometry_base;
    typedef typename geometry<T>::vertex_type vertex_type;
    typedef typename geometry<T>::value_type value_type;
private:
    vertex_type pt_;
public:
    point() : geometry<T>() {}

    int type() const
    {
        return Point;
    }

    double area() const
    {
        return 0;
    }

    void label_position(double *x, double *y) const
    {
        *x = pt_.x;
        *y = pt_.y;
    }

    void move_to(value_type x,value_type y)
    {
        pt_.x = x;
        pt_.y = y;
    }

    void line_to(value_type ,value_type ) {}

    unsigned num_points() const
    {
        return 1;
    }

    unsigned vertex(double* x, double* y) const
    {
        *x = pt_.x;
        *y = pt_.y;
        return SEG_LINETO;
    }

    void rewind(unsigned ) const {}

    bool hit_test(value_type x,value_type y, double tol) const
    {
        return point_in_circle(pt_.x,pt_.y, x,y,tol);
    }

    void set_capacity(size_t) {}
    virtual ~point() {}
};

template <typename T, template <typename> class Container=vertex_vector2>
class polygon //: public geometry<T>
{
    typedef T vertex_type;
    typedef typename vertex_type::type value_type;
    typedef Container<vertex_type> container_type;

private:
    container_type cont_;
    mutable unsigned itr_;
public:
    polygon()
        : //geometry_base(),
        itr_(0)
    {}

    int type() const
    {
        return Polygon;
    }

    double area() const
    {
        unsigned i;
        double sum = 0.0;
        double x(0);
        double y(0);
        rewind(0);
        double xs = x;
        double ys = y;
        for (unsigned i=0;i<num_points();++i)
        {
            double x0,y0;
            vertex(&x0,&y0);
            sum += x * y0 - y * x0;
            x = x0;
            y = y0;
        }
        return (sum + x * ys - y * xs) * 0.5;
    }

    box2d<double> envelope() const
    {
        box2d<double> result;
        double x(0);
        double y(0);
        rewind(0);
        for (unsigned i=0;i<num_points();++i)
        {
            vertex(&x,&y);
            if (i==0)
            {
                result.init(x,y,x,y);
            }
            else
            {
                result.expand_to_include(x,y);
            }
        }
        return result;
    }
    void label_position(double *x, double *y) const
    {
        unsigned size = cont_.size();
        if (size < 3)
        {
            cont_.get_vertex(0,x,y);
            return;
        }

        double ai;
        double atmp = 0;
        double xtmp = 0;
        double ytmp = 0;
        double x0 =0;
        double y0 =0;
        double x1 =0;
        double y1 =0;
        double ox =0;
        double oy =0;

        unsigned i;

        // Use first point as origin to improve numerical accuracy
        cont_.get_vertex(0,&ox,&oy);

        for (i = 0; i < size-1; i++)
        {
            cont_.get_vertex(i,&x0,&y0);
            cont_.get_vertex(i+1,&x1,&y1);

            x0 -= ox; y0 -= oy;
            x1 -= ox; y1 -= oy;

            ai = x0 * y1 - x1 * y0;
            atmp += ai;
            xtmp += (x1 + x0) * ai;
            ytmp += (y1 + y0) * ai;
        }
        if (atmp != 0)
        {
            *x = (xtmp/(3*atmp)) + ox;
            *y = (ytmp/(3*atmp)) + oy;
            return;
        }
        *x=x0;
        *y=y0;
    }

    void middle_point(double *x, double *y) const
    {
        // calculate mid point on path
        double x0=0;
        double y0=0;
        double x1=0;
        double y1=0;

        unsigned size = cont_.size();
        if (size == 1)
        {
            cont_.get_vertex(0,x,y);
        }
        else if (size == 2)
        {
            cont_.get_vertex(0,&x0,&y0);
            cont_.get_vertex(1,&x1,&y1);
            *x = 0.5 * (x1 + x0);
            *y = 0.5 * (y1 + y0);
        }
        else
        {
            double len=0.0;
            for (unsigned pos = 1; pos < size; ++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                len += std::sqrt(dx * dx + dy * dy);
            }
            double midlen = 0.5 * len;
            double dist = 0.0;
            for (unsigned pos = 1; pos < size;++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                double seg_len = std::sqrt(dx * dx + dy * dy);
                if (( dist + seg_len) >= midlen)
                {
                    double r = (midlen - dist)/seg_len;
                    *x = x0 + (x1 - x0) * r;
                    *y = y0 + (y1 - y0) * r;
                    break;
                }
                dist += seg_len;
            }
        }
    }

    void line_to(value_type x,value_type y)
    {
        cont_.push_back(x,y,SEG_LINETO);
    }

    void move_to(value_type x,value_type y)
    {
        cont_.push_back(x,y,SEG_MOVETO);
    }

    unsigned num_points() const
    {
        return cont_.size();
    }

    unsigned vertex(double* x, double* y) const
    {
        return cont_.get_vertex(itr_++,x,y);
    }

    void rewind(unsigned ) const
    {
        itr_=0;
    }

    bool hit_test(value_type x,value_type y, double) const
    {
        return point_inside_path(x,y,cont_.begin(),cont_.end());
    }

    void set_capacity(size_t size)
    {
        cont_.set_capacity(size);
    }
    //virtual ~polygon() {}
};

template <typename T, template <typename> class Container=vertex_vector2>
class line_string : public geometry<T>
{
    typedef geometry<T> geometry_base;
    typedef typename geometry_base::value_type value_type;
    typedef typename geometry<T>::vertex_type vertex_type;
    typedef Container<vertex_type> container_type;
private:
    container_type cont_;
    mutable unsigned itr_;
public:
    line_string()
        : geometry_base(),
          itr_(0)
    {}

    int type() const
    {
        return LineString;
    }

    double area() const
    {
        return 0;
    }

    void label_position(double *x, double *y) const
    {
        // calculate mid point on line string
        double x0=0;
        double y0=0;
        double x1=0;
        double y1=0;

        unsigned size = cont_.size();
        if (size == 1)
        {
            cont_.get_vertex(0,x,y);
        }
        else if (size == 2)
        {
            cont_.get_vertex(0,&x0,&y0);
            cont_.get_vertex(1,&x1,&y1);
            *x = 0.5 * (x1 + x0);
            *y = 0.5 * (y1 + y0);
        }
        else
        {
            double len=0.0;
            for (unsigned pos = 1; pos < size; ++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                len += std::sqrt(dx * dx + dy * dy);
            }
            double midlen = 0.5 * len;
            double dist = 0.0;
            for (unsigned pos = 1; pos < size;++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                double seg_len = std::sqrt(dx * dx + dy * dy);
                if (( dist + seg_len) >= midlen)
                {
                    double r = (midlen - dist)/seg_len;
                    *x = x0 + (x1 - x0) * r;
                    *y = y0 + (y1 - y0) * r;
                    break;
                }
                dist += seg_len;
            }
        }
    }
    void line_to(value_type x,value_type y)
    {
        cont_.push_back(x,y,SEG_LINETO);
    }

    void move_to(value_type x,value_type y)
    {
        cont_.push_back(x,y,SEG_MOVETO);
    }

    unsigned num_points() const
    {
        return cont_.size();
    }

    unsigned vertex(double* x, double* y) const
    {
        return cont_.get_vertex(itr_++,x,y);
    }

    void rewind(unsigned ) const
    {
        itr_=0;
    }

    bool hit_test(value_type x,value_type y, double tol) const
    {
        return point_on_path(x,y,cont_.begin(),cont_.end(),tol);
    }

    void set_capacity(size_t size)
    {
        cont_.set_capacity(size);
    }
    virtual ~line_string() {}
};

//typedef point<vertex2d> point_impl;
//typedef line_string<vertex2d,vertex_vector2> line_string_impl;
typedef polygon<vertex2d,vertex_vector2> point_impl;
typedef polygon<vertex2d,vertex_vector2> line_string_impl;
typedef polygon<vertex2d,vertex_vector2> polygon_impl;

typedef polygon_impl geometry2d;
typedef boost::shared_ptr<geometry2d> geometry_ptr;
typedef boost::ptr_vector<geometry2d> geometry_containter;
}

#endif //GEOMETRY_HPP
<commit_msg>+ remove ununsed varialble<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library 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 2.1 of the License, or (at your option) any later version.
 *
 * This library 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 Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id: geometry.hpp 39 2005-04-10 20:39:53Z pavlenko $

#ifndef GEOMETRY_HPP
#define GEOMETRY_HPP

// mapnik
#include <mapnik/vertex_vector.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/geom_util.hpp>
// boost
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <boost/ptr_container/ptr_vector.hpp>

namespace mapnik {
enum GeomType {
    Point = 1,
    LineString = 2,
    Polygon = 3
};

template <typename T>
class geometry : private boost::noncopyable
{
public:
    typedef T vertex_type;
    typedef typename vertex_type::type value_type;
public:
    geometry () {}

    box2d<double> envelope() const
    {
        box2d<double> result;
        double x(0);
        double y(0);
        rewind(0);
        for (unsigned i=0;i<num_points();++i)
        {
            vertex(&x,&y);
            if (i==0)
            {
                result.init(x,y,x,y);
            }
            else
            {
                result.expand_to_include(x,y);
            }
        }
        return result;
    }

    virtual int type() const=0;
    virtual double area() const=0;
    virtual bool hit_test(value_type x,value_type y, double tol) const=0;
    virtual void label_position(double *x, double *y) const=0;
    virtual void move_to(value_type x,value_type y)=0;
    virtual void line_to(value_type x,value_type y)=0;
    virtual unsigned num_points() const = 0;
    virtual unsigned vertex(double* x, double* y) const=0;
    virtual void rewind(unsigned) const=0;
    virtual void set_capacity(size_t size)=0;
    virtual ~geometry() {}
};

template <typename T>
class point : public geometry<T>
{
    typedef geometry<T> geometry_base;
    typedef typename geometry<T>::vertex_type vertex_type;
    typedef typename geometry<T>::value_type value_type;
private:
    vertex_type pt_;
public:
    point() : geometry<T>() {}

    int type() const
    {
        return Point;
    }

    double area() const
    {
        return 0;
    }

    void label_position(double *x, double *y) const
    {
        *x = pt_.x;
        *y = pt_.y;
    }

    void move_to(value_type x,value_type y)
    {
        pt_.x = x;
        pt_.y = y;
    }

    void line_to(value_type ,value_type ) {}

    unsigned num_points() const
    {
        return 1;
    }

    unsigned vertex(double* x, double* y) const
    {
        *x = pt_.x;
        *y = pt_.y;
        return SEG_LINETO;
    }

    void rewind(unsigned ) const {}

    bool hit_test(value_type x,value_type y, double tol) const
    {
        return point_in_circle(pt_.x,pt_.y, x,y,tol);
    }

    void set_capacity(size_t) {}
    virtual ~point() {}
};

template <typename T, template <typename> class Container=vertex_vector2>
class polygon //: public geometry<T>
{
    typedef T vertex_type;
    typedef typename vertex_type::type value_type;
    typedef Container<vertex_type> container_type;

private:
    container_type cont_;
    mutable unsigned itr_;
public:
    polygon()
        : //geometry_base(),
        itr_(0)
    {}

    int type() const
    {
        return Polygon;
    }

    double area() const
    {
        double sum = 0.0;
        double x(0);
        double y(0);
        rewind(0);
        double xs = x;
        double ys = y;
        for (unsigned i=0;i<num_points();++i)
        {
            double x0,y0;
            vertex(&x0,&y0);
            sum += x * y0 - y * x0;
            x = x0;
            y = y0;
        }
        return (sum + x * ys - y * xs) * 0.5;
    }

    box2d<double> envelope() const
    {
        box2d<double> result;
        double x(0);
        double y(0);
        rewind(0);
        for (unsigned i=0;i<num_points();++i)
        {
            vertex(&x,&y);
            if (i==0)
            {
                result.init(x,y,x,y);
            }
            else
            {
                result.expand_to_include(x,y);
            }
        }
        return result;
    }
    void label_position(double *x, double *y) const
    {
        unsigned size = cont_.size();
        if (size < 3)
        {
            cont_.get_vertex(0,x,y);
            return;
        }

        double ai;
        double atmp = 0;
        double xtmp = 0;
        double ytmp = 0;
        double x0 =0;
        double y0 =0;
        double x1 =0;
        double y1 =0;
        double ox =0;
        double oy =0;

        unsigned i;

        // Use first point as origin to improve numerical accuracy
        cont_.get_vertex(0,&ox,&oy);

        for (i = 0; i < size-1; i++)
        {
            cont_.get_vertex(i,&x0,&y0);
            cont_.get_vertex(i+1,&x1,&y1);

            x0 -= ox; y0 -= oy;
            x1 -= ox; y1 -= oy;

            ai = x0 * y1 - x1 * y0;
            atmp += ai;
            xtmp += (x1 + x0) * ai;
            ytmp += (y1 + y0) * ai;
        }
        if (atmp != 0)
        {
            *x = (xtmp/(3*atmp)) + ox;
            *y = (ytmp/(3*atmp)) + oy;
            return;
        }
        *x=x0;
        *y=y0;
    }

    void middle_point(double *x, double *y) const
    {
        // calculate mid point on path
        double x0=0;
        double y0=0;
        double x1=0;
        double y1=0;

        unsigned size = cont_.size();
        if (size == 1)
        {
            cont_.get_vertex(0,x,y);
        }
        else if (size == 2)
        {
            cont_.get_vertex(0,&x0,&y0);
            cont_.get_vertex(1,&x1,&y1);
            *x = 0.5 * (x1 + x0);
            *y = 0.5 * (y1 + y0);
        }
        else
        {
            double len=0.0;
            for (unsigned pos = 1; pos < size; ++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                len += std::sqrt(dx * dx + dy * dy);
            }
            double midlen = 0.5 * len;
            double dist = 0.0;
            for (unsigned pos = 1; pos < size;++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                double seg_len = std::sqrt(dx * dx + dy * dy);
                if (( dist + seg_len) >= midlen)
                {
                    double r = (midlen - dist)/seg_len;
                    *x = x0 + (x1 - x0) * r;
                    *y = y0 + (y1 - y0) * r;
                    break;
                }
                dist += seg_len;
            }
        }
    }

    void line_to(value_type x,value_type y)
    {
        cont_.push_back(x,y,SEG_LINETO);
    }

    void move_to(value_type x,value_type y)
    {
        cont_.push_back(x,y,SEG_MOVETO);
    }

    unsigned num_points() const
    {
        return cont_.size();
    }

    unsigned vertex(double* x, double* y) const
    {
        return cont_.get_vertex(itr_++,x,y);
    }

    void rewind(unsigned ) const
    {
        itr_=0;
    }

    bool hit_test(value_type x,value_type y, double) const
    {
        return point_inside_path(x,y,cont_.begin(),cont_.end());
    }

    void set_capacity(size_t size)
    {
        cont_.set_capacity(size);
    }
    //virtual ~polygon() {}
};

template <typename T, template <typename> class Container=vertex_vector2>
class line_string : public geometry<T>
{
    typedef geometry<T> geometry_base;
    typedef typename geometry_base::value_type value_type;
    typedef typename geometry<T>::vertex_type vertex_type;
    typedef Container<vertex_type> container_type;
private:
    container_type cont_;
    mutable unsigned itr_;
public:
    line_string()
        : geometry_base(),
          itr_(0)
    {}

    int type() const
    {
        return LineString;
    }

    double area() const
    {
        return 0;
    }

    void label_position(double *x, double *y) const
    {
        // calculate mid point on line string
        double x0=0;
        double y0=0;
        double x1=0;
        double y1=0;

        unsigned size = cont_.size();
        if (size == 1)
        {
            cont_.get_vertex(0,x,y);
        }
        else if (size == 2)
        {
            cont_.get_vertex(0,&x0,&y0);
            cont_.get_vertex(1,&x1,&y1);
            *x = 0.5 * (x1 + x0);
            *y = 0.5 * (y1 + y0);
        }
        else
        {
            double len=0.0;
            for (unsigned pos = 1; pos < size; ++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                len += std::sqrt(dx * dx + dy * dy);
            }
            double midlen = 0.5 * len;
            double dist = 0.0;
            for (unsigned pos = 1; pos < size;++pos)
            {
                cont_.get_vertex(pos-1,&x0,&y0);
                cont_.get_vertex(pos,&x1,&y1);
                double dx = x1 - x0;
                double dy = y1 - y0;
                double seg_len = std::sqrt(dx * dx + dy * dy);
                if (( dist + seg_len) >= midlen)
                {
                    double r = (midlen - dist)/seg_len;
                    *x = x0 + (x1 - x0) * r;
                    *y = y0 + (y1 - y0) * r;
                    break;
                }
                dist += seg_len;
            }
        }
    }
    void line_to(value_type x,value_type y)
    {
        cont_.push_back(x,y,SEG_LINETO);
    }

    void move_to(value_type x,value_type y)
    {
        cont_.push_back(x,y,SEG_MOVETO);
    }

    unsigned num_points() const
    {
        return cont_.size();
    }

    unsigned vertex(double* x, double* y) const
    {
        return cont_.get_vertex(itr_++,x,y);
    }

    void rewind(unsigned ) const
    {
        itr_=0;
    }

    bool hit_test(value_type x,value_type y, double tol) const
    {
        return point_on_path(x,y,cont_.begin(),cont_.end(),tol);
    }

    void set_capacity(size_t size)
    {
        cont_.set_capacity(size);
    }
    virtual ~line_string() {}
};

//typedef point<vertex2d> point_impl;
//typedef line_string<vertex2d,vertex_vector2> line_string_impl;
typedef polygon<vertex2d,vertex_vector2> point_impl;
typedef polygon<vertex2d,vertex_vector2> line_string_impl;
typedef polygon<vertex2d,vertex_vector2> polygon_impl;

typedef polygon_impl geometry2d;
typedef boost::shared_ptr<geometry2d> geometry_ptr;
typedef boost::ptr_vector<geometry2d> geometry_containter;
}

#endif //GEOMETRY_HPP
<|endoftext|>


<commit_before>template <typename T>
class stack
{
public:
	stack() : array_(nullptr), array_size_(0), count_(0) {} /*noexcept*/
	stack(const stack & _stack); /*noexcept*/
	stack& operator=(const stack & _stack); /*basic*/
	size_t count() const; /*noexcept*/
	void push(T const &); /*strong*/
	void pop(); /*noexcept*/
	T& top(); /*strong*/
	~stack(); /*noexcept*/
private:
	T* array_;
	size_t array_size_;
	size_t count_;
	void rereserve(size_t new_size, size_t n_elements_to_copy); /*strong*/
	T* newCopiedArray(const T* source, size_t source_size, size_t destination_size); /*strong*/
};
//T: T(), operator=,
template<typename T>
stack<T>::stack(const stack & _stack)
	: array_(newCopiedArray(_stack.array_, _stack.count_, _stack.array_size_)),
	array_size_(array_ != nullptr ? _stack.array_size_ : 0),
	count_(array_ != nullptr ? _stack.count_ : 0) {
	;
}

template<typename T>
stack<T>& stack<T>::operator=(const stack & _stack) {
	if (this == &_stack) {
		return *this;
	}
	if (array_size_ < _stack.count_) {
		T* new_array = new T[_stack.array_size_];
		delete[] array_;
		array_ = new_array;
		array_size_ = _stack.array_size_;
	}
	std::copy(_stack.array_, _stack.array_ + _stack.count_, array_);
	count_ = _stack.count_;
	return *this;
}

template<typename T>
size_t stack<T>::count() const
{
	return count_;
}

template<typename T>
void stack<T>::push(T const & new_element)
{
	if (count_ >= array_size_) {
		rereserve((array_size_ * 3) / 2 + 1, count_); //can throw
	}
	try {
		array_[count_] = new_element;
	}
	catch (...) {
		count_--;
	}
	count_++;
}

template<typename T>
void stack<T>::pop()
{
	if (count_ != 0) {
		count_--;
	}
}

template<typename T>
T& stack<T>::top()
{
	if (count_ == 0) {
		throw ("count_ == 0");
	}
	return array_[count_ - 1];
}

template<typename T>
stack<T>::~stack()
{
	delete[] array_;
}

template<typename T>
void stack<T>::rereserve(size_t new_size, size_t n_elements_to_copy) {
	T* new_array = newCopiedArray(array_, count_, new_size);
	if (new_array == nullptr) throw(1);
	delete[] array_;
	array_ = new_array;
	array_size_ = new_size;
}

template<typename T>
T* stack<T>::newCopiedArray(const T* source, size_t source_count, size_t destination_size)
{
	T* new_array = nullptr;
	try {
		new_array = new T[destination_size];
		std::copy(source, source + source_count, new_array); //Throws if an element assignment throws
	}
	catch (...) {
		delete[] new_array;
		new_array = nullptr;
	}
	return new_array;
}
<commit_msg>Strong warranty<commit_after>template <typename T>
class stack
{
public:
	stack() : array_(nullptr), array_size_(0), count_(0) {} /*noexcept*/
	stack(const stack & _stack); /*noexcept*/
	stack& operator=(const stack & _stack); /*strong*/
	size_t count() const; /*noexcept*/
	void push(T const &); /*strong*/
	void pop(); /*noexcept*/
	T& top(); /*strong*/
	~stack(); /*noexcept*/
private:
	T* array_;
	size_t array_size_;
	size_t count_;
	void rereserve(size_t new_size, size_t n_elements_to_copy); /*strong*/
	T* newCopiedArray(const T* source, size_t source_size, size_t destination_size); /*strong*/
};
//T: T(), operator=,
template<typename T>
stack<T>::stack(const stack & _stack)
	: array_(newCopiedArray(_stack.array_, _stack.count_, _stack.array_size_)),
	array_size_(array_ != nullptr ? _stack.array_size_ : 0),
	count_(array_ != nullptr ? _stack.count_ : 0) {
	;
}

template<typename T>
stack<T>& stack<T>::operator=(const stack & _stack) {
	if (this == &_stack) {
		return *this;
	}
	if (array_size_ < _stack.count_) {
		T* new_array = new T[_stack.array_size_];
		delete[] array_;
		array_ = new_array;
	}
	T* midterm = new T[_stack.array_size_];								//Only for strict
	std::copy(_stack.array_, _stack.array_ + _stack.count_, midterm);   //warranty and copy.
	array_ = midterm;
	count_ = _stack.count_;
	array_size_ = _stack.array_size_;
	return *this;
}

template<typename T>
size_t stack<T>::count() const
{
	return count_;
}

template<typename T>
void stack<T>::push(T const & new_element)
{
	if (count_ >= array_size_) {
		rereserve((array_size_ * 3) / 2 + 1, count_); //can throw
	}
	try {
		array_[count_] = new_element;
	}
	catch (...) {
		count_--;
	}
	count_++;
}

template<typename T>
void stack<T>::pop()
{
	if (count_ != 0) {
		count_--;
	}
}

template<typename T>
T& stack<T>::top()
{
	if (count_ == 0) {
		throw ("count_ == 0");
	}
	return array_[count_ - 1];
}

template<typename T>
stack<T>::~stack()
{
	delete[] array_;
}

template<typename T>
void stack<T>::rereserve(size_t new_size, size_t n_elements_to_copy) {
	T* new_array = newCopiedArray(array_, count_, new_size);
	if (new_array == nullptr) throw(1);
	delete[] array_;
	array_ = new_array;
	array_size_ = new_size;
}

template<typename T>
T* stack<T>::newCopiedArray(const T* source, size_t source_count, size_t destination_size)
{
	T* new_array = nullptr;
	try {
		new_array = new T[destination_size];
		std::copy(source, source + source_count, new_array); //Throws if an element assignment throws
	}
	catch (...) {
		delete[] new_array;
		new_array = nullptr;
	}
	return new_array;
}
<|endoftext|>