<commit_before>///
/// @file  generate_phi.hpp
/// @brief The PhiCache class calculates the partial sieve function
///        (a.k.a. Legendre-sum) using the recursive formula:
///        phi(x, a) = phi(x, a - 1) - phi(x / primes[a], a - 1).
///        phi(x, a) counts the numbers <= x that are not divisible
///        by any of the first a primes. The algorithm used is an
///        optimized version of the recursive algorithm described in
///        Tomás Oliveira e Silva's paper [2]. I have added 5
///        optimizations to my implementation which speed up the
///        computation by several orders of magnitude.
///
///    [1] In-depth description of primecount's phi(x, a) implementation:
///        https://github.com/kimwalisch/primecount/blob/master/doc/Partial-Sieve-Function.md
///    [2] Tomás Oliveira e Silva, Computing pi(x): the combinatorial
///        method, Revista do DETUA, vol. 4, no. 6, March 2006, p. 761.
///        http://sweet.ua.pt/tos/bib/5.4.pdf
///
/// Copyright (C) 2021 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#ifndef GENERATE_PHI_HPP
#define GENERATE_PHI_HPP

#include <primecount-internal.hpp>
#include <BitSieve240.hpp>
#include <fast_div.hpp>
#include <imath.hpp>
#include <min.hpp>
#include <PhiTiny.hpp>
#include <PiTable.hpp>
#include <pod_vector.hpp>
#include <popcnt.hpp>

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

namespace {

using namespace std;
using namespace primecount;

template <typename Primes>
class PhiCache : public BitSieve240
{
public:
  PhiCache(uint64_t x,
           uint64_t a,
           const Primes& primes,
           const PiTable& pi) :
    primes_(primes),
    pi_(pi)
  {
    // We cache phi(x, a) if a <= max_a.
    // The value max_a = 100 has been determined empirically
    // by running benchmarks. Using a smaller or larger
    // max_a with the same amount of memory (max_megabytes)
    // decreases the performance.
    uint64_t max_a = 100;
    uint64_t tiny_a = PhiTiny::max_a();

    // Make sure we cache only frequently used values
    a = a - min(a, 30);
    max_a = min(a, max_a);

    if (max_a <= tiny_a)
      return;

    // We cache phi(x, a) if x <= max_x.
    // The value max_x = sqrt(x) has been determined by running
    // S2_hard(x) and D(x) benchmarks from 1e12 to 1e21.
    uint64_t max_x = isqrt(x);

    // The cache (i.e. the sieve array)
    // uses at most max_megabytes per thread.
    uint64_t max_megabytes = 16;
    uint64_t indexes = max_a - tiny_a;
    uint64_t max_bytes = max_megabytes << 20;
    uint64_t max_bytes_per_index = max_bytes / indexes;
    uint64_t numbers_per_byte = 240 / sizeof(sieve_t);
    uint64_t cache_limit = max_bytes_per_index * numbers_per_byte;
    max_x = min(max_x, cache_limit);
    max_x_size_ = ceil_div(max_x, 240);

    // For tiny computations caching is not worth it
    if (max_x_size_ < 8)
      return;

    // Make sure that there are no uninitialized
    // bits in the last sieve array element.
    assert(max_x_size_ > 0);
    max_x_ = max_x_size_ * 240 - 1;
    max_a_ = max_a;
    sieve_.resize(max_a_ + 1);
  }

  /// Calculate phi(x, a) using the recursive formula:
  /// phi(x, a) = phi(x, a - 1) - phi(x / primes[a], a - 1)
  ///
  template <int SIGN>
  int64_t phi(int64_t x, int64_t a)
  {
    if (x <= (int64_t) primes_[a])
      return SIGN;
    else if (is_phi_tiny(a))
      return phi_tiny(x, a) * SIGN;
    else if (is_pix(x, a))
      return (pi_[x] - a + 1) * SIGN;
    else if (is_cached(x, a))
      return phi_cache(x, a) * SIGN;

    // Cache all small phi(x, i) results with:
    // x <= max_x && i <= min(a, max_a)
    sieve_cache(x, a);

    int64_t sqrtx = isqrt(x);
    int64_t c = PhiTiny::get_c(sqrtx);
    int64_t larger_c = min(a, max_a_cached_);
    int64_t sum, i;

    if (c >= larger_c ||
        !is_cached(x, larger_c))
      sum = phi_tiny(x, c) * SIGN;
    else
    {
      c = larger_c;
      assert(larger_c <= a);
      sum = phi_cache(x, c) * SIGN;
    }

    for (i = c + 1; i <= a; i++)
    {
      // phi(x / prime[i], i - 1) = 1 if x / prime[i] <= prime[i-1].
      // However we can do slightly better:
      // If prime[i] > sqrt(x) and prime[i-1] <= sqrt(x) then
      // phi(x / prime[i], i - 1) = 1 even if x / prime[i] > prime[i-1].
      // This works because in this case there is no other prime
      // inside the interval ]prime[i-1], x / prime[i]].
      if (primes_[i] > sqrtx)
        break;
      int64_t xp = fast_div(x, primes_[i]);
      if (is_pix(xp, i - 1))
        break;
      sum += phi<-SIGN>(xp, i - 1);
    }

    for (; i <= a; i++)
    {
      if (primes_[i] > sqrtx)
        break;
      int64_t xp = fast_div(x, primes_[i]);
      // if a >= pi(sqrt(x)): phi(x, a) = pi(x) - a + 1
      // phi(xp, i - 1) = pi(xp) - (i - 1) + 1
      // phi(xp, i - 1) = pi(xp) - i + 2
      sum += (pi_[xp] - i + 2) * -SIGN;
    }

    // phi(xp, i - 1) = 1 for i in [i, a]
    sum += (a + 1 - i) * -SIGN;
  }

private:
  /// phi(x, a) counts the numbers <= x that are not divisible by any of
  /// the first a primes. If a >= pi(sqrt(x)) then phi(x, a) counts the
  /// number of primes <= x, minus the first a primes, plus the number 1.
  /// Hence if a >= pi(sqrt(x)): phi(x, a) = pi(x) - a + 1.
  ///
  bool is_pix(int64_t x, int64_t a) const
  {
    return x < pi_.size() &&
           x < isquare(primes_[a + 1]);
  }

  bool is_cached(uint64_t x, uint64_t a) const
  {
    return x <= max_x_ &&
           a <= max_a_cached_;
  }

  int64_t phi_cache(uint64_t x, uint64_t a) const
  {
    assert(a < sieve_.size());
    assert(x / 240 < sieve_[a].size());

    uint64_t count = sieve_[a][x / 240].count;
    uint64_t bits = sieve_[a][x / 240].bits;
    uint64_t bitmask = unset_larger_[x % 240];
    return count + popcnt64(bits & bitmask);
  }

  /// Cache phi(x, i) results with: x <= max_x && i <= min(a, max_a).
  /// Eratosthenes-like sieving algorithm that removes the first a primes
  /// and their multiples from the sieve array. Additionally this
  /// algorithm counts the numbers that are not divisible by any of the
  /// first a primes after sieving has completed. After sieving and
  /// counting has finished phi(x, a) results can be retrieved from the
  /// cache in O(1) using the phi_cache(x, a) method.
  ///
  void sieve_cache(uint64_t x, uint64_t a)
  {
    a = min(a, max_a_);

    if (x > max_x_ ||
        a <= max_a_cached_)
      return;

    uint64_t i = max_a_cached_ + 1;
    uint64_t tiny_a = PhiTiny::max_a();
    max_a_cached_ = a;
    i = max(i, 3);

    for (; i <= a; i++)
    {
      // Each bit in the sieve array corresponds to an integer that
      // is not divisible by 2, 3 and 5. The 8 bits of each byte
      // correspond to the offsets { 1, 7, 11, 13, 17, 19, 23, 29 }.
      if (i == 3)
        sieve_[i].resize(max_x_size_);
      else
      {
        // Initalize phi(x, i) with phi(x, i - 1)
        if (i - 1 <= tiny_a)
          sieve_[i] = std::move(sieve_[i - 1]);
        else
          sieve_[i] = sieve_[i - 1];

        // Remove prime[i] and its multiples
        uint64_t prime = primes_[i];
        if (prime <= max_x_)
          sieve_[i][prime / 240].bits &= unset_bit_[prime % 240];
        for (uint64_t n = prime * prime; n <= max_x_; n += prime * 2)
          sieve_[i][n / 240].bits &= unset_bit_[n % 240];

        if (i > tiny_a)
        {
          uint64_t count = 0;

          // Fill an array with the cumulative 1 bit counts.
          // sieve[i][j] contains the count of numbers < j * 240 that
          // are not divisible by any of the first i primes.
          for (auto& sieve : sieve_[i])
          {
            sieve.count = (uint32_t) count;
            count += popcnt64(sieve.bits);
          }
        }
      }
    }
  }

  uint64_t max_x_ = 0;
  uint64_t max_x_size_ = 0;
  uint64_t max_a_cached_ = 0;
  uint64_t max_a_ = 0;

  /// Packing sieve_t increases the cache's capacity by 25%
  /// which improves performance by up to 10%.
  #pragma pack(push, 1)
  struct sieve_t
  {
    uint32_t count = 0;
    uint64_t bits = ~0ull;
  };

  #pragma pack(pop)

  /// sieve[a] contains only numbers that are not divisible
  /// by any of the the first a primes. sieve[a][i].count
  /// contains the count of numbers < i * 240 that are not
  /// divisible by any of the first a primes.
  vector<vector<sieve_t>> sieve_;
  const Primes& primes_;
  const PiTable& pi_;
};

/// Returns a vector with phi(x, i - 1) values such that
/// phi[i] = phi(x, i - 1) for 1 <= i <= a.
/// phi(x, a) counts the numbers <= x that are not
/// divisible by any of the first a primes.
///
template <typename Primes>
pod_vector<int64_t>
generate_phi(int64_t x,
             int64_t a,
             const Primes& primes,
             const PiTable& pi)
{
  int64_t size = a + 1;
  pod_vector<int64_t> phi(size);
  phi[0] = 0;

  if (size > 1)
  {
    if ((int64_t) primes[a] > x)
      a = pi[x];

    phi[1] = x;
    int64_t i = 2;
    int64_t sqrtx = isqrt(x);
    PhiCache<Primes> cache(x, a, primes, pi);

    // 2 <= i <= pi(sqrt(x)) + 1
    for (; i <= a && primes[i - 1] <= sqrtx; i++)
      phi[i] = phi[i - 1] + cache.template phi<-1>(x / primes[i - 1], i - 2);

    // pi(sqrt(x)) + 1 < i <= a
    for (; i <= a; i++)
      phi[i] = phi[i - 1] - (x > 0);

    // a < i < size
    for (; i < size; i++)
      phi[i] = x > 0;
  }

  return phi;
}

} // namespace

#endif
<commit_msg>Fix copy paste bug<commit_after>///
/// @file  generate_phi.hpp
/// @brief The PhiCache class calculates the partial sieve function
///        (a.k.a. Legendre-sum) using the recursive formula:
///        phi(x, a) = phi(x, a - 1) - phi(x / primes[a], a - 1).
///        phi(x, a) counts the numbers <= x that are not divisible
///        by any of the first a primes. The algorithm used is an
///        optimized version of the recursive algorithm described in
///        Tomás Oliveira e Silva's paper [2]. I have added 5
///        optimizations to my implementation which speed up the
///        computation by several orders of magnitude.
///
///    [1] In-depth description of primecount's phi(x, a) implementation:
///        https://github.com/kimwalisch/primecount/blob/master/doc/Partial-Sieve-Function.md
///    [2] Tomás Oliveira e Silva, Computing pi(x): the combinatorial
///        method, Revista do DETUA, vol. 4, no. 6, March 2006, p. 761.
///        http://sweet.ua.pt/tos/bib/5.4.pdf
///
/// Copyright (C) 2021 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#ifndef GENERATE_PHI_HPP
#define GENERATE_PHI_HPP

#include <primecount-internal.hpp>
#include <BitSieve240.hpp>
#include <fast_div.hpp>
#include <imath.hpp>
#include <min.hpp>
#include <PhiTiny.hpp>
#include <PiTable.hpp>
#include <pod_vector.hpp>
#include <popcnt.hpp>

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

namespace {

using namespace std;
using namespace primecount;

template <typename Primes>
class PhiCache : public BitSieve240
{
public:
  PhiCache(uint64_t x,
           uint64_t a,
           const Primes& primes,
           const PiTable& pi) :
    primes_(primes),
    pi_(pi)
  {
    // We cache phi(x, a) if a <= max_a.
    // The value max_a = 100 has been determined empirically
    // by running benchmarks. Using a smaller or larger
    // max_a with the same amount of memory (max_megabytes)
    // decreases the performance.
    uint64_t max_a = 100;
    uint64_t tiny_a = PhiTiny::max_a();

    // Make sure we cache only frequently used values
    a = a - min(a, 30);
    max_a = min(a, max_a);

    if (max_a <= tiny_a)
      return;

    // We cache phi(x, a) if x <= max_x.
    // The value max_x = sqrt(x) has been determined by running
    // S2_hard(x) and D(x) benchmarks from 1e12 to 1e21.
    uint64_t max_x = isqrt(x);

    // The cache (i.e. the sieve array)
    // uses at most max_megabytes per thread.
    uint64_t max_megabytes = 16;
    uint64_t indexes = max_a - tiny_a;
    uint64_t max_bytes = max_megabytes << 20;
    uint64_t max_bytes_per_index = max_bytes / indexes;
    uint64_t numbers_per_byte = 240 / sizeof(sieve_t);
    uint64_t cache_limit = max_bytes_per_index * numbers_per_byte;
    max_x = min(max_x, cache_limit);
    max_x_size_ = ceil_div(max_x, 240);

    // For tiny computations caching is not worth it
    if (max_x_size_ < 8)
      return;

    // Make sure that there are no uninitialized
    // bits in the last sieve array element.
    assert(max_x_size_ > 0);
    max_x_ = max_x_size_ * 240 - 1;
    max_a_ = max_a;
    sieve_.resize(max_a_ + 1);
  }

  /// Calculate phi(x, a) using the recursive formula:
  /// phi(x, a) = phi(x, a - 1) - phi(x / primes[a], a - 1)
  ///
  template <int SIGN>
  int64_t phi(int64_t x, int64_t a)
  {
    if (x <= (int64_t) primes_[a])
      return SIGN;
    else if (is_phi_tiny(a))
      return phi_tiny(x, a) * SIGN;
    else if (is_pix(x, a))
      return (pi_[x] - a + 1) * SIGN;
    else if (is_cached(x, a))
      return phi_cache(x, a) * SIGN;

    // Cache all small phi(x, i) results with:
    // x <= max_x && i <= min(a, max_a)
    sieve_cache(x, a);

    int64_t sqrtx = isqrt(x);
    int64_t c = PhiTiny::get_c(sqrtx);
    int64_t larger_c = min(a, max_a_cached_);
    int64_t sum, i;

    if (c >= larger_c ||
        !is_cached(x, larger_c))
      sum = phi_tiny(x, c) * SIGN;
    else
    {
      c = larger_c;
      assert(larger_c <= a);
      sum = phi_cache(x, c) * SIGN;
    }

    for (i = c + 1; i <= a; i++)
    {
      // phi(x / prime[i], i - 1) = 1 if x / prime[i] <= prime[i-1].
      // However we can do slightly better:
      // If prime[i] > sqrt(x) and prime[i-1] <= sqrt(x) then
      // phi(x / prime[i], i - 1) = 1 even if x / prime[i] > prime[i-1].
      // This works because in this case there is no other prime
      // inside the interval ]prime[i-1], x / prime[i]].
      if (primes_[i] > sqrtx)
        break;
      int64_t xp = fast_div(x, primes_[i]);
      if (is_pix(xp, i - 1))
        break;
      sum += phi<-SIGN>(xp, i - 1);
    }

    for (; i <= a; i++)
    {
      if (primes_[i] > sqrtx)
        break;
      int64_t xp = fast_div(x, primes_[i]);
      // if a >= pi(sqrt(x)): phi(x, a) = pi(x) - a + 1
      // phi(xp, i - 1) = pi(xp) - (i - 1) + 1
      // phi(xp, i - 1) = pi(xp) - i + 2
      sum += (pi_[xp] - i + 2) * -SIGN;
    }

    // phi(xp, i - 1) = 1 for i in [i, a]
    sum += (a + 1 - i) * -SIGN;
    return sum;
  }

private:
  /// phi(x, a) counts the numbers <= x that are not divisible by any of
  /// the first a primes. If a >= pi(sqrt(x)) then phi(x, a) counts the
  /// number of primes <= x, minus the first a primes, plus the number 1.
  /// Hence if a >= pi(sqrt(x)): phi(x, a) = pi(x) - a + 1.
  ///
  bool is_pix(int64_t x, int64_t a) const
  {
    return x < pi_.size() &&
           x < isquare(primes_[a + 1]);
  }

  bool is_cached(uint64_t x, uint64_t a) const
  {
    return x <= max_x_ &&
           a <= max_a_cached_;
  }

  int64_t phi_cache(uint64_t x, uint64_t a) const
  {
    assert(a < sieve_.size());
    assert(x / 240 < sieve_[a].size());

    uint64_t count = sieve_[a][x / 240].count;
    uint64_t bits = sieve_[a][x / 240].bits;
    uint64_t bitmask = unset_larger_[x % 240];
    return count + popcnt64(bits & bitmask);
  }

  /// Cache phi(x, i) results with: x <= max_x && i <= min(a, max_a).
  /// Eratosthenes-like sieving algorithm that removes the first a primes
  /// and their multiples from the sieve array. Additionally this
  /// algorithm counts the numbers that are not divisible by any of the
  /// first a primes after sieving has completed. After sieving and
  /// counting has finished phi(x, a) results can be retrieved from the
  /// cache in O(1) using the phi_cache(x, a) method.
  ///
  void sieve_cache(uint64_t x, uint64_t a)
  {
    a = min(a, max_a_);

    if (x > max_x_ ||
        a <= max_a_cached_)
      return;

    uint64_t i = max_a_cached_ + 1;
    uint64_t tiny_a = PhiTiny::max_a();
    max_a_cached_ = a;
    i = max(i, 3);

    for (; i <= a; i++)
    {
      // Each bit in the sieve array corresponds to an integer that
      // is not divisible by 2, 3 and 5. The 8 bits of each byte
      // correspond to the offsets { 1, 7, 11, 13, 17, 19, 23, 29 }.
      if (i == 3)
        sieve_[i].resize(max_x_size_);
      else
      {
        // Initalize phi(x, i) with phi(x, i - 1)
        if (i - 1 <= tiny_a)
          sieve_[i] = std::move(sieve_[i - 1]);
        else
          sieve_[i] = sieve_[i - 1];

        // Remove prime[i] and its multiples
        uint64_t prime = primes_[i];
        if (prime <= max_x_)
          sieve_[i][prime / 240].bits &= unset_bit_[prime % 240];
        for (uint64_t n = prime * prime; n <= max_x_; n += prime * 2)
          sieve_[i][n / 240].bits &= unset_bit_[n % 240];

        if (i > tiny_a)
        {
          uint64_t count = 0;

          // Fill an array with the cumulative 1 bit counts.
          // sieve[i][j] contains the count of numbers < j * 240 that
          // are not divisible by any of the first i primes.
          for (auto& sieve : sieve_[i])
          {
            sieve.count = (uint32_t) count;
            count += popcnt64(sieve.bits);
          }
        }
      }
    }
  }

  uint64_t max_x_ = 0;
  uint64_t max_x_size_ = 0;
  uint64_t max_a_cached_ = 0;
  uint64_t max_a_ = 0;

  /// Packing sieve_t increases the cache's capacity by 25%
  /// which improves performance by up to 10%.
  #pragma pack(push, 1)
  struct sieve_t
  {
    uint32_t count = 0;
    uint64_t bits = ~0ull;
  };

  #pragma pack(pop)

  /// sieve[a] contains only numbers that are not divisible
  /// by any of the the first a primes. sieve[a][i].count
  /// contains the count of numbers < i * 240 that are not
  /// divisible by any of the first a primes.
  vector<vector<sieve_t>> sieve_;
  const Primes& primes_;
  const PiTable& pi_;
};

/// Returns a vector with phi(x, i - 1) values such that
/// phi[i] = phi(x, i - 1) for 1 <= i <= a.
/// phi(x, a) counts the numbers <= x that are not
/// divisible by any of the first a primes.
///
template <typename Primes>
pod_vector<int64_t>
generate_phi(int64_t x,
             int64_t a,
             const Primes& primes,
             const PiTable& pi)
{
  int64_t size = a + 1;
  pod_vector<int64_t> phi(size);
  phi[0] = 0;

  if (size > 1)
  {
    if ((int64_t) primes[a] > x)
      a = pi[x];

    phi[1] = x;
    int64_t i = 2;
    int64_t sqrtx = isqrt(x);
    PhiCache<Primes> cache(x, a, primes, pi);

    // 2 <= i <= pi(sqrt(x)) + 1
    for (; i <= a && primes[i - 1] <= sqrtx; i++)
      phi[i] = phi[i - 1] + cache.template phi<-1>(x / primes[i - 1], i - 2);

    // pi(sqrt(x)) + 1 < i <= a
    for (; i <= a; i++)
      phi[i] = phi[i - 1] - (x > 0);

    // a < i < size
    for (; i < size; i++)
      phi[i] = x > 0;
  }

  return phi;
}

} // namespace

#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$

#ifndef VALUE_HPP
#define VALUE_HPP

// mapnik
#include <mapnik/unicode.hpp>
#include <mapnik/config_error.hpp>
// boost
#include <boost/variant.hpp>
// stl
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
// uci
#include <unicode/unistr.h>

namespace mapnik  {

   struct value_null
   {
   };

   typedef boost::variant<value_null,bool,int,double,UnicodeString> value_base;

   namespace impl {
      struct equals
	 : public boost::static_visitor<bool>
      {
            template <typename T, typename U>
	    bool operator() (const T &, const U &) const
	    {
	       return false;
	    }

            template <typename T>
            bool operator() (T lhs, T rhs) const
	    {
	       return lhs == rhs;
	    }

            bool operator() (int lhs, double rhs) const
	    {
	       return  lhs == rhs;
	    }

            bool operator() (double lhs, int rhs) const
	    {
	       return  lhs == rhs;
	    }

            bool operator() (UnicodeString const& lhs,
                             UnicodeString const& rhs) const
	    {
	       return  lhs == rhs;
	    }

            bool operator() (value_null, value_null) const
	    {
	       return false;
	    }
      };

      struct not_equals
	 : public boost::static_visitor<bool>
      {
            template <typename T, typename U>
	    bool operator() (const T &, const U &) const
	    {
	       return true;
	    }

            template <typename T>
            bool operator() (T lhs, T rhs) const
	    {
	       return lhs != rhs;
	    }

            bool operator() (int lhs, double rhs) const
	    {
	       return  lhs != rhs;
	    }

            bool operator() (double lhs, int rhs) const
	    {
	       return  lhs != rhs;
	    }

            bool operator() (UnicodeString const& lhs,
                             UnicodeString const& rhs) const
	    {
	       return  lhs != rhs;
	    }

            bool operator() (value_null, value_null) const
	    {
	       return false;
	    }

            template <typename T>
            bool operator() (value_null, const T &) const
	    {
	       return false;
	    }

            template <typename T>
            bool operator() (const T &, value_null) const
	    {
	       return false;
	    }
      };

      struct greater_than
	 : public boost::static_visitor<bool>
      {
            template <typename T, typename U>
            bool operator()(const T &, const U &) const
	    {
	       return false;
	    }

            template <typename T>
            bool operator()(T lhs, T rhs) const
	    {
	       return lhs > rhs;
	    }

            bool operator() (int lhs, double rhs) const
	    {
	       return  lhs > rhs;
	    }

            bool operator() (double lhs, int rhs) const
	    {
	       return  lhs > rhs;
	    }

            bool operator() (UnicodeString const& lhs, UnicodeString const& rhs) const
	    {
	       return  lhs > rhs;
	    }

            bool operator() (value_null, value_null) const
	    {
	       return false;
	    }
      };

      struct greater_or_equal
	 : public boost::static_visitor<bool>
      {
            template <typename T, typename U>
            bool operator()(const T &, const U &) const
	    {
	       return false;
	    }

            template <typename T>
            bool operator() (T lhs, T rhs) const
	    {
	       return lhs >= rhs;
	    }

            bool operator() (int lhs, double rhs) const
	    {
	       return  lhs >= rhs;
	    }

            bool operator() (double lhs, int rhs) const
	    {
	       return  lhs >= rhs;
	    }

            bool operator() (UnicodeString const& lhs, UnicodeString const& rhs) const
	    {
	       return lhs >= rhs;
	    }

            bool operator() (value_null, value_null) const
	    {
	       return false;
	    }
      };

      struct less_than
	 : public boost::static_visitor<bool>
      {
            template <typename T, typename U>
            bool operator()(const T &, const U &) const
	    {
	       return false;
	    }

            template <typename T>
            bool operator()(T lhs, T rhs) const
	    {
	       return lhs < rhs;
	    }

            bool operator() (int lhs, double rhs) const
	    {
	       return  lhs < rhs;
	    }

            bool operator() (double lhs, int rhs) const
	    {
	       return  lhs < rhs;
	    }

            bool operator()(UnicodeString const& lhs,
                            UnicodeString const& rhs ) const
	    {
	       return lhs < rhs;
	    }

            bool operator() (value_null, value_null) const
	    {
	       return false;
	    }
      };

      struct less_or_equal
	 : public boost::static_visitor<bool>
      {
            template <typename T, typename U>
            bool operator()(const T &, const U &) const
	    {
	       return false;
	    }

            template <typename T>
            bool operator()(T lhs, T rhs) const
	    {
	       return lhs <= rhs;
	    }

            bool operator() (int lhs, double rhs) const
	    {
	       return  lhs <= rhs;
	    }

            bool operator() (double lhs, int rhs) const
	    {
	       return  lhs <= rhs;
	    }

            template <typename T>
            bool operator()(UnicodeString const& lhs,
                            UnicodeString const& rhs ) const
	    {
	       return lhs <= rhs;
	    }

            bool operator() (value_null, value_null) const
	    {
	       return false;
	    }
      };

      template <typename V>
      struct add : public boost::static_visitor<V>
      {
            typedef V value_type;
            template <typename T1, typename T2>
            value_type operator() (T1 const& lhs, T2 const&) const
	    {
	       return lhs;
	    }
            template <typename T>
            value_type operator() (T lhs, T rhs) const
	    {
	       return lhs + rhs ;
	    }

            value_type operator() (UnicodeString const& lhs ,
                                   UnicodeString const& rhs ) const
	    {
	       return lhs + rhs;
	    }

            value_type operator() (double lhs, int rhs) const
	    {
	       return lhs + rhs;
	    }

            value_type operator() (int lhs, double rhs) const
	    {
	       return lhs + rhs;
	    }
      };
      template <typename V>
      struct sub : public boost::static_visitor<V>
      {
            typedef V value_type;
            template <typename T1, typename T2>
            value_type operator() (T1 const& lhs, T2 const&) const
	    {
	       return lhs;
	    }

            template <typename T>
            value_type operator() (T  lhs, T rhs) const
	    {
	       return lhs - rhs ;
	    }

            value_type operator() (UnicodeString const& lhs,
                                   UnicodeString const& ) const
	    {
	       return lhs;
	    }

            value_type operator() (double lhs, int rhs) const
	    {
	       return lhs - rhs;
	    }

            value_type operator() (int lhs, double rhs) const
	    {
	       return lhs - rhs;
	    }
      };

      template <typename V>
      struct mult : public boost::static_visitor<V>
      {
            typedef V value_type;
            template <typename T1, typename T2>
            value_type operator() (T1 const& lhs , T2 const& ) const
	    {
	       return lhs;
	    }
            template <typename T>
            value_type operator() (T lhs, T rhs) const
	    {
	       return lhs * rhs;
	    }

            value_type operator() (UnicodeString const& lhs,
                                   UnicodeString const& ) const
	    {
	       return lhs;
	    }

            value_type operator() (double lhs, int rhs) const
	    {
	       return lhs * rhs;
	    }

            value_type operator() (int lhs, double rhs) const
	    {
	       return lhs * rhs;
	    }
      };

      template <typename V>
      struct div: public boost::static_visitor<V>
      {
            typedef V value_type;
            template <typename T1, typename T2>
            value_type operator() (T1 const& lhs, T2 const&) const
	    {
	       return lhs;
	    }

            template <typename T>
            value_type operator() (T lhs, T rhs) const
	    {
	       return lhs / rhs;
	    }

            value_type operator() (UnicodeString const& lhs,
                                   UnicodeString const&) const
	    {
	       return lhs;
	    }

            value_type operator() (double lhs, int rhs) const
	    {
	       return lhs / rhs;
	    }

            value_type operator() (int lhs, double rhs) const
	    {
	       return lhs / rhs;
	    }
      };

      struct to_bool : public boost::static_visitor<bool>
      {

            template <typename T>
            bool operator() (T val) const
	    {
               throw config_error("Boolean value expected");
	    }

            bool operator() (bool val) const
            {
	       return val;
            }
      };

      struct to_string : public boost::static_visitor<std::string>
      {

            template <typename T>
            std::string operator() (T val) const
	    {
               std::stringstream ss;
	       ss << val;
	       return ss.str();
	    }
            // specializations
            std::string operator() (UnicodeString const& val) const
	    {
               //std::stringstream ss;
               //std::wstring::const_iterator pos = val.begin();
               //ss << std::hex ;
               //for (;pos!=val.end();++pos)
               //{
               //  wchar_t c = *pos;
               //  if (c < 0x80)
               //  {
               //     ss << char(c);
               //  }
               //  else
               //  {
               //     ss << "\\x";
               //     unsigned c0 = (c >> 8) & 0xff;
               //     if (c0) ss << c0;
               //     ss << (c & 0xff);
               //  }
               //}
	       //return ss.str();
               return "TODO";
	    }

            std::string operator() (double val) const
            {
               std::stringstream ss;
	       ss << std::setprecision(16) << val;
	       return ss.str();
            }

            std::string operator() (value_null const& val) const
            {
	       return "";
            }
       };

      struct to_unicode : public boost::static_visitor<UnicodeString>
      {

            template <typename T>
            UnicodeString operator() (T val) const
	    {
               std::basic_ostringstream<char> out;
	       out << val;
               return UnicodeString(out.str().c_str());
	    }

            // specializations
            UnicodeString const& operator() (UnicodeString const& val) const
	    {
               return val;
	    }

            UnicodeString operator() (double val) const
            {
               std::basic_ostringstream<char> out;
	       out << std::setprecision(16) << val;
               return UnicodeString(out.str().c_str());
            }

            UnicodeString operator() (value_null const& val) const
            {
	       return UnicodeString("");
            }
      };

      struct to_expression_string : public boost::static_visitor<std::string>
      {
            std::string operator() (UnicodeString const& val) const
	    {
               /*
               std::stringstream ss;
               UnicodeString::const_iterator pos = val.begin();
               ss << std::hex ;
               for (;pos!=val.end();++pos)
               {
                  wchar_t c = *pos;
                  if (c < 0x80)
                  {
                     ss << char(c);
                  }
                  else
                  {
                     ss << "\\x";
                     unsigned c0 = (c >> 8) & 0xff;
                     if (c0) ss << c0;
                     ss << (c & 0xff);
                  }
               }
	       return "\'" + ss.str() + "\'";
               */
               return "TODO";
	    }

            template <typename T>
            std::string operator() (T val) const
	    {
	       std::stringstream ss;
	       ss << val;
	       return ss.str();
	    }

            std::string operator() (double val) const
            {
               std::stringstream ss;
	       ss << std::setprecision(16) << val;
	       return ss.str();
            }

            std::string operator() (value_null const& val) const
	    {
               return "null";
            }
      };
   }

   class value
   {
	 value_base base_;
	 friend const value operator+(value const&,value const&);
	 friend const value operator-(value const&,value const&);
	 friend const value operator*(value const&,value const&);
	 friend const value operator/(value const&,value const&);

      public:
	 value ()
            : base_(value_null()) {}

	 template <typename T> value(T _val_)
            : base_(_val_) {}

	 bool operator==(value const& other) const
	 {
	    return boost::apply_visitor(impl::equals(),base_,other.base_);
	 }

	 bool operator!=(value const& other) const
	 {
	    return boost::apply_visitor(impl::not_equals(),base_,other.base_);
	 }

	 bool operator>(value const& other) const
	 {
	    return boost::apply_visitor(impl::greater_than(),base_,other.base_);
	 }

	 bool operator>=(value const& other) const
	 {
	    return boost::apply_visitor(impl::greater_or_equal(),base_,other.base_);
	 }

	 bool operator<(value const& other) const
	 {
	    return boost::apply_visitor(impl::less_than(),base_,other.base_);
	 }

	 bool operator<=(value const& other) const
	 {
	    return boost::apply_visitor(impl::less_or_equal(),base_,other.base_);
	 }

	 value_base const& base() const
	 {
	    return base_;
	 }

	 bool to_bool() const
	 {
	    return boost::apply_visitor(impl::to_bool(),base_);
	 }

	 std::string to_expression_string() const
	 {
	    return boost::apply_visitor(impl::to_expression_string(),base_);
	 }

	 std::string to_string() const
	 {
	    return boost::apply_visitor(impl::to_string(),base_);
	 }

         UnicodeString to_unicode() const
         {
            return boost::apply_visitor(impl::to_unicode(),base_);
         }
   };

   inline const value operator+(value const& p1,value const& p2)
   {

      return value(boost::apply_visitor(impl::add<value>(),p1.base_, p2.base_));
   }

   inline const value operator-(value const& p1,value const& p2)
   {

      return value(boost::apply_visitor(impl::sub<value>(),p1.base_, p2.base_));
   }

   inline const value operator*(value const& p1,value const& p2)
   {

      return value(boost::apply_visitor(impl::mult<value>(),p1.base_, p2.base_));
   }

   inline const value operator/(value const& p1,value const& p2)
   {

      return value(boost::apply_visitor(impl::div<value>(),p1.base_, p2.base_));
   }

  template <typename charT, typename traits>
  inline std::basic_ostream<charT,traits>&
  operator << (std::basic_ostream<charT,traits>& out,
	       value const& v)
  {
    out << v.to_string();
    return out;
  }
}

#endif //VALUE_HPP
<commit_msg>+ to_utf8 function to convert from icu::UnicodeString to utf-8 std::string<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$

#ifndef VALUE_HPP
#define VALUE_HPP

// mapnik
#include <mapnik/unicode.hpp>
#include <mapnik/config_error.hpp>
// boost
#include <boost/variant.hpp>
#include <boost/scoped_array.hpp>
// stl
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
// uci
#include <unicode/unistr.h>
#include <unicode/ustring.h>

namespace mapnik  {

   inline void to_utf8(UnicodeString const& input, std::string & target)
   {
      if (input.length() == 0) return;

      const int BUF_SIZE = 256;
      char  buf [BUF_SIZE];
      int len;

      UErrorCode err = U_ZERO_ERROR;
      u_strToUTF8(buf, BUF_SIZE, &len, input.getBuffer(), input.length(), &err);
      if (err == U_BUFFER_OVERFLOW_ERROR || err == U_STRING_NOT_TERMINATED_WARNING )
      {
         boost::scoped_array<char> buf_ptr(new char [len+1]);
         err = U_ZERO_ERROR;
         u_strToUTF8(buf_ptr.get() , len + 1, &len, input.getBuffer(), input.length(), &err);
         target.assign(buf_ptr.get() , len);
      }
      else
      {
         target.assign(buf, len);
      }
   }

   struct value_null
   {
   };

   typedef boost::variant<value_null,bool,int,double,UnicodeString> value_base;

   namespace impl {
      struct equals
	 : public boost::static_visitor<bool>
      {
            template <typename T, typename U>
	    bool operator() (const T &, const U &) const
	    {
	       return false;
	    }

            template <typename T>
            bool operator() (T lhs, T rhs) const
	    {
	       return lhs == rhs;
	    }

            bool operator() (int lhs, double rhs) const
	    {
	       return  lhs == rhs;
	    }

            bool operator() (double lhs, int rhs) const
	    {
	       return  lhs == rhs;
	    }

            bool operator() (UnicodeString const& lhs,
                             UnicodeString const& rhs) const
	    {
	       return  lhs == rhs;
	    }

            bool operator() (value_null, value_null) const
	    {
	       return false;
	    }
      };

      struct not_equals
	 : public boost::static_visitor<bool>
      {
            template <typename T, typename U>
	    bool operator() (const T &, const U &) const
	    {
	       return true;
	    }

            template <typename T>
            bool operator() (T lhs, T rhs) const
	    {
	       return lhs != rhs;
	    }

            bool operator() (int lhs, double rhs) const
	    {
	       return  lhs != rhs;
	    }

            bool operator() (double lhs, int rhs) const
	    {
	       return  lhs != rhs;
	    }

            bool operator() (UnicodeString const& lhs,
                             UnicodeString const& rhs) const
	    {
	       return  lhs != rhs;
	    }

            bool operator() (value_null, value_null) const
	    {
	       return false;
	    }

            template <typename T>
            bool operator() (value_null, const T &) const
	    {
	       return false;
	    }

            template <typename T>
            bool operator() (const T &, value_null) const
	    {
	       return false;
	    }
      };

      struct greater_than
	 : public boost::static_visitor<bool>
      {
            template <typename T, typename U>
            bool operator()(const T &, const U &) const
	    {
	       return false;
	    }

            template <typename T>
            bool operator()(T lhs, T rhs) const
	    {
	       return lhs > rhs;
	    }

            bool operator() (int lhs, double rhs) const
	    {
	       return  lhs > rhs;
	    }

            bool operator() (double lhs, int rhs) const
	    {
	       return  lhs > rhs;
	    }

            bool operator() (UnicodeString const& lhs, UnicodeString const& rhs) const
	    {
	       return  lhs > rhs;
	    }

            bool operator() (value_null, value_null) const
	    {
	       return false;
	    }
      };

      struct greater_or_equal
	 : public boost::static_visitor<bool>
      {
            template <typename T, typename U>
            bool operator()(const T &, const U &) const
	    {
	       return false;
	    }

            template <typename T>
            bool operator() (T lhs, T rhs) const
	    {
	       return lhs >= rhs;
	    }

            bool operator() (int lhs, double rhs) const
	    {
	       return  lhs >= rhs;
	    }

            bool operator() (double lhs, int rhs) const
	    {
	       return  lhs >= rhs;
	    }

            bool operator() (UnicodeString const& lhs, UnicodeString const& rhs) const
	    {
	       return lhs >= rhs;
	    }

            bool operator() (value_null, value_null) const
	    {
	       return false;
	    }
      };

      struct less_than
	 : public boost::static_visitor<bool>
      {
            template <typename T, typename U>
            bool operator()(const T &, const U &) const
	    {
	       return false;
	    }

            template <typename T>
            bool operator()(T lhs, T rhs) const
	    {
	       return lhs < rhs;
	    }

            bool operator() (int lhs, double rhs) const
	    {
	       return  lhs < rhs;
	    }

            bool operator() (double lhs, int rhs) const
	    {
	       return  lhs < rhs;
	    }

            bool operator()(UnicodeString const& lhs,
                            UnicodeString const& rhs ) const
	    {
	       return lhs < rhs;
	    }

            bool operator() (value_null, value_null) const
	    {
	       return false;
	    }
      };

      struct less_or_equal
	 : public boost::static_visitor<bool>
      {
            template <typename T, typename U>
            bool operator()(const T &, const U &) const
	    {
	       return false;
	    }

            template <typename T>
            bool operator()(T lhs, T rhs) const
	    {
	       return lhs <= rhs;
	    }

            bool operator() (int lhs, double rhs) const
	    {
	       return  lhs <= rhs;
	    }

            bool operator() (double lhs, int rhs) const
	    {
	       return  lhs <= rhs;
	    }

            template <typename T>
            bool operator()(UnicodeString const& lhs,
                            UnicodeString const& rhs ) const
	    {
	       return lhs <= rhs;
	    }

            bool operator() (value_null, value_null) const
	    {
	       return false;
	    }
      };

      template <typename V>
      struct add : public boost::static_visitor<V>
      {
            typedef V value_type;
            template <typename T1, typename T2>
            value_type operator() (T1 const& lhs, T2 const&) const
	    {
	       return lhs;
	    }
            template <typename T>
            value_type operator() (T lhs, T rhs) const
	    {
	       return lhs + rhs ;
	    }

            value_type operator() (UnicodeString const& lhs ,
                                   UnicodeString const& rhs ) const
	    {
	       return lhs + rhs;
	    }

            value_type operator() (double lhs, int rhs) const
	    {
	       return lhs + rhs;
	    }

            value_type operator() (int lhs, double rhs) const
	    {
	       return lhs + rhs;
	    }
      };
      template <typename V>
      struct sub : public boost::static_visitor<V>
      {
            typedef V value_type;
            template <typename T1, typename T2>
            value_type operator() (T1 const& lhs, T2 const&) const
	    {
	       return lhs;
	    }

            template <typename T>
            value_type operator() (T  lhs, T rhs) const
	    {
	       return lhs - rhs ;
	    }

            value_type operator() (UnicodeString const& lhs,
                                   UnicodeString const& ) const
	    {
	       return lhs;
	    }

            value_type operator() (double lhs, int rhs) const
	    {
	       return lhs - rhs;
	    }

            value_type operator() (int lhs, double rhs) const
	    {
	       return lhs - rhs;
	    }
      };

      template <typename V>
      struct mult : public boost::static_visitor<V>
      {
            typedef V value_type;
            template <typename T1, typename T2>
            value_type operator() (T1 const& lhs , T2 const& ) const
	    {
	       return lhs;
	    }
            template <typename T>
            value_type operator() (T lhs, T rhs) const
	    {
	       return lhs * rhs;
	    }

            value_type operator() (UnicodeString const& lhs,
                                   UnicodeString const& ) const
	    {
	       return lhs;
	    }

            value_type operator() (double lhs, int rhs) const
	    {
	       return lhs * rhs;
	    }

            value_type operator() (int lhs, double rhs) const
	    {
	       return lhs * rhs;
	    }
      };

      template <typename V>
      struct div: public boost::static_visitor<V>
      {
            typedef V value_type;
            template <typename T1, typename T2>
            value_type operator() (T1 const& lhs, T2 const&) const
	    {
	       return lhs;
	    }

            template <typename T>
            value_type operator() (T lhs, T rhs) const
	    {
	       return lhs / rhs;
	    }

            value_type operator() (UnicodeString const& lhs,
                                   UnicodeString const&) const
	    {
	       return lhs;
	    }

            value_type operator() (double lhs, int rhs) const
	    {
	       return lhs / rhs;
	    }

            value_type operator() (int lhs, double rhs) const
	    {
	       return lhs / rhs;
	    }
      };

      struct to_bool : public boost::static_visitor<bool>
      {

            template <typename T>
            bool operator() (T val) const
	    {
               throw config_error("Boolean value expected");
	    }

            bool operator() (bool val) const
            {
	       return val;
            }
      };

      struct to_string : public boost::static_visitor<std::string>
      {

            template <typename T>
            std::string operator() (T val) const
	    {
               std::stringstream ss;
	       ss << val;
	       return ss.str();
	    }
            // specializations
            std::string operator() (UnicodeString const& val) const
	    {
               //std::stringstream ss;
               //std::wstring::const_iterator pos = val.begin();
               //ss << std::hex ;
               //for (;pos!=val.end();++pos)
               //{
               //  wchar_t c = *pos;
               //  if (c < 0x80)
               //  {
               //     ss << char(c);
               //  }
               //  else
               //  {
               //     ss << "\\x";
               //     unsigned c0 = (c >> 8) & 0xff;
               //     if (c0) ss << c0;
               //     ss << (c & 0xff);
               //  }
               //}
	       //return ss.str();
               return "TODO";
	    }

            std::string operator() (double val) const
            {
               std::stringstream ss;
	       ss << std::setprecision(16) << val;
	       return ss.str();
            }

            std::string operator() (value_null const& val) const
            {
	       return "";
            }
       };

      struct to_unicode : public boost::static_visitor<UnicodeString>
      {

            template <typename T>
            UnicodeString operator() (T val) const
	    {
               std::basic_ostringstream<char> out;
	       out << val;
               return UnicodeString(out.str().c_str());
	    }

            // specializations
            UnicodeString const& operator() (UnicodeString const& val) const
	    {
               return val;
	    }

            UnicodeString operator() (double val) const
            {
               std::basic_ostringstream<char> out;
	       out << std::setprecision(16) << val;
               return UnicodeString(out.str().c_str());
            }

            UnicodeString operator() (value_null const& val) const
            {
	       return UnicodeString("");
            }
      };

      struct to_expression_string : public boost::static_visitor<std::string>
      {
            std::string operator() (UnicodeString const& val) const
	    {
               std::string utf8;
               to_utf8(val,utf8);
               return "'" + utf8 + "'";
	    }

            template <typename T>
            std::string operator() (T val) const
	    {
	       std::stringstream ss;
	       ss << val;
	       return ss.str();
	    }

            std::string operator() (double val) const
            {
               std::stringstream ss;
	       ss << std::setprecision(16) << val;
	       return ss.str();
            }

            std::string operator() (value_null const& val) const
	    {
               return "null";
            }
      };
   }

   class value
   {
	 value_base base_;
	 friend const value operator+(value const&,value const&);
	 friend const value operator-(value const&,value const&);
	 friend const value operator*(value const&,value const&);
	 friend const value operator/(value const&,value const&);

      public:
	 value ()
            : base_(value_null()) {}

	 template <typename T> value(T _val_)
            : base_(_val_) {}

	 bool operator==(value const& other) const
	 {
	    return boost::apply_visitor(impl::equals(),base_,other.base_);
	 }

	 bool operator!=(value const& other) const
	 {
	    return boost::apply_visitor(impl::not_equals(),base_,other.base_);
	 }

	 bool operator>(value const& other) const
	 {
	    return boost::apply_visitor(impl::greater_than(),base_,other.base_);
	 }

	 bool operator>=(value const& other) const
	 {
	    return boost::apply_visitor(impl::greater_or_equal(),base_,other.base_);
	 }

	 bool operator<(value const& other) const
	 {
	    return boost::apply_visitor(impl::less_than(),base_,other.base_);
	 }

	 bool operator<=(value const& other) const
	 {
	    return boost::apply_visitor(impl::less_or_equal(),base_,other.base_);
	 }

	 value_base const& base() const
	 {
	    return base_;
	 }

	 bool to_bool() const
	 {
	    return boost::apply_visitor(impl::to_bool(),base_);
	 }

	 std::string to_expression_string() const
	 {
	    return boost::apply_visitor(impl::to_expression_string(),base_);
	 }

	 std::string to_string() const
	 {
	    return boost::apply_visitor(impl::to_string(),base_);
	 }

         UnicodeString to_unicode() const
         {
            return boost::apply_visitor(impl::to_unicode(),base_);
         }
   };

   inline const value operator+(value const& p1,value const& p2)
   {

      return value(boost::apply_visitor(impl::add<value>(),p1.base_, p2.base_));
   }

   inline const value operator-(value const& p1,value const& p2)
   {

      return value(boost::apply_visitor(impl::sub<value>(),p1.base_, p2.base_));
   }

   inline const value operator*(value const& p1,value const& p2)
   {

      return value(boost::apply_visitor(impl::mult<value>(),p1.base_, p2.base_));
   }

   inline const value operator/(value const& p1,value const& p2)
   {

      return value(boost::apply_visitor(impl::div<value>(),p1.base_, p2.base_));
   }

  template <typename charT, typename traits>
  inline std::basic_ostream<charT,traits>&
  operator << (std::basic_ostream<charT,traits>& out,
	       value const& v)
  {
    out << v.to_string();
    return out;
  }
}

#endif //VALUE_HPP
<|endoftext|>


<commit_before>class AliAnalysisGrid;
const char *dataset   = "";
TString anaLibs = "";
//Int_t iESDfilter       = 1;
Int_t iESDfilter       = 0;
Int_t iAODTagCreation  = 1;
Int_t iAODAddMCBranch  = 0;

//______________________________________________________________________________
void RunGrid(
         const char* runtype = "local", // local, proof or grid
         const char *gridmode = "test", // Set the run mode (can be "full", "test", "offline", "submit" or "terminate"). Full & Test work for proof
         const bool bMCtruth = 1, // 1 = MCEvent handler is on (MC truth), 0 = MCEvent handler is off (MC reconstructed/real data)
         const bool bMCphyssel = 1, // 1 = looking at MC truth or reconstructed, 0 = looking at real data
         const Long64_t nentries = 2000, // for local and proof mode, ignored in grid mode. Set to 1234567890 for all events.
         const Long64_t firstentry = 0, // for local and proof mode, ignored in grid mode
         const char *proofdataset = "/alice/data/LHC10c_000120821_p1", // path to dataset on proof cluster, for proof analysis
         const char *proofcluster = "alice-caf.cern.ch", // which proof cluster to use in proof mode
         const char *taskname = "Flowd_PbPb2011"
         )
{
  // check run type
  if(runtype != "local" && runtype != "proof" && runtype != "grid"){
    Printf("\n\tIncorrect run option, check first argument of run macro");
    Printf("\tint runtype = local, proof or grid\n");
    return;
  }
  Printf("%s analysis chosen",runtype);

  gROOT->ProcessLine(".include $ALICE_ROOT/include");

  gSystem->AddIncludePath("-I$ALICE_ROOT/include");
  gSystem->AddIncludePath("-I$ALICE_ROOT/PWGHF/vertexingHF");
  // Load analysis specific libraries
  //=====================================================================

  gSystem->SetIncludePath("-I. -I$ROOTSYS/include -I$ALICE_ROOT -I$ALICE_ROOT/include -I$ALICE_ROOT/ITS -I$ALICE_ROOT/TPC -I$ALICE_ROOT/CONTAINERS -I$ALICE_ROOT/STEER/STEER -I$ALICE_ROOT/STEER/STEERBase -I$ALICE_ROOT/STEER/ESD -I$ALICE_ROOT/STEER/AOD -I$ALICE_ROOT/TRD -I$ALICE_ROOT/macros -I$ALICE_ROOT/ANALYSIS  -I$ALICE_ROOT/OADB -I$ALICE_ROOT/PWGHF -I$ALICE_ROOT/PWGHF/base -I$ALICE_ROOT/PWGHF/vertexingHF -I$ALICE_ROOT/PWG/FLOW/Base -I$ALICE_ROOT/PWG/FLOW/Tasks -g");

  gSystem->Load("libTree.so");
  gSystem->Load("libGeom.so");
  gSystem->Load("libPhysics.so");
  gSystem->Load("libVMC.so");
  gSystem->Load("libMinuit.so");
  gSystem->Load("libSTEERBase.so");
  gSystem->Load("libESD.so");
  gSystem->Load("libAOD.so");
  gSystem->Load("libANALYSIS.so");
  gSystem->Load("libOADB.so");
  gSystem->Load("libANALYSISalice.so");
  gSystem->Load("libCORRFW.so");
  gSystem->Load("libPWGHFbase.so");
  gSystem->Load("libPWGflowBase.so");
  gSystem->Load("libPWGflowTasks.so");
  gSystem->Load("libPWGHFvertexingHF.so");

  // Load analysis specific libraries
  //=====================================================================
  //------ Create AlienPlugin ---------------------
  AliAnalysisGrid *plugin = 0x0;
  TChain *chain = 0x0;
  if (runtype != "local") {
    plugin = CreateAlienHandler(taskname, gridmode, proofcluster, proofdataset);
    if(!plugin) return;
  } else {
    gROOT->LoadMacro("$ALICE_ROOT/PWGCF/Correlations/macros/dphicorrelations/CreateESDChain.C");
    chain = CreateESDChain("ESDs.txt");
  }

  //---- Create the analysis manager
  AliAnalysisManager* mgr = new AliAnalysisManager(taskname);
  if(plugin) mgr->SetGridHandler(plugin);

  //  Input

  AliESDInputHandler* iH = new AliESDInputHandler("handler","handler for my analisys");
  mgr->SetInputEventHandler(iH);

  //--------------------------------------------------------------
  // Other tasks

  // Physics selection
  gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
  AliPhysicsSelectionTask *physSel = AddTaskPhysicsSelection(kFALSE); // useMC
  // Centrality selection
  gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskCentrality.C");
  AliCentralitySelectionTask *taskCentr = AddTaskCentrality();

  gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPIDResponse.C");
  AliAnalysisTaskPIDResponse *pidTask = AddTaskPIDResponse(kFALSE); // useMC

  gROOT->LoadMacro("./AliAnalysisTaskFlowd.cxx+g");//$ALICE_ROOT/PWGLF/STRANGENESS/Cascades/AliAnalysisTaskCheckCascadePbPb.cxx++g");
  gROOT->LoadMacro("./AddTaskFlowd.C");//$ALICE_ROOT/PWGLF/STRANGENESS/Cascades/macros/AddTaskCheckCascadePbPb.C");
  AliAnalysisTaskFlowd *task = AddTaskFlowd(kTRUE);

  //__________________________________________________________________________
  // Disable debug printouts
  mgr->SetDebugLevel(3);
  AliLog::SetGlobalLogLevel(AliLog::kFatal);
  AliLog::SetGlobalDebugLevel(0);

  //__________________________________________________________________________
  if (!mgr->InitAnalysis()) return;
  mgr->PrintStatus();
  // Start analysis in grid.
  if (runtype == "local")
    mgr->StartAnalysis(runtype,chain,nentries,firstentry);
  else
    mgr->StartAnalysis(runtype,nentries,firstentry);
}

//______________________________________________________________________________
AliAnalysisGrid* CreateAlienHandler(const char *taskname, const char *gridmode, const char *proofcluster, const char *proofdataset)
{
  AliAnalysisAlien *plugin = new AliAnalysisAlien();
  // Set the run mode (can be "full", "test", "offline", "submit" or "terminate")
  plugin->SetRunMode(gridmode);

  // Set versions of used packages

  plugin->SetAPIVersion("V1.1x");
  plugin->SetROOTVersion("v5-34-08");
  plugin->SetAliROOTVersion("vAN-20140915");
  plugin->SetExecutableCommand("aliroot -b -q");

  // Declare input data to be processed.

  // Method 1: Create automatically XML collections using alien 'find' command.
  // Define production directory LFN
  //    plugin->SetGridDataDir("/alice/data/2010/LHC10h");

  // plugin->SetGridDataDir(" /alice/data/2011/LHC11h_2/"); //sim
  // plugin->SetDataPattern("pass2/*AliAOD.root"); // sim

  plugin->SetGridDataDir("/alice/data/2011/LHC11h_2/"); //sim
  plugin->SetDataPattern("/pass2/ESDs/*AliESD.root"); // sim
  plugin->SetRunPrefix("000");   // real data

  Int_t runlist[1]={167693};
  for(Int_t i=0;i<1;i++)
    plugin->AddRunNumber(runlist[i]);

  //    plugin->AddRunNumber(139505);
  //  plugin->AddRunNumber(138652);
  plugin->SetNrunsPerMaster(1);
  plugin->SetOutputToRunNo();

  // Method 2: Declare existing data files (raw collections, xml collections, root file)
  //   plugin->AddDataFile("/alice/data/2008/LHC08c/000057657/raw/Run57657.Merged.RAW.tag.root");

  // Define alien work directory where all files will be copied. Relative to alien $HOME.
  plugin->SetGridWorkingDir(taskname);

  // Declare alien output directory. Relative to working directory.
  plugin->SetGridOutputDir("output"); // In this case will be $HOME/taskname/out

  //  plugin->SetAdditionalLibs("libTree.so libGeom.so libPhysics.so libVMC.so libMinuit.so libSTEERBase.so libESD.so libAOD.so  libANALYSIS.so libOADB.so libANALYSISalice.so libCORRFW.so libPWGHFbase.so libPWGflowBase.so libPWGflowTasks.so libPWGHFvertexingHF.so");

  // plugin->SetAdditionalLibs("libCORRFW.so libPWGHFbase.so libPWGflowBase.so libPWGflowTasks.so libPWGHFvertexingHF.so");

  plugin->SetAnalysisSource("AliAnalysisTaskFlowd.cxx");

  cout<<"-->>>>>>>>>>>>>>>>>>>>>>>>> 1"<<endl;

  // Declare the analysis source files names separated by blancs. To be compiled runtime
  // using ACLiC on the worker nodes.
  //plugin->SetAdditionalLibs("libPWGHFbase.so libPWGflowBase.so libPWGflowTasks.so libPWGHFvertexingHF.so AliAODMuonReplicator0.so");

  cout<<"-->>>>>>>>>>>>>>>>>>>>>>>>> 2"<<endl;
  // plugin->SetAdditionalLibs("libTree.so libGeom.so libPhysics.so libVMC.so libMinuit.so libSTEERBase.so libESD.so libAOD.so libANALYSIS.so libOADB.so libANALYSISalice.so libCORRFW.so libPWGHFbase.so libPWGflowBase.so libPWGflowTasks.so libPWGHFvertexingHF.so");

  // plugin->SetAnalysisSource("AliAnalysisTaskESDMuonFilterO.cxx");
  //plugin->SetAnalysisSource("AliAODMuonReplicator0.cxx");

  // Declare all libraries (other than the default ones for the framework. These will be
  // loaded by the generated analysis macro. Add all extra files (task .cxx/.h) here.
  // plugin->SetAdditionalLibs("AliAODMuonReplicator0_cxx.so");
  // plugin->SetAdditionalLibs("AliAnalysisTaskESDMuonFilterO_cxx.so");

  //questo
  plugin->SetAdditionalLibs("libPWGflowBase.so libPWGflowTasks.so libPWGHFbase.so libPWGHFvertexingHF.so");
  plugin->AddIncludePath("-I. -I$ROOTSYS/include -I$ALICE_ROOT -I$ALICE_ROOT/include -I$ALICE_ROOT/ITS -I$ALICE_ROOT/TPC -I$ALICE_ROOT/CONTAINERS -I$ALICE_ROOT/STEER/STEER -I$ALICE_ROOT/STEER/STEERBase -I$ALICE_ROOT/STEER/ESD -I$ALICE_ROOT/STEER/AOD -I$ALICE_ROOT/TRD -I$ALICE_ROOT/macros -I$ALICE_ROOT/ANALYSIS  -I$ALICE_ROOT/OADB -I$ALICE_ROOT/PWGHF -I$ALICE_ROOT/PWGHF/base -I$ALICE_ROOT/PWGHF/vertexingHF -I$ALICE_ROOT/PWG/FLOW/Base -I$ALICE_ROOT/PWG/FLOW/Tasks -g");

  // plugin->SetAdditionalLibs("AliAODMuonReplicator0.h AliAODMuonReplicator0.cxx");
  // plugin->SetAdditionalLibs("AliAnalysisTaskESDMuonFilterO.h AliAnalysisTaskESDMuonFilterO.cxx");

  //plugin->SetAdditionalLibs("AliAODMuonReplicator0.h AliAODMuonReplicator0.cxx AliAnalysisTaskESDMuonFilterO.h AliAnalysisTaskESDMuonFilterO.cxx");

  cout<<"-->>>>>>>>>>>>>>>>>>>>>>>>> 3"<<endl;

  // plugin->SetAdditionalLibs("AliAODMuonReplicator0.h AliAODMuonReplicator0.cxx");

  // plugin->SetAdditionalLibs("AliAnalysisTaskESDMuonFilterO.h AliAnalysisTaskESDMuonFilterO.cxx");

  // Declare the output file names separated by blancs.
  // (can be like: file.root or file.root@ALICE::Niham::File)
  // To only save certain files, use SetDefaultOutputs(kFALSE), and then
  // SetOutputFiles("list.root other.filename") to choose which files to save
  plugin->SetDefaultOutputs();
  //plugin->SetOutputFiles("list.root");

  // Optionally set a name for the generated analysis macro (default MyAnalysis.C)
  plugin->SetAnalysisMacro(Form("%s.C",taskname));

  // Optionally set maximum number of input files/subjob (default 100, put 0 to ignore)
  plugin->SetSplitMaxInputFileNumber(100);

  // Optionally modify the executable name (default analysis.sh)
  plugin->SetExecutable(Form("%s.sh",taskname));

  // set number of test files to use in "test" mode
  plugin->SetNtestFiles(10);

  // Optionally resubmit threshold.
  plugin->SetMasterResubmitThreshold(90);

  // Optionally set time to live (default 30000 sec)
  plugin->SetTTL(30000);

  // Optionally set input format (default xml-single)
  plugin->SetInputFormat("xml-single");

  // Optionally modify the name of the generated JDL (default analysis.jdl)
  plugin->SetJDLName(Form("%s.jdl",taskname));

  // Optionally modify job price (default 1)
  plugin->SetPrice(1);

  // Optionally modify split mode (default 'se')
  plugin->SetSplitMode("se");

  //----------------------------------------------------------
  //---      PROOF MODE SPECIFIC SETTINGS         ------------
  //----------------------------------------------------------
  // Proof cluster
  plugin->SetProofCluster(proofcluster);
  // Dataset to be used
  plugin->SetProofDataSet(proofdataset);
  // May need to reset proof. Supported modes: 0-no reset, 1-soft, 2-hard
  plugin->SetProofReset(0);
  // May limit number of workers
  plugin->SetNproofWorkers(0);
  // May limit the number of workers per slave
  plugin->SetNproofWorkersPerSlave(1);
  // May use a specific version of root installed in proof
  plugin->SetRootVersionForProof("current");
  // May set the aliroot mode. Check http://aaf.cern.ch/node/83
  plugin->SetAliRootMode("default"); // Loads AF libs by default
  // May request ClearPackages (individual ClearPackage not supported)
  plugin->SetClearPackages(kFALSE);
  // Plugin test mode works only providing a file containing test file locations, used in "local" mode also
  plugin->SetFileForTestMode("files.txt"); // file should contain path name to a local directory containg *ESDs.root etc
  // Request connection to alien upon connection to grid
  plugin->SetProofConnectGrid(kFALSE);

  cout<<"-->>>>>>>>>>>>>>>>>>>>>>>>> 4"<<endl;

  return plugin;

  cout<<"-->>>>>>>>>>>>>>>>>>>>>>>>> 5"<<endl;

}
<commit_msg>Fixed data pattern<commit_after>class AliAnalysisGrid;
const char *dataset   = "";
TString anaLibs = "";
//Int_t iESDfilter       = 1;
Int_t iESDfilter       = 0;
Int_t iAODTagCreation  = 1;
Int_t iAODAddMCBranch  = 0;

//______________________________________________________________________________
void RunGrid(
         const char* runtype = "local", // local, proof or grid
         const char *gridmode = "test", // Set the run mode (can be "full", "test", "offline", "submit" or "terminate"). Full & Test work for proof
         const bool bMCtruth = 1, // 1 = MCEvent handler is on (MC truth), 0 = MCEvent handler is off (MC reconstructed/real data)
         const bool bMCphyssel = 1, // 1 = looking at MC truth or reconstructed, 0 = looking at real data
         const Long64_t nentries = 2000, // for local and proof mode, ignored in grid mode. Set to 1234567890 for all events.
         const Long64_t firstentry = 0, // for local and proof mode, ignored in grid mode
         const char *proofdataset = "/alice/data/LHC10c_000120821_p1", // path to dataset on proof cluster, for proof analysis
         const char *proofcluster = "alice-caf.cern.ch", // which proof cluster to use in proof mode
         const char *taskname = "Flowd_PbPb2011"
         )
{
  // check run type
  if(runtype != "local" && runtype != "proof" && runtype != "grid"){
    Printf("\n\tIncorrect run option, check first argument of run macro");
    Printf("\tint runtype = local, proof or grid\n");
    return;
  }
  Printf("%s analysis chosen",runtype);

  gROOT->ProcessLine(".include $ALICE_ROOT/include");

  gSystem->AddIncludePath("-I$ALICE_ROOT/include");
  gSystem->AddIncludePath("-I$ALICE_ROOT/PWGHF/vertexingHF");
  // Load analysis specific libraries
  //=====================================================================

  gSystem->SetIncludePath("-I. -I$ROOTSYS/include -I$ALICE_ROOT -I$ALICE_ROOT/include -I$ALICE_ROOT/ITS -I$ALICE_ROOT/TPC -I$ALICE_ROOT/CONTAINERS -I$ALICE_ROOT/STEER/STEER -I$ALICE_ROOT/STEER/STEERBase -I$ALICE_ROOT/STEER/ESD -I$ALICE_ROOT/STEER/AOD -I$ALICE_ROOT/TRD -I$ALICE_ROOT/macros -I$ALICE_ROOT/ANALYSIS  -I$ALICE_ROOT/OADB -I$ALICE_ROOT/PWGHF -I$ALICE_ROOT/PWGHF/base -I$ALICE_ROOT/PWGHF/vertexingHF -I$ALICE_ROOT/PWG/FLOW/Base -I$ALICE_ROOT/PWG/FLOW/Tasks -g");

  gSystem->Load("libTree.so");
  gSystem->Load("libGeom.so");
  gSystem->Load("libPhysics.so");
  gSystem->Load("libVMC.so");
  gSystem->Load("libMinuit.so");
  gSystem->Load("libSTEERBase.so");
  gSystem->Load("libESD.so");
  gSystem->Load("libAOD.so");
  gSystem->Load("libANALYSIS.so");
  gSystem->Load("libOADB.so");
  gSystem->Load("libANALYSISalice.so");
  gSystem->Load("libCORRFW.so");
  gSystem->Load("libPWGHFbase.so");
  gSystem->Load("libPWGflowBase.so");
  gSystem->Load("libPWGflowTasks.so");
  gSystem->Load("libPWGHFvertexingHF.so");

  // Load analysis specific libraries
  //=====================================================================
  //------ Create AlienPlugin ---------------------
  AliAnalysisGrid *plugin = 0x0;
  TChain *chain = 0x0;
  if (runtype != "local") {
    plugin = CreateAlienHandler(taskname, gridmode, proofcluster, proofdataset);
    if(!plugin) return;
  } else {
    gROOT->LoadMacro("$ALICE_ROOT/PWGCF/Correlations/macros/dphicorrelations/CreateESDChain.C");
    chain = CreateESDChain("ESDs.txt");
  }

  //---- Create the analysis manager
  AliAnalysisManager* mgr = new AliAnalysisManager(taskname);
  if(plugin) mgr->SetGridHandler(plugin);

  //  Input

  AliESDInputHandler* iH = new AliESDInputHandler("handler","handler for my analisys");
  mgr->SetInputEventHandler(iH);

  //--------------------------------------------------------------
  // Other tasks

  // Physics selection
  gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
  AliPhysicsSelectionTask *physSel = AddTaskPhysicsSelection(kFALSE); // useMC
  // Centrality selection
  gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskCentrality.C");
  AliCentralitySelectionTask *taskCentr = AddTaskCentrality();

  gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPIDResponse.C");
  AliAnalysisTaskPIDResponse *pidTask = AddTaskPIDResponse(kFALSE); // useMC

  gROOT->LoadMacro("./AliAnalysisTaskFlowd.cxx+g");//$ALICE_ROOT/PWGLF/STRANGENESS/Cascades/AliAnalysisTaskCheckCascadePbPb.cxx++g");
  gROOT->LoadMacro("./AddTaskFlowd.C");//$ALICE_ROOT/PWGLF/STRANGENESS/Cascades/macros/AddTaskCheckCascadePbPb.C");
  AliAnalysisTaskFlowd *task = AddTaskFlowd(kTRUE);

  //__________________________________________________________________________
  // Disable debug printouts
  mgr->SetDebugLevel(3);
  AliLog::SetGlobalLogLevel(AliLog::kFatal);
  AliLog::SetGlobalDebugLevel(0);

  //__________________________________________________________________________
  if (!mgr->InitAnalysis()) return;
  mgr->PrintStatus();
  // Start analysis in grid.
  if (runtype == "local")
    mgr->StartAnalysis(runtype,chain,nentries,firstentry);
  else
    mgr->StartAnalysis(runtype,nentries,firstentry);
}

//______________________________________________________________________________
AliAnalysisGrid* CreateAlienHandler(const char *taskname, const char *gridmode, const char *proofcluster, const char *proofdataset)
{
  AliAnalysisAlien *plugin = new AliAnalysisAlien();
  // Set the run mode (can be "full", "test", "offline", "submit" or "terminate")
  plugin->SetRunMode(gridmode);

  // Set versions of used packages

  plugin->SetAPIVersion("V1.1x");
  plugin->SetROOTVersion("v5-34-08");
  plugin->SetAliROOTVersion("vAN-20140915");
  plugin->SetExecutableCommand("aliroot -b -q");

  // Declare input data to be processed.

  // Method 1: Create automatically XML collections using alien 'find' command.
  // Define production directory LFN
  //    plugin->SetGridDataDir("/alice/data/2010/LHC10h");

  // plugin->SetGridDataDir(" /alice/data/2011/LHC11h_2/"); //sim
  // plugin->SetDataPattern("pass2/*AliAOD.root"); // sim

  plugin->SetGridDataDir("/alice/data/2011/LHC11h_2/"); //sim
  plugin->SetDataPattern("*/pass2/*AliESDs.root"); // sim
  plugin->SetRunPrefix("000");   // real data

  Int_t runlist[1]={167693};
  for(Int_t i=0;i<1;i++)
    plugin->AddRunNumber(runlist[i]);

  //    plugin->AddRunNumber(139505);
  //  plugin->AddRunNumber(138652);
  plugin->SetNrunsPerMaster(1);
  plugin->SetOutputToRunNo();

  // Method 2: Declare existing data files (raw collections, xml collections, root file)
  //   plugin->AddDataFile("/alice/data/2008/LHC08c/000057657/raw/Run57657.Merged.RAW.tag.root");

  // Define alien work directory where all files will be copied. Relative to alien $HOME.
  plugin->SetGridWorkingDir(taskname);

  // Declare alien output directory. Relative to working directory.
  plugin->SetGridOutputDir("output"); // In this case will be $HOME/taskname/out

  //  plugin->SetAdditionalLibs("libTree.so libGeom.so libPhysics.so libVMC.so libMinuit.so libSTEERBase.so libESD.so libAOD.so  libANALYSIS.so libOADB.so libANALYSISalice.so libCORRFW.so libPWGHFbase.so libPWGflowBase.so libPWGflowTasks.so libPWGHFvertexingHF.so");

  // plugin->SetAdditionalLibs("libCORRFW.so libPWGHFbase.so libPWGflowBase.so libPWGflowTasks.so libPWGHFvertexingHF.so");

  plugin->SetAnalysisSource("AliAnalysisTaskFlowd.cxx");

  cout<<"-->>>>>>>>>>>>>>>>>>>>>>>>> 1"<<endl;

  // Declare the analysis source files names separated by blancs. To be compiled runtime
  // using ACLiC on the worker nodes.
  //plugin->SetAdditionalLibs("libPWGHFbase.so libPWGflowBase.so libPWGflowTasks.so libPWGHFvertexingHF.so AliAODMuonReplicator0.so");

  cout<<"-->>>>>>>>>>>>>>>>>>>>>>>>> 2"<<endl;
  // plugin->SetAdditionalLibs("libTree.so libGeom.so libPhysics.so libVMC.so libMinuit.so libSTEERBase.so libESD.so libAOD.so libANALYSIS.so libOADB.so libANALYSISalice.so libCORRFW.so libPWGHFbase.so libPWGflowBase.so libPWGflowTasks.so libPWGHFvertexingHF.so");

  // plugin->SetAnalysisSource("AliAnalysisTaskESDMuonFilterO.cxx");
  //plugin->SetAnalysisSource("AliAODMuonReplicator0.cxx");

  // Declare all libraries (other than the default ones for the framework. These will be
  // loaded by the generated analysis macro. Add all extra files (task .cxx/.h) here.
  // plugin->SetAdditionalLibs("AliAODMuonReplicator0_cxx.so");
  // plugin->SetAdditionalLibs("AliAnalysisTaskESDMuonFilterO_cxx.so");

  //questo
  plugin->SetAdditionalLibs("libPWGflowBase.so libPWGflowTasks.so libPWGHFbase.so libPWGHFvertexingHF.so");
  plugin->AddIncludePath("-I. -I$ROOTSYS/include -I$ALICE_ROOT -I$ALICE_ROOT/include -I$ALICE_ROOT/ITS -I$ALICE_ROOT/TPC -I$ALICE_ROOT/CONTAINERS -I$ALICE_ROOT/STEER/STEER -I$ALICE_ROOT/STEER/STEERBase -I$ALICE_ROOT/STEER/ESD -I$ALICE_ROOT/STEER/AOD -I$ALICE_ROOT/TRD -I$ALICE_ROOT/macros -I$ALICE_ROOT/ANALYSIS  -I$ALICE_ROOT/OADB -I$ALICE_ROOT/PWGHF -I$ALICE_ROOT/PWGHF/base -I$ALICE_ROOT/PWGHF/vertexingHF -I$ALICE_ROOT/PWG/FLOW/Base -I$ALICE_ROOT/PWG/FLOW/Tasks -g");

  // plugin->SetAdditionalLibs("AliAODMuonReplicator0.h AliAODMuonReplicator0.cxx");
  // plugin->SetAdditionalLibs("AliAnalysisTaskESDMuonFilterO.h AliAnalysisTaskESDMuonFilterO.cxx");

  //plugin->SetAdditionalLibs("AliAODMuonReplicator0.h AliAODMuonReplicator0.cxx AliAnalysisTaskESDMuonFilterO.h AliAnalysisTaskESDMuonFilterO.cxx");

  cout<<"-->>>>>>>>>>>>>>>>>>>>>>>>> 3"<<endl;

  // plugin->SetAdditionalLibs("AliAODMuonReplicator0.h AliAODMuonReplicator0.cxx");

  // plugin->SetAdditionalLibs("AliAnalysisTaskESDMuonFilterO.h AliAnalysisTaskESDMuonFilterO.cxx");

  // Declare the output file names separated by blancs.
  // (can be like: file.root or file.root@ALICE::Niham::File)
  // To only save certain files, use SetDefaultOutputs(kFALSE), and then
  // SetOutputFiles("list.root other.filename") to choose which files to save
  plugin->SetDefaultOutputs();
  //plugin->SetOutputFiles("list.root");

  // Optionally set a name for the generated analysis macro (default MyAnalysis.C)
  plugin->SetAnalysisMacro(Form("%s.C",taskname));

  // Optionally set maximum number of input files/subjob (default 100, put 0 to ignore)
  plugin->SetSplitMaxInputFileNumber(100);

  // Optionally modify the executable name (default analysis.sh)
  plugin->SetExecutable(Form("%s.sh",taskname));

  // set number of test files to use in "test" mode
  plugin->SetNtestFiles(10);

  // Optionally resubmit threshold.
  plugin->SetMasterResubmitThreshold(90);

  // Optionally set time to live (default 30000 sec)
  plugin->SetTTL(30000);

  // Optionally set input format (default xml-single)
  plugin->SetInputFormat("xml-single");

  // Optionally modify the name of the generated JDL (default analysis.jdl)
  plugin->SetJDLName(Form("%s.jdl",taskname));

  // Optionally modify job price (default 1)
  plugin->SetPrice(1);

  // Optionally modify split mode (default 'se')
  plugin->SetSplitMode("se");

  //----------------------------------------------------------
  //---      PROOF MODE SPECIFIC SETTINGS         ------------
  //----------------------------------------------------------
  // Proof cluster
  plugin->SetProofCluster(proofcluster);
  // Dataset to be used
  plugin->SetProofDataSet(proofdataset);
  // May need to reset proof. Supported modes: 0-no reset, 1-soft, 2-hard
  plugin->SetProofReset(0);
  // May limit number of workers
  plugin->SetNproofWorkers(0);
  // May limit the number of workers per slave
  plugin->SetNproofWorkersPerSlave(1);
  // May use a specific version of root installed in proof
  plugin->SetRootVersionForProof("current");
  // May set the aliroot mode. Check http://aaf.cern.ch/node/83
  plugin->SetAliRootMode("default"); // Loads AF libs by default
  // May request ClearPackages (individual ClearPackage not supported)
  plugin->SetClearPackages(kFALSE);
  // Plugin test mode works only providing a file containing test file locations, used in "local" mode also
  plugin->SetFileForTestMode("files.txt"); // file should contain path name to a local directory containg *ESDs.root etc
  // Request connection to alien upon connection to grid
  plugin->SetProofConnectGrid(kFALSE);

  cout<<"-->>>>>>>>>>>>>>>>>>>>>>>>> 4"<<endl;

  return plugin;

  cout<<"-->>>>>>>>>>>>>>>>>>>>>>>>> 5"<<endl;

}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2009 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "common.h"

#include "TextUtils.h"

/* system headers */
#include <sstream>
#include <string>
#include <stdio.h>
#include <string.h>

#ifdef __APPLE__
#include <sstream>
#include <CoreServices/CoreServices.h>
#include <sys/sysctl.h>
#endif

#ifdef _WIN32
#include <windows.h>
#else
#include <sys/utsname.h>
#endif

// opaque version number increments on protocol incompatibility
#ifndef BZ_PROTO_VERSION
#  define BZ_PROTO_VERSION	"0108"
#endif
// ditto for bzrobots
#ifndef BZROBOTS_PROTO_VERSION
#  define BZROBOTS_PROTO_VERSION    "0001"
#endif

// version numbers - also update:
//  README
//  configure.ac
//  include/version.h
//  package/win32/nsis/BZFlag.nsi
#ifndef BZ_MAJOR_VERSION
#  define BZ_MAJOR_VERSION	2
#endif

#ifndef BZ_MINOR_VERSION
#  define BZ_MINOR_VERSION	99
#endif

#ifndef BZ_REV
#  define BZ_REV		50
#endif

// DEVEL | STABLE | MAINT
#ifndef BZ_BUILD_TYPE
#  define BZ_BUILD_TYPE		"DEVEL"
#endif

const char *bzfcopyright = "Copyright (c) 1993 - 2009 Tim Riker";

//
//  Although the ./configure process will generate
//  -DBZ_BUILD_DATE for the build, here it's voided.
//
//  Could someone explain the reason for the
//  inconience caused by the ./configure method? This
//  way is simple, touch the *.cxx to get a new time
//  stamp (no big recompiles). If this file is updated,
//  you are also forced to get a new timestamp.
//
//  Using __DATE__ for all OSes is more consistent.
//
#undef BZ_BUILD_DATE

#ifndef BZ_BUILD_DATE
/* to get the version in the right format YYYYMMDD */
/* yes this is horrible but it needs to be done to get it right */
/* windows should pull from a resouce */
/* *nix gets this from the passed from my the Makefile */
static const char buildDate[] = {__DATE__};

static const char monthsOfYear[][4] = {"Jan","Feb","Mar","Apr","May","Jun",
                                       "Jul","Aug","Sep","Oct","Nov","Dec"};

int getBuildDate()
{
  int year = 1900, month, day = 0;
  char monthStr[4];

  sscanf(buildDate, "%4s %d %d", monthStr, &day, &year);

  for (month = 12; month > 1; --month) {
    if (strcmp(monthStr, monthsOfYear[month-1]) == 0)
      break;
  }

  return 10000*year + 100*month + day;
}
#endif
// down here so above gets created
#include "version.h"

const char*		getProtocolVersion()
{
  static std::string protVersion = BZ_PROTO_VERSION;
  return protVersion.c_str();
}

const char*		getRobotsProtocolVersion()
{
  static std::string robotsProtVersion = BZROBOTS_PROTO_VERSION;
  return robotsProtVersion.c_str();
}

const char*		getServerVersion()
{
  static std::string serverVersion = std::string("BZFS") + getProtocolVersion();
  return serverVersion.c_str();
}

const char*		getMajorMinorVersion()
{
  static std::string	version = "";
  if (!version.size()){
    std::ostringstream	versionStream;
    versionStream << BZ_MAJOR_VERSION << "." << BZ_MINOR_VERSION;
    version = versionStream.str();
  }
  return version.c_str();
}

const char*		getMajorMinorRevVersion()
{
  static std::string	version = "";
  if (!version.size()){
    std::ostringstream	versionStream;
    versionStream << BZ_MAJOR_VERSION << "." << BZ_MINOR_VERSION << "." << BZ_REV;
    version = versionStream.str();
  }
  return version.c_str();
}

const char*		getAppVersion()
{
  static std::string	appVersion = "";
  if (!appVersion.size()){
    std::ostringstream	appVersionStream;
    // TODO add current platform, release, cpu, etc
    appVersionStream << getMajorMinorRevVersion() << "." << BZ_BUILD_DATE
	<< "-" << BZ_BUILD_TYPE << "-" << BZ_BUILD_OS;
#ifdef HAVE_SDL
    appVersionStream << "-SDL";
#endif
    appVersion = appVersionStream.str();
  }
  return appVersion.c_str();
}

std::string getOSString()
{
#ifdef __APPLE__
  OSErr err = noErr;

  long systemMajor, systemMinor, systemBugFix = 0;
  err = Gestalt(gestaltSystemVersionMajor, &systemMajor);
  if (err == noErr){
    err = Gestalt(gestaltSystemVersionMinor, &systemMinor);
    if (err == noErr){
      err = Gestalt(gestaltSystemVersionBugFix, &systemBugFix);
    }
  }

  std::stringstream reply;
  if (err == noErr) {
    reply << "Mac OS X Version ";
    reply << systemMajor;
    reply << ".";
    reply << systemMinor;
    reply << ".";
    reply << systemBugFix;
  } else {
    reply << "unknown system version (Gestalt error)";
  }

  long systemArchitecture = 0;
  err = Gestalt(gestaltSysArchitecture, &systemArchitecture);
  if (err == noErr) {
    switch (systemArchitecture) {
      case gestalt68k: {reply << " 68k"; break;}
      case gestaltPowerPC: {reply << " PPC"; break;}
      case gestaltIntel: {reply << " x86"; break;}
      default: {reply << " unknown CPU architecture (Gestalt reply is ";
      reply << systemArchitecture; reply << ")";}
    }
  } else {
    reply << " unknown CPU architecture (Gestalt error)";
  }

  int value = 0;
  size_t length = sizeof(value);
  if (sysctlbyname("hw.cpu64bit_capable", &value, &length, NULL, 0) == 0) {
    if (value) {
      reply << "; CPU 64 bit cabable";
    }
  }

  return std::string(reply.str());
#else
	#ifdef _WIN32
	  // build up version string
	  OSVERSIONINFOEX versionInfo;
	  SYSTEM_INFO systemInfo;

	  versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
	  GetVersionEx((LPOSVERSIONINFO)&versionInfo);
	  GetNativeSystemInfo(&systemInfo);

	  std::string versionString;
	  std::string platform = "Win32";
	  if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
		platform = "Win64";
	  if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
		platform = "WinIA64";
	  versionString = TextUtils::format("%s%d.%d.%d sp%d.$d",platform.c_str(),versionInfo.dwMajorVersion,versionInfo.dwMinorVersion,versionInfo.dwBuildNumber, versionInfo.wServicePackMajor,versionInfo.wServicePackMinor);

	  return versionString;
	#else
  std::string versionString;
  struct utsname buf;
  if (uname(&buf) == 0) {
    std::vector<std::string> rtok = TextUtils::tokenize(buf.release, ".", 4);
    std::string rel;
    unsigned int i;
    // use up to three period separated elements of the release string
    for (i = 0; i < 3 && i < rtok.size(); i++) {
      if (rel.size() > 0)
	rel += ".";
      rel += rtok[i];
    }
    // "Linux 2.6.27 x86_64" for example
    versionString = TextUtils::format("%s %s %s", buf.sysname, rel.c_str(), buf.machine);
  }
  else {
    perror("uname");
    versionString = "unix unknown";
  }
  return versionString;
	#endif
#endif
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>Refactor getOSString() with better #ifdef structure. Fix whitespace.<commit_after>/* bzflag
 * Copyright (c) 1993 - 2009 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "common.h"

/* system headers */
#include <sstream>
#include <string>
#include <stdio.h>
#include <string.h>

#ifdef _WIN32
#include <windows.h>
#else
#ifdef __APPLE__
#include <sstream>
#include <CoreServices/CoreServices.h>
#include <sys/sysctl.h>
#else
#include <sys/utsname.h>
#endif // __APPLE__
#endif // _WIN32

// common headers
#include "TextUtils.h"

// opaque version number increments on protocol incompatibility
#ifndef BZ_PROTO_VERSION
#  define BZ_PROTO_VERSION	"0108"
#endif
// ditto for bzrobots
#ifndef BZROBOTS_PROTO_VERSION
#  define BZROBOTS_PROTO_VERSION    "0001"
#endif

// version numbers - also update:
//  README
//  configure.ac
//  include/version.h
//  package/win32/nsis/BZFlag.nsi
#ifndef BZ_MAJOR_VERSION
#  define BZ_MAJOR_VERSION	2
#endif

#ifndef BZ_MINOR_VERSION
#  define BZ_MINOR_VERSION	99
#endif

#ifndef BZ_REV
#  define BZ_REV		50
#endif

// DEVEL | STABLE | MAINT
#ifndef BZ_BUILD_TYPE
#  define BZ_BUILD_TYPE		"DEVEL"
#endif

const char *bzfcopyright = "Copyright (c) 1993 - 2009 Tim Riker";

//
//  Although the ./configure process will generate
//  -DBZ_BUILD_DATE for the build, here it's voided.
//
//  Could someone explain the reason for the
//  inconience caused by the ./configure method? This
//  way is simple, touch the *.cxx to get a new time
//  stamp (no big recompiles). If this file is updated,
//  you are also forced to get a new timestamp.
//
//  Using __DATE__ for all OSes is more consistent.
//
#undef BZ_BUILD_DATE

#ifndef BZ_BUILD_DATE
/* to get the version in the right format YYYYMMDD */
/* yes this is horrible but it needs to be done to get it right */
/* windows should pull from a resouce */
/* *nix gets this from the passed from my the Makefile */
static const char buildDate[] = {__DATE__};

static const char monthsOfYear[][4] = {"Jan","Feb","Mar","Apr","May","Jun",
                                       "Jul","Aug","Sep","Oct","Nov","Dec"};

int getBuildDate()
{
  int year = 1900, month, day = 0;
  char monthStr[4];

  sscanf(buildDate, "%4s %d %d", monthStr, &day, &year);

  for (month = 12; month > 1; --month) {
    if (strcmp(monthStr, monthsOfYear[month-1]) == 0)
      break;
  }

  return 10000*year + 100*month + day;
}
#endif
// down here so above gets created
#include "version.h"

const char*		getProtocolVersion()
{
  static std::string protVersion = BZ_PROTO_VERSION;
  return protVersion.c_str();
}

const char*		getRobotsProtocolVersion()
{
  static std::string robotsProtVersion = BZROBOTS_PROTO_VERSION;
  return robotsProtVersion.c_str();
}

const char*		getServerVersion()
{
  static std::string serverVersion = std::string("BZFS") + getProtocolVersion();
  return serverVersion.c_str();
}

const char*		getMajorMinorVersion()
{
  static std::string	version = "";
  if (!version.size()){
    std::ostringstream	versionStream;
    versionStream << BZ_MAJOR_VERSION << "." << BZ_MINOR_VERSION;
    version = versionStream.str();
  }
  return version.c_str();
}

const char*		getMajorMinorRevVersion()
{
  static std::string	version = "";
  if (!version.size()){
    std::ostringstream	versionStream;
    versionStream << BZ_MAJOR_VERSION << "." << BZ_MINOR_VERSION << "." << BZ_REV;
    version = versionStream.str();
  }
  return version.c_str();
}

const char*		getAppVersion()
{
  static std::string	appVersion = "";
  if (!appVersion.size()){
    std::ostringstream	appVersionStream;
    // TODO add current platform, release, cpu, etc
    appVersionStream << getMajorMinorRevVersion() << "." << BZ_BUILD_DATE
	<< "-" << BZ_BUILD_TYPE << "-" << BZ_BUILD_OS;
#ifdef HAVE_SDL
    appVersionStream << "-SDL";
#endif
    appVersion = appVersionStream.str();
  }
  return appVersion.c_str();
}

std::string		getOSString()
{
  std::string versionString = "unknown";
#ifdef _WIN32
  // build up version string
  OSVERSIONINFOEX versionInfo;
  SYSTEM_INFO systemInfo;

  versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  GetVersionEx((LPOSVERSIONINFO)&versionInfo);
  GetNativeSystemInfo(&systemInfo);

  std::string platform = "Win32";
  if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
    platform = "Win64";
  if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
    platform = "WinIA64";
  versionString = TextUtils::format("%s%d.%d.%d sp%d.$d",platform.c_str(),versionInfo.dwMajorVersion,versionInfo.dwMinorVersion,versionInfo.dwBuildNumber, versionInfo.wServicePackMajor,versionInfo.wServicePackMinor);
#else
#ifdef __APPLE__
  OSErr err = noErr;

  long systemMajor, systemMinor, systemBugFix = 0;
  err = Gestalt(gestaltSystemVersionMajor, &systemMajor);
  if (err == noErr){
    err = Gestalt(gestaltSystemVersionMinor, &systemMinor);
    if (err == noErr){
      err = Gestalt(gestaltSystemVersionBugFix, &systemBugFix);
    }
  }

  std::stringstream reply;
  if (err == noErr) {
    reply << "Mac OS X Version ";
    reply << systemMajor;
    reply << ".";
    reply << systemMinor;
    reply << ".";
    reply << systemBugFix;
  } else {
    reply << "unknown system version (Gestalt error)";
  }

  long systemArchitecture = 0;
  err = Gestalt(gestaltSysArchitecture, &systemArchitecture);
  if (err == noErr) {
    switch (systemArchitecture) {
      case gestalt68k: {reply << " 68k"; break;}
      case gestaltPowerPC: {reply << " PPC"; break;}
      case gestaltIntel: {reply << " x86"; break;}
      default: {reply << " unknown CPU architecture (Gestalt reply is ";
	reply << systemArchitecture; reply << ")";}
    }
  } else {
    reply << " unknown CPU architecture (Gestalt error)";
  }

  int value = 0;
  size_t length = sizeof(value);
  if (sysctlbyname("hw.cpu64bit_capable", &value, &length, NULL, 0) == 0) {
    if (value) {
      reply << "; CPU 64 bit cabable";
    }
  }

  versionString = reply.str();
#else
  struct utsname buf;
  if (uname(&buf) == 0) {
    std::vector<std::string> rtok = TextUtils::tokenize(buf.release, ".", 4);
    std::string rel;
    unsigned int i;
    // use up to three period separated elements of the release string
    for (i = 0; i < 3 && i < rtok.size(); i++) {
      if (rel.size() > 0)
	rel += ".";
      rel += rtok[i];
    }
    // "Linux 2.6.27 x86_64" for example
    versionString = TextUtils::format("%s %s %s", buf.sysname, rel.c_str(), buf.machine);
  }
  else {
    perror("uname");
    versionString = "unix unknown";
  }
#endif // __APPLE__
#endif // _WIN32
  return versionString;
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>// Copyright © 2014 German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.
//
// Author: Christian Kellner <kellner@bio.lmu.de>

#ifdef _WIN32
 #ifdef NIXEXPORT
 #define NIXAPI __declspec(dllexport)
 #else
 #define NIXAPI __declspec(dllimport)
 #endif
#pragma warning(disable: 4250 4251)

 //workaround for missing ssize_t on windows
 #include <BaseTsd.h>
 typedef SSIZE_T ssize_t;
#else
 #define NIXAPI
#endif

#ifdef _MSC_VER
#define NOEXCEPT
#else
#define NOEXCEPT noexcept
#endif
<commit_msg>[win] only typedef ssize_t if not yet defined<commit_after>// Copyright © 2014 German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.
//
// Author: Christian Kellner <kellner@bio.lmu.de>

#ifdef _WIN32
 #ifdef NIXEXPORT
 #define NIXAPI __declspec(dllexport)
 #else
 #define NIXAPI __declspec(dllimport)
 #endif
#pragma warning(disable: 4250 4251)

 //workaround for missing ssize_t on windows
 #ifndef ssize_t
   #include <BaseTsd.h>
   typedef SSIZE_T ssize_t;
 #endif
#else
 #define NIXAPI
#endif

#ifdef _MSC_VER
#define NOEXCEPT
#else
#define NOEXCEPT noexcept
#endif
<|endoftext|>