code:
//  (C) Copyright Howard Hinnant
//  (C) Copyright 2011 Vicente J. Botet Escriba
//  Use, modification and distribution are subject to 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).
//

#ifndef BOOST_CHRONO_IO_DURATION_GET_HPP
#define BOOST_CHRONO_IO_DURATION_GET_HPP

#include <boost/chrono/config.hpp>
#include <string>
#include <boost/type_traits/is_scalar.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_signed.hpp>
#include <boost/mpl/if.hpp>
#include <boost/integer/common_factor_rt.hpp>
#include <boost/chrono/detail/scan_keyword.hpp>
#include <boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp>
#include <boost/chrono/process_cpu_clocks.hpp>

#include <boost/assert.hpp>
#include <locale>

/**
 * Duration formatting facet for input.
 */
namespace boost
{
  namespace chrono
  {

    namespace detail
    {
      template <class Rep, bool = is_scalar<Rep>::value>
      struct duration_io_intermediate
      {
        typedef Rep type;
      };

      template <class Rep>
      struct duration_io_intermediate<Rep, true>
      {
        typedef typename mpl::if_c<is_floating_point<Rep>::value, long double, typename mpl::if_c<
            is_signed<Rep>::value, long long, unsigned long long>::type>::type type;
      };

      template <class Rep>
      struct duration_io_intermediate<process_times<Rep>, false>
      {
        typedef process_times<typename duration_io_intermediate<Rep>::type> type;
      };

      template <typename intermediate_type>
      typename enable_if<is_integral<intermediate_type> , bool>::type reduce(intermediate_type& r,
          unsigned long long& den, std::ios_base::iostate& err)
      {
        typedef typename common_type<intermediate_type, unsigned long long>::type common_type_t;

        // Reduce r * num / den
        common_type_t t = integer::gcd<common_type_t>(common_type_t(r), common_type_t(den));
        r /= t;
        den /= t;
        if (den != 1)
        {
          // Conversion to Period is integral and not exact
          err |= std::ios_base::failbit;
          return false;
        }
        return true;
      }
      template <typename intermediate_type>
      typename disable_if<is_integral<intermediate_type> , bool>::type reduce(intermediate_type&, unsigned long long&,
          std::ios_base::iostate&)
      {
        return true;
      }

    }

    /**
     * @c duration_get is used to parse a character sequence, extracting
     * components of a duration into a class duration.
     * Each get member parses a format as produced by a corresponding format specifier to time_put<>::put.
     * If the sequence being parsed matches the correct format, the
     * corresponding member of the class duration argument are set to the
     * value used to produce the sequence;
     * otherwise either an error is reported or unspecified values are assigned.
     * In other words, user confirmation is required for reliable parsing of
     * user-entered durations, but machine-generated formats can be parsed
     * reliably. This allows parsers to be aggressive about interpreting user
     * variations on standard formats.
     *
     * If the end iterator is reached during parsing of the get() member
     * function, the member sets std::ios_base::eofbit in err.
     */
    template <class CharT, class InputIterator = std::istreambuf_iterator<CharT> >
    class duration_get: public std::locale::facet
    {
    public:
      /**
       * Type of character the facet is instantiated on.
       */
      typedef CharT char_type;
      /**
       * Type of character string passed to member functions.
       */
      typedef std::basic_string<CharT> string_type;
      /**
       * Type of iterator used to scan the character buffer.
       */
      typedef InputIterator iter_type;

      /**
       * Construct a @c duration_get facet.
       * @param refs
       * @Effects Construct a @c duration_get facet.
       * If the @c refs argument is @c 0 then destruction of the object is
       * delegated to the @c locale, or locales, containing it. This allows
       * the user to ignore lifetime management issues. On the other had,
       * if @c refs is @c 1 then the object must be explicitly deleted;
       * the @c locale will not do so. In this case, the object can be
       * maintained across the lifetime of multiple locales.
       */

      explicit duration_get(size_t refs = 0) :
        std::locale::facet(refs)
      {
      }

      /**
       * @param s start input stream iterator
       * @param end end input stream iterator
       * @param ios a reference to a ios_base
       * @param err the ios_base state
       * @param d the duration
       * @param pattern begin of the formatting pattern
       * @param pat_end end of the formatting pattern
       *
       * Requires: [pattern,pat_end) shall be a valid range.
       *
       * Effects: The function starts by evaluating err = std::ios_base::goodbit.
       * It then enters a loop, reading zero or more characters from s at
       * each iteration. Unless otherwise specified below, the loop
       * terminates when the first of the following conditions holds:
       * - The expression pattern == pat_end evaluates to true.
       * - The expression err == std::ios_base::goodbit evaluates to false.
       * - The expression s == end evaluates to true, in which case the
       * function evaluates err = std::ios_base::eofbit | std::ios_base::failbit.
       * - The next element of pattern is equal to '%', followed by a conversion
       * specifier character, format.
       * If the number of elements in the range [pattern,pat_end) is not
       * sufficient to unambiguously determine whether the conversion
       * specification is complete and valid, the function evaluates
       * err = std::ios_base::failbit. Otherwise, the function evaluates
       * s = get_value(s, end, ios, err, r) when the conversion specification is 'v' and
       * s = get_value(s, end, ios, err, rt) when the conversion specification is 'u'.
       * If err == std::ios_base::goodbit holds after
       * the evaluation of the expression, the function increments pattern to
       * point just past the end of the conversion specification and continues
       * looping.
       * - The expression isspace(*pattern, ios.getloc()) evaluates to true, in
       * which case the function first increments pattern until
       * pattern == pat_end || !isspace(*pattern, ios.getloc()) evaluates to true,
       * then advances s until s == end || !isspace(*s, ios.getloc()) is true,
       * and finally resumes looping.
       * - The next character read from s matches the element pointed to by
       * pattern in a case-insensitive comparison, in which case the function
       * evaluates ++pattern, ++s and continues looping. Otherwise, the function
       * evaluates err = std::ios_base::failbit.
       *
       * Once r and rt are retrieved,
       * Returns: s
       */
      template <typename Rep, typename Period>
      iter_type get(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err,
          duration<Rep, Period> &d, const char_type *pattern, const char_type *pat_end) const
      {
        if (std::has_facet<duration_units<CharT> >(ios.getloc()))
        {
          duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(ios.getloc());
          return get(facet, s, end, ios, err, d, pattern, pat_end);
        }
        else
        {
          duration_units_default<CharT> facet;
          return get(facet, s, end, ios, err, d, pattern, pat_end);
        }
      }

      template <typename Rep, typename Period>
      iter_type get(duration_units<CharT> const&facet, iter_type s, iter_type end, std::ios_base& ios,
          std::ios_base::iostate& err, duration<Rep, Period> &d, const char_type *pattern, const char_type *pat_end) const
      {

        typedef typename detail::duration_io_intermediate<Rep>::type intermediate_type;
        intermediate_type r;
        rt_ratio rt;
        bool value_found = false, unit_found = false;

        const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
        while (pattern != pat_end && err == std::ios_base::goodbit)
        {
          if (s == end)
          {
            err |= std::ios_base::eofbit;
            break;
          }
          if (ct.narrow(*pattern, 0) == '%')
          {
            if (++pattern == pat_end)
            {
              err |= std::ios_base::failbit;
              return s;
            }
            char cmd = ct.narrow(*pattern, 0);
            switch (cmd)
            {
            case 'v':
            {
              if (value_found)
              {
                err |= std::ios_base::failbit;
                return s;
              }
              value_found = true;
              s = get_value(s, end, ios, err, r);
              if (err & (std::ios_base::badbit | std::ios_base::failbit))
              {
                return s;
              }
              break;
            }
            case 'u':
            {
              if (unit_found)
              {
                err |= std::ios_base::failbit;
                return s;
              }
              unit_found = true;
              s = get_unit(facet, s, end, ios, err, rt);
              if (err & (std::ios_base::badbit | std::ios_base::failbit))
              {
                return s;
              }
              break;
            }
            default:
              BOOST_ASSERT(false && "Boost::Chrono internal error.");
              break;
            }

            ++pattern;
          }
          else if (ct.is(std::ctype_base::space, *pattern))
          {
            for (++pattern; pattern != pat_end && ct.is(std::ctype_base::space, *pattern); ++pattern)
              ;
            for (; s != end && ct.is(std::ctype_base::space, *s); ++s)
              ;
          }
          else if (ct.toupper(*s) == ct.toupper(*pattern))
          {
            ++s;
            ++pattern;
          }
          else
          {
            err |= std::ios_base::failbit;
            return s;
          }

        }

        unsigned long long num = rt.num;
        unsigned long long den = rt.den;

        // r should be multiplied by (num/den) / Period
        // Reduce (num/den) / Period to lowest terms
        unsigned long long gcd_n1_n2 = integer::gcd<unsigned long long>(num, Period::num);
        unsigned long long gcd_d1_d2 = integer::gcd<unsigned long long>(den, Period::den);
        num /= gcd_n1_n2;
        den /= gcd_d1_d2;
        unsigned long long n2 = Period::num / gcd_n1_n2;
        unsigned long long d2 = Period::den / gcd_d1_d2;
        if (num > (std::numeric_limits<unsigned long long>::max)() / d2 || den
            > (std::numeric_limits<unsigned long long>::max)() / n2)
        {
          // (num/den) / Period overflows
          err |= std::ios_base::failbit;
          return s;
        }
        num *= d2;
        den *= n2;

        typedef typename common_type<intermediate_type, unsigned long long>::type common_type_t;

        // num / den is now factor to multiply by r
        if (!detail::reduce(r, den, err)) return s;

        if (chrono::detail::gt(r, ( (duration_values<common_type_t>::max)() / num)))
        {
          // Conversion to Period overflowed
          err |= std::ios_base::failbit;
          return s;
        }
        common_type_t t = r * num;
        t /= den;
        if (t > duration_values<common_type_t>::zero())
        {
          Rep pt = t;
          if ( (duration_values<Rep>::max)() < pt)
          {
            // Conversion to Period overflowed
            err |= std::ios_base::failbit;
            return s;
          }
        }
        // Success!  Store it.
        r = Rep(t);
        d = duration<Rep, Period> (r);

        return s;
      }

      /**
       *
       * @param s start input stream iterator
       * @param end end input stream iterator
       * @param ios a reference to a ios_base
       * @param err the ios_base state
       * @param d the duration
       * Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if
       * @code
       *   return get(s, end, ios, err, ios, d, str.data(), str.data() + str.size());
       * @codeend
       * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
       */
      template <typename Rep, typename Period>
      iter_type get(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err,
          duration<Rep, Period> & d) const
      {
        if (std::has_facet<duration_units<CharT> >(ios.getloc()))
        {
          duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(ios.getloc());
          std::basic_string<CharT> str = facet.get_pattern();
          return get(facet, s, end, ios, err, d, str.data(), str.data() + str.size());
        }
        else
        {
          duration_units_default<CharT> facet;
          std::basic_string<CharT> str = facet.get_pattern();
          return get(facet, s, end, ios, err, d, str.data(), str.data() + str.size());
        }
      }

      /**
       *
       * @param s start input stream iterator
       * @param end end input stream iterator
       * @param ios a reference to a ios_base
       * @param err the ios_base state
       * @param r a reference to the duration representation.
       * @Effects As if
       * @code
       * return std::use_facet<std::num_get<cahr_type, iter_type> >(ios.getloc()).get(s, end, ios, err, r);
       * @endcode
       *
       * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
       */
      template <typename Rep>
      iter_type get_value(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, Rep& r) const
      {
        return std::use_facet<std::num_get<CharT, iter_type> >(ios.getloc()).get(s, end, ios, err, r);
      }
      template <typename Rep>
      iter_type get_value(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, process_times<Rep>& r) const
      {
        if (s == end) {
            err |= std::ios_base::eofbit;
            return s;
        } else if (*s != '{') { // mandatory '{'
            err |= std::ios_base::failbit;
            return s;
        }
        ++s;
        s = std::use_facet<std::num_get<CharT, iter_type> >(ios.getloc()).get(s, end, ios, err, r.real);
        if (s == end) {
            err |= std::ios_base::eofbit;
            return s;
        } else if (*s != ';') { // mandatory ';'
            err |= std::ios_base::failbit;
            return s;
        }
        ++s;
        s = std::use_facet<std::num_get<CharT, iter_type> >(ios.getloc()).get(s, end, ios, err, r.user);
        if (s == end) {
            err |= std::ios_base::eofbit;
            return s;
        } else if (*s != ';') { // mandatory ';'
            err |= std::ios_base::failbit;
            return s;
        }
        ++s;
        s = std::use_facet<std::num_get<CharT, iter_type> >(ios.getloc()).get(s, end, ios, err, r.system);
        if (s == end) {
            err |= std::ios_base::eofbit;
            return s;
        } else if (*s != '}') { // mandatory '}'
            err |= std::ios_base::failbit;
            return s;
        }
        return s;
      }

      /**
       *
       * @param s start input stream iterator
       * @param e end input stream iterator
       * @param ios a reference to a ios_base
       * @param err the ios_base state
       * @param rt a reference to the duration run-time ratio.
       * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name
       */
      iter_type get_unit(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err, rt_ratio &rt) const
      {
        if (std::has_facet<duration_units<CharT> >(is.getloc()))
        {
          return get_unit(std::use_facet<duration_units<CharT> >(is.getloc()), i, e, is, err, rt);
        }
        else
        {
          duration_units_default<CharT> facet;
          return get_unit(facet, i, e, is, err, rt);
        }
      }

      iter_type get_unit(duration_units<CharT> const &facet, iter_type i, iter_type e, std::ios_base& is,
          std::ios_base::iostate& err, rt_ratio &rt) const
      {

        if (*i == '[')
        {
          // parse [N/D]s or [N/D]second or [N/D]seconds format
          ++i;
          i = std::use_facet<std::num_get<CharT, iter_type> >(is.getloc()).get(i, e, is, err, rt.num);
          if ( (err & std::ios_base::failbit) != 0)
          {
            return i;
          }

          if (i == e)
          {
            err |= std::ios_base::failbit;
            return i;
          }
          CharT x = *i++;
          if (x != '/')
          {
            err |= std::ios_base::failbit;
            return i;
          }
          i = std::use_facet<std::num_get<CharT, iter_type> >(is.getloc()).get(i, e, is, err, rt.den);
          if ( (err & std::ios_base::failbit) != 0)
          {
            return i;
          }
          if (i == e)
          {
            err |= std::ios_base::failbit;
            return i;
          }
          if (*i != ']')
          {
            err |= std::ios_base::failbit;
            return i;
          }
          ++i;
          if (i == e)
          {
            err |= std::ios_base::failbit;
            return i;
          }
          // parse s or second or seconds
          return do_get_n_d_valid_unit(facet, i, e, is, err);
        }
        else
        {
          return do_get_valid_unit(facet, i, e, is, err, rt);
        }
      }

      /**
       * Unique identifier for this type of facet.
       */
      static std::locale::id id;

      /**
       * @Effects Destroy the facet
       */
      ~duration_get()
      {
      }

    protected:

      /**
       * Extracts the run-time ratio associated to the duration when it is given in prefix form.
       *
       * This is an extension point of this facet so that we can take in account other periods that can have a useful
       * translation in other contexts, as e.g. days and weeks.
       *
       * @param facet the duration_units facet
       * @param i start input stream iterator.
       * @param e end input stream iterator.
       * @param ios a reference to a ios_base.
       * @param err the ios_base state.
       * @return @c s
       */
      iter_type do_get_n_d_valid_unit(duration_units<CharT> const &facet, iter_type i, iter_type e,
          std::ios_base&, std::ios_base::iostate& err) const
      {
        // parse SI name, short or long

        const string_type* units = facet.get_n_d_valid_units_start();
        const string_type* units_end = facet.get_n_d_valid_units_end();

        const string_type* k = chrono_detail::scan_keyword(i, e, units, units_end,
        //~ std::use_facet<std::ctype<CharT> >(loc),
            err);
        if (err & (std::ios_base::badbit | std::ios_base::failbit))
        {
          return i;
        }
        if (!facet.match_n_d_valid_unit(k))
        {
          err |= std::ios_base::failbit;
        }
        return i;
      }

      /**
       * Extracts the run-time ratio associated to the duration when it is given in prefix form.
       *
       * This is an extension point of this facet so that we can take in account other periods that can have a useful
       * translation in other contexts, as e.g. days and weeks.
       *
       * @param facet the duration_units facet
       * @param i start input stream iterator.
       * @param e end input stream iterator.
       * @param ios a reference to a ios_base.
       * @param err the ios_base state.
       * @param rt a reference to the duration run-time ratio.
       * @Effects
       * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name.
       */
      iter_type do_get_valid_unit(duration_units<CharT> const &facet, iter_type i, iter_type e,
          std::ios_base&, std::ios_base::iostate& err, rt_ratio &rt) const
      {
        // parse SI name, short or long

        const string_type* units = facet.get_valid_units_start();
        const string_type* units_end = facet.get_valid_units_end();

        err = std::ios_base::goodbit;
        const string_type* k = chrono_detail::scan_keyword(i, e, units, units_end,
        //~ std::use_facet<std::ctype<CharT> >(loc),
            err);
        if (err & (std::ios_base::badbit | std::ios_base::failbit))
        {
          return i;
        }
        if (!facet.match_valid_unit(k, rt))
        {
          err |= std::ios_base::failbit;
        }
        return i;
      }
    };

    /**
     * Unique identifier for this type of facet.
     */
    template <class CharT, class InputIterator>
    std::locale::id duration_get<CharT, InputIterator>::id;

  } // chrono
}
// boost

#endif  // header


code:
#ifndef _DATE_TIME_WRAPPING_INT_HPP__
#define _DATE_TIME_WRAPPING_INT_HPP__

/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
 * Use, modification and distribution is subject to the
 * Boost Software License, Version 1.0. (See accompanying
 * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 * Author: Jeff Garland, Bart Garst
 * $Date$
 */

namespace boost {
namespace date_time {

//! A wrapping integer used to support time durations (WARNING: only instantiate with a signed type)
/*! In composite date and time types this type is used to
 *  wrap at the day boundary.
 *  Ex:
 *  A wrapping_int<short, 10> will roll over after nine, and
 *  roll under below zero. This gives a range of [0,9]
 *
 * NOTE: it is strongly recommended that wrapping_int2 be used
 * instead of wrapping_int as wrapping_int is to be depricated
 * at some point soon.
 *
 * Also Note that warnings will occur if instantiated with an
 * unsigned type. Only a signed type should be used!
 */
template<typename int_type_, int_type_ wrap_val>
class wrapping_int {
public:
  typedef int_type_ int_type;
  //typedef overflow_type_ overflow_type;
  static int_type wrap_value() {return wrap_val;}
  //!Add, return true if wrapped
  wrapping_int(int_type v) : value_(v) {}
  //! Explicit converion method
  int_type as_int()   const   {return value_;}
  operator int_type() const   {return value_;}
  //!Add, return number of wraps performed
  /*! The sign of the returned value will indicate which direction the
   * wraps went. Ex: add a negative number and wrapping under could occur,
   * this would be indicated by a negative return value. If wrapping over
   * took place, a positive value would be returned */
  template< typename IntT >
  IntT add(IntT v)
  {
    int_type remainder = static_cast<int_type>(v % (wrap_val));
    IntT overflow = static_cast<IntT>(v / (wrap_val));
    value_ = static_cast<int_type>(value_ + remainder);
    return calculate_wrap(overflow);
  }
  //! Subtract will return '+d' if wrapping under took place ('d' is the number of wraps)
  /*! The sign of the returned value will indicate which direction the
   * wraps went (positive indicates wrap under, negative indicates wrap over).
   * Ex: subtract a negative number and wrapping over could
   * occur, this would be indicated by a negative return value. If
   * wrapping under took place, a positive value would be returned. */
  template< typename IntT >
  IntT subtract(IntT v)
  {
    int_type remainder = static_cast<int_type>(v % (wrap_val));
    IntT underflow = static_cast<IntT>(-(v / (wrap_val)));
    value_ = static_cast<int_type>(value_ - remainder);
    return calculate_wrap(underflow) * -1;
  }
private:
  int_type value_;

  template< typename IntT >
  IntT calculate_wrap(IntT wrap)
  {
    if ((value_) >= wrap_val)
    {
      ++wrap;
      value_ -= (wrap_val);
    }
    else if(value_ < 0)
    {
      --wrap;
      value_ += (wrap_val);
    }
    return wrap;
  }

};

//! A wrapping integer used to wrap around at the top (WARNING: only instantiate with a signed type)
/*! Bad name, quick impl to fix a bug -- fix later!!
 *  This allows the wrap to restart at a value other than 0.
 */
template<typename int_type_, int_type_ wrap_min, int_type_ wrap_max>
class wrapping_int2 {
public:
  typedef int_type_ int_type;
  static int_type wrap_value() {return wrap_max;}
  static int_type min_value()  {return wrap_min;}
  /*! If initializing value is out of range of [wrap_min, wrap_max],
   * value will be initialized to closest of min or max */
  wrapping_int2(int_type v) : value_(v) {
    if(value_ < wrap_min)
    {
      value_ = wrap_min;
    }
    if(value_ > wrap_max)
    {
      value_ = wrap_max;
    }
  }
  //! Explicit converion method
  int_type as_int()   const   {return value_;}
  operator int_type() const {return value_;}
  //!Add, return number of wraps performed
  /*! The sign of the returned value will indicate which direction the
   * wraps went. Ex: add a negative number and wrapping under could occur,
   * this would be indicated by a negative return value. If wrapping over
   * took place, a positive value would be returned */
  template< typename IntT >
  IntT add(IntT v)
  {
    int_type remainder = static_cast<int_type>(v % (wrap_max - wrap_min + 1));
    IntT overflow = static_cast<IntT>(v / (wrap_max - wrap_min + 1));
    value_ = static_cast<int_type>(value_ + remainder);
    return calculate_wrap(overflow);
  }
  //! Subtract will return '-d' if wrapping under took place ('d' is the number of wraps)
  /*! The sign of the returned value will indicate which direction the
   * wraps went. Ex: subtract a negative number and wrapping over could
   * occur, this would be indicated by a positive return value. If
   * wrapping under took place, a negative value would be returned */
  template< typename IntT >
  IntT subtract(IntT v)
  {
    int_type remainder = static_cast<int_type>(v % (wrap_max - wrap_min + 1));
    IntT underflow = static_cast<IntT>(-(v / (wrap_max - wrap_min + 1)));
    value_ = static_cast<int_type>(value_ - remainder);
    return calculate_wrap(underflow);
  }

private:
  int_type value_;

  template< typename IntT >
  IntT calculate_wrap(IntT wrap)
  {
    if ((value_) > wrap_max)
    {
      ++wrap;
      value_ -= (wrap_max - wrap_min + 1);
    }
    else if((value_) < wrap_min)
    {
      --wrap;
      value_ += (wrap_max - wrap_min + 1);
    }
    return wrap;
  }
};

} } //namespace date_time

#endif

license: mit


code:
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).

//------------------------------------------------------------------------------

#ifndef BOOST_FT_IS_CALLABLE_BUILTIN_HPP_INCLUDED
#define BOOST_FT_IS_CALLABLE_BUILTIN_HPP_INCLUDED

#include <boost/mpl/aux_/lambda_support.hpp>

#include <boost/function_types/components.hpp>

namespace boost
{
  namespace function_types
  {
    template< typename T, typename Tag = null_tag >
    struct is_callable_builtin
      : function_types::represents
        < function_types::components<T>
        , function_types::tag<Tag, detail::callable_builtin_tag>
        >
    {
      BOOST_MPL_AUX_LAMBDA_SUPPORT(2,is_callable_builtin,(T,Tag))
    };
  }
}

#endif


code:
/* Boost interval/detail/x86gcc_rounding_control.hpp file
 *
 * Copyright 2000 Jens Maurer
 * Copyright 2002 Herv� Br�nnimann, Guillaume Melquiond, Sylvain Pion
 *
 * 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)
 */

#ifndef BOOST_NUMERIC_INTERVAL_DETAIL_X86GCC_ROUNDING_CONTROL_HPP
#define BOOST_NUMERIC_INTERVAL_DETAIL_X86GCC_ROUNDING_CONTROL_HPP

#ifndef __GNUC__
#  error This header only works with GNU CC.
#endif

#ifndef __i386__
#  error This header only works on x86 CPUs.
#endif

namespace boost {
namespace numeric {
namespace interval_lib {
namespace detail {

struct x86_rounding
{
  typedef unsigned short rounding_mode;

  static void set_rounding_mode(const rounding_mode& mode)
  { __asm__ __volatile__ ("fldcw %0" : : "m"(mode)); }

  static void get_rounding_mode(rounding_mode& mode)
  { __asm__ __volatile__ ("fnstcw %0" : "=m"(mode)); }

  template<class T>
  static T to_int(T r)
  {
    T r_;
    __asm__ ("frndint" : "=&t"(r_) : "0"(r));
    return r_;
  }
};

} // namespace detail
} // namespace interval_lib
} // namespace numeric
} // namespace boost

#endif /* BOOST_NUMERIC_INTERVAL_DETAIL_X86GCC_ROUNDING_CONTROL_HPP */


code:
#ifndef BOOST_MPL_AUX_LAMBDA_ARITY_PARAM_HPP_INCLUDED
#define BOOST_MPL_AUX_LAMBDA_ARITY_PARAM_HPP_INCLUDED

// Copyright Aleksey Gurtovoy 2001-2004
//
// 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)
//
// See http://www.boost.org/libs/mpl for documentation.

// $Id$
// $Date$
// $Revision$

#include <boost/mpl/aux_/config/ttp.hpp>

#if !defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING)
#   define BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(param)
#else
#   define BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(param) , param
#endif

#endif // BOOST_MPL_AUX_LAMBDA_ARITY_PARAM_HPP_INCLUDED


code:
/*
Copyright Rene Rivera 2008-2015
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)
*/

#ifndef BOOST_PREDEF_LIBRARY_STD_DINKUMWARE_H
#define BOOST_PREDEF_LIBRARY_STD_DINKUMWARE_H

#include <boost/predef/library/std/_prefix.h>

#include <boost/predef/version_number.h>
#include <boost/predef/make.h>

/*`
[heading `BOOST_LIB_STD_DINKUMWARE`]

[@http://en.wikipedia.org/wiki/Dinkumware Dinkumware] Standard C++ Library.
If available version number as major, minor, and patch.

[table
    [[__predef_symbol__] [__predef_version__]]

    [[`_YVALS`, `__IBMCPP__`] [__predef_detection__]]
    [[`_CPPLIB_VER`] [__predef_detection__]]

    [[`_CPPLIB_VER`] [V.R.0]]
    ]
 */

#define BOOST_LIB_STD_DINKUMWARE BOOST_VERSION_NUMBER_NOT_AVAILABLE

#if (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
#   undef BOOST_LIB_STD_DINKUMWARE
#   if defined(_CPPLIB_VER)
#       define BOOST_LIB_STD_DINKUMWARE BOOST_PREDEF_MAKE_10_VVRR(_CPPLIB_VER)
#   else
#       define BOOST_LIB_STD_DINKUMWARE BOOST_VERSION_NUMBER_AVAILABLE
#   endif
#endif

#if BOOST_LIB_STD_DINKUMWARE
#   define BOOST_LIB_STD_DINKUMWARE_AVAILABLE
#endif

#define BOOST_LIB_STD_DINKUMWARE_NAME "Dinkumware"

#endif

#include <boost/predef/detail/test.h>
BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_DINKUMWARE,BOOST_LIB_STD_DINKUMWARE_NAME)


code:
// Copyright David Abrahams 2002.
// 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)
#ifndef MAP_ENTRY_DWA2002118_HPP
# define MAP_ENTRY_DWA2002118_HPP

namespace boost { namespace python { namespace detail {

// A trivial type that works well as the value_type of associative
// vector maps
template <class Key, class Value>
struct map_entry
{
    map_entry() {}
    map_entry(Key k) : key(k), value() {}
    map_entry(Key k, Value v) : key(k), value(v) {}

    bool operator<(map_entry const& rhs) const
    {
        return this->key < rhs.key;
    }

    Key key;
    Value value;
};

template <class Key, class Value>
bool operator<(map_entry<Key,Value> const& e, Key const& k)
{
    return e.key < k;
}

template <class Key, class Value>
bool operator<(Key const& k, map_entry<Key,Value> const& e)
{
    return k < e.key;
}

}}} // namespace boost::python::detail

#endif // MAP_ENTRY_DWA2002118_HPP


code:
/* Boost interval/compare/certain.hpp template implementation file
 *
 * Copyright 2003 Guillaume Melquiond
 *
 * 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)
 */

#ifndef BOOST_NUMERIC_INTERVAL_COMPARE_CERTAIN_HPP
#define BOOST_NUMERIC_INTERVAL_COMPARE_CERTAIN_HPP

#include <boost/numeric/interval/detail/interval_prototype.hpp>
#include <boost/numeric/interval/detail/test_input.hpp>

namespace boost {
namespace numeric {
namespace interval_lib {
namespace compare {
namespace certain {

template<class T, class Policies1, class Policies2> inline
bool operator<(const interval<T, Policies1>& x, const interval<T, Policies2>& y)
{
  if (detail::test_input(x, y)) throw comparison_error();
  return x.upper() < y.lower();
}

template<class T, class Policies> inline
bool operator<(const interval<T, Policies>& x, const T& y)
{
  if (detail::test_input(x, y)) throw comparison_error();
  return x.upper() < y;
}

template<class T, class Policies1, class Policies2> inline
bool operator<=(const interval<T, Policies1>& x, const interval<T, Policies2>& y)
{
  if (detail::test_input(x, y)) throw comparison_error();
  return x.upper() <= y.lower();
}

template<class T, class Policies> inline
bool operator<=(const interval<T, Policies>& x, const T& y)
{
  if (detail::test_input(x, y)) throw comparison_error();
  return x.upper() <= y;
}

template<class T, class Policies1, class Policies2> inline
bool operator>(const interval<T, Policies1>& x, const interval<T, Policies2>& y)
{
  if (detail::test_input(x, y)) throw comparison_error();
  return x.lower() > y.upper();
}

template<class T, class Policies> inline
bool operator>(const interval<T, Policies>& x, const T& y)
{
  if (detail::test_input(x, y)) throw comparison_error();
  return x.lower() > y;
}

template<class T, class Policies1, class Policies2> inline
bool operator>=(const interval<T, Policies1>& x, const interval<T, Policies2>& y)
{
  if (detail::test_input(x, y)) throw comparison_error();
  return x.lower() >= y.upper();
}

template<class T, class Policies> inline
bool operator>=(const interval<T, Policies>& x, const T& y)
{
  if (detail::test_input(x, y)) throw comparison_error();
  return x.lower() >= y;
}

template<class T, class Policies1, class Policies2> inline
bool operator==(const interval<T, Policies1>& x, const interval<T, Policies2>& y)
{
  if (detail::test_input(x, y)) throw comparison_error();
  return x.upper() == y.lower() && x.lower() == y.upper();
}

template<class T, class Policies> inline
bool operator==(const interval<T, Policies>& x, const T& y)
{
  if (detail::test_input(x, y)) throw comparison_error();
  return x.upper() == y && x.lower() == y;
}

template<class T, class Policies1, class Policies2> inline
bool operator!=(const interval<T, Policies1>& x, const interval<T, Policies2>& y)
{
  if (detail::test_input(x, y)) throw comparison_error();
  return x.upper() < y.lower() || x.lower() > y.upper();
}

template<class T, class Policies> inline
bool operator!=(const interval<T, Policies>& x, const T& y)
{
  if (detail::test_input(x, y)) throw comparison_error();
  return x.upper() < y || x.lower() > y;
}

} // namespace certain
} // namespace compare
} // namespace interval_lib
} // namespace numeric
} // namespace boost

#endif // BOOST_NUMERIC_INTERVAL_COMPARE_CERTAIN_HPP


code:
# /* **************************************************************************
#  *                                                                          *
#  *     (C) Copyright Paul Mensonides 2002-2011.                             *
#  *     (C) Copyright Edward Diener 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)                                *
#  *                                                                          *
#  ************************************************************************** */
#
# /* See http://www.boost.org for most recent version. */
#
# ifndef BOOST_PREPROCESSOR_CONFIG_CONFIG_HPP
# define BOOST_PREPROCESSOR_CONFIG_CONFIG_HPP
#
# /* BOOST_PP_CONFIG_FLAGS */
#
# define BOOST_PP_CONFIG_STRICT() 0x0001
# define BOOST_PP_CONFIG_IDEAL() 0x0002
#
# define BOOST_PP_CONFIG_MSVC() 0x0004
# define BOOST_PP_CONFIG_MWCC() 0x0008
# define BOOST_PP_CONFIG_BCC() 0x0010
# define BOOST_PP_CONFIG_EDG() 0x0020
# define BOOST_PP_CONFIG_DMC() 0x0040
#
# ifndef BOOST_PP_CONFIG_FLAGS
#    if defined(__GCCXML__)
#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT())
#    elif defined(__WAVE__)
#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT())
#    elif defined(__MWERKS__) && __MWERKS__ >= 0x3200
#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT())
#    elif defined(__EDG__) || defined(__EDG_VERSION__)
#        if defined(_MSC_VER) && (defined(__INTELLISENSE__) || __EDG_VERSION__ >= 308)
#            define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_MSVC())
#        else
#            define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_EDG() | BOOST_PP_CONFIG_STRICT())
#        endif
#    elif defined(__MWERKS__)
#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_MWCC())
#    elif defined(__DMC__)
#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_DMC())
#    elif defined(__BORLANDC__) && __BORLANDC__ >= 0x581
#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT())
#    elif defined(__BORLANDC__) || defined(__IBMC__) || defined(__IBMCPP__) || defined(__SUNPRO_CC)
#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_BCC())
#    elif defined(_MSC_VER) && !defined(__clang__)
#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_MSVC())
#    else
#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT())
#    endif
# endif
#
# /* BOOST_PP_CONFIG_EXTENDED_LINE_INFO */
#
# ifndef BOOST_PP_CONFIG_EXTENDED_LINE_INFO
#    define BOOST_PP_CONFIG_EXTENDED_LINE_INFO 0
# endif
#
# /* BOOST_PP_CONFIG_ERRORS */
#
# ifndef BOOST_PP_CONFIG_ERRORS
#    ifdef NDEBUG
#        define BOOST_PP_CONFIG_ERRORS 0
#    else
#        define BOOST_PP_CONFIG_ERRORS 1
#    endif
# endif
#
# /* BOOST_PP_VARIADICS */
#
# define BOOST_PP_VARIADICS_MSVC 0
# if !defined BOOST_PP_VARIADICS
#    /* variadic support explicitly disabled for all untested compilers */
#    if defined __GCCXML__ || defined __CUDACC__ || defined __PATHSCALE__ || defined __DMC__ || defined __CODEGEARC__ || defined __BORLANDC__ || defined __MWERKS__ || ( defined __SUNPRO_CC && __SUNPRO_CC < 0x5120 ) || defined __HP_aCC && !defined __EDG__ || defined __MRC__ || defined __SC__ || defined __IBMCPP__ || defined __PGI
#        define BOOST_PP_VARIADICS 0
#    /* VC++ (C/C++) */
#    elif defined _MSC_VER && _MSC_VER >= 1400 && (!defined __EDG__ || defined(__INTELLISENSE__)) && !defined __clang__
#        define BOOST_PP_VARIADICS 1
#        undef BOOST_PP_VARIADICS_MSVC
#        define BOOST_PP_VARIADICS_MSVC 1
#    /* Wave (C/C++), GCC (C++) */
#    elif defined __WAVE__ && __WAVE_HAS_VARIADICS__ || defined __GNUC__ && defined __GXX_EXPERIMENTAL_CXX0X__ && __GXX_EXPERIMENTAL_CXX0X__
#        define BOOST_PP_VARIADICS 1
#    /* EDG-based (C/C++), GCC (C), and unknown (C/C++) */
#    elif !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L
#        define BOOST_PP_VARIADICS 1
#    else
#        define BOOST_PP_VARIADICS 0
#    endif
# elif !BOOST_PP_VARIADICS + 1 < 2
#    undef BOOST_PP_VARIADICS
#    define BOOST_PP_VARIADICS 1
#    if defined _MSC_VER && _MSC_VER >= 1400 && (defined(__INTELLISENSE__) || !(defined __EDG__ || defined __GCCXML__ || defined __CUDACC__ || defined __PATHSCALE__ || defined __clang__ || defined __DMC__ || defined __CODEGEARC__ || defined __BORLANDC__ || defined __MWERKS__ || defined __SUNPRO_CC || defined __HP_aCC || defined __MRC__ || defined __SC__ || defined __IBMCPP__ || defined __PGI))
#        undef BOOST_PP_VARIADICS_MSVC
#        define BOOST_PP_VARIADICS_MSVC 1
#    endif
# else
#    undef BOOST_PP_VARIADICS
#    define BOOST_PP_VARIADICS 0
# endif
#
# endif


code:
/*
 [auto_generated]
 boost/numeric/odeint/iterator/adaptive_iterator.hpp

 [begin_description]
 Iterator for iterating throught the solution of an ODE with adaptive step size. The dereferenced types containes also the time.
 [end_description]

 Copyright 2012-2013 Karsten Ahnert
 Copyright 2012 Mario Mulansky

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

#ifndef BOOST_NUMERIC_ODEINT_ITERATOR_ADAPTIVE_ITERATOR_HPP_INCLUDED
#define BOOST_NUMERIC_ODEINT_ITERATOR_ADAPTIVE_ITERATOR_HPP_INCLUDED

#include <boost/numeric/odeint/util/stepper_traits.hpp>
#include <boost/numeric/odeint/util/unit_helper.hpp>
#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
#include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
#include <boost/numeric/odeint/iterator/impl/adaptive_iterator_impl.hpp>

namespace boost {
namespace numeric {
namespace odeint {

    /* use the adaptive_iterator_impl with the right tags */
    template< class Stepper , class System , class State
#ifndef DOXYGEN_SKIP
        , class StepperTag = typename base_tag< typename traits::stepper_category< Stepper >::type >::type
#endif
    >
    class adaptive_iterator : public adaptive_iterator_impl<
            adaptive_iterator< Stepper , System , State , StepperTag > ,
            Stepper , System , State , detail::ode_state_iterator_tag , StepperTag
        >
    {
        typedef typename traits::time_type< Stepper >::type time_type;
        typedef adaptive_iterator< Stepper , System , State , StepperTag > iterator_type;

    public:
        adaptive_iterator( Stepper stepper , System sys , State &s , time_type t_start , time_type t_end , time_type dt )
            : adaptive_iterator_impl< iterator_type , Stepper , System , State , detail::ode_state_iterator_tag , StepperTag >( stepper , sys , s , t_start , t_end , dt )
        {}

        adaptive_iterator( Stepper stepper , System sys , State &s )
            : adaptive_iterator_impl< iterator_type , Stepper , System , State , detail::ode_state_iterator_tag , StepperTag >( stepper , sys , s )
        {}
    };

    template< class Stepper , class System , class State >
    adaptive_iterator< Stepper , System , State > make_adaptive_iterator_begin(
        Stepper stepper ,
        System system ,
        State &x ,
        typename traits::time_type< Stepper >::type t_start ,
        typename traits::time_type< Stepper >::type t_end ,
        typename traits::time_type< Stepper >::type dt )
    {
        return adaptive_iterator< Stepper , System , State >( stepper , system , x , t_start , t_end , dt );
    }

    template< class Stepper , class System , class State >
    adaptive_iterator< Stepper , System , State > make_adaptive_iterator_end(
        Stepper stepper ,
        System system ,
        State &x )
    {
        return adaptive_iterator< Stepper , System , State >( stepper , system , x );
    }

    template< class Stepper , class System , class State >
    std::pair< adaptive_iterator< Stepper , System , State > , adaptive_iterator< Stepper , System , State > >
    make_adaptive_range(
        Stepper stepper ,
        System system ,
        State &x ,
        typename traits::time_type< Stepper >::type t_start ,
        typename traits::time_type< Stepper >::type t_end ,
        typename traits::time_type< Stepper >::type dt )
    {
        return std::make_pair(
            adaptive_iterator< Stepper , System , State >( stepper , system , x , t_start , t_end , dt ) ,
            adaptive_iterator< Stepper , System , State >( stepper , system , x )
            );
    }

    /**
     * \class adaptive_iterator
     *
     * \brief ODE Iterator with adaptive step size. The value type of this iterator is the state type of the stepper.
     *
     * Implements an iterator representing the solution of an ODE from t_start
     * to t_end evaluated at steps with an adaptive step size dt.
     * After each iteration the iterator dereferences to the state x at the next
     * time t+dt where dt is controlled by the stepper.
     * This iterator can be used with ControlledSteppers and
     * DenseOutputSteppers and it always makes use of the all the given steppers
     * capabilities. A for_each over such an iterator range behaves similar to
     * the integrate_adaptive routine.
     *
     * adaptive_iterator is a model of single-pass iterator.
     *
     * The value type of this iterator is the state type of the stepper. Hence one can only access the state and not the current time.
     *
     * \tparam Stepper The stepper type which should be used during the iteration.
     * \tparam System The type of the system function (ODE) which should be solved.
     * \tparam State The state type of the ODE.
     */

    /**
     * \fn make_adaptive_iterator_begin( Stepper stepper , System system , State &x ,
        typename traits::time_type< Stepper >::type t_start ,
        typename traits::time_type< Stepper >::type t_end ,
        typename traits::time_type< Stepper >::type dt )
     *
     * \brief Factory function for adaptive_iterator. Constructs a begin iterator.
     *
     * \param stepper The stepper to use during the iteration.
     * \param system The system function (ODE) to solve.
     * \param x The initial state.
     * \param t_start The initial time.
     * \param t_end The end time, at which the iteration should stop.
     * \param dt The initial time step.
     * \returns The adaptive iterator.
     */

    /**
     * \fn make_adaptive_iterator_end( Stepper stepper , System system , State &x )
     * \brief Factory function for adaptive_iterator. Constructs a end iterator.
     *
     * \param stepper The stepper to use during the iteration.
     * \param system The system function (ODE) to solve.
     * \param x The initial state.
     * \returns The adaptive iterator.
     */

    /**
     * \fn make_adaptive_range( Stepper stepper , System system , State &x ,
        typename traits::time_type< Stepper >::type t_start ,
        typename traits::time_type< Stepper >::type t_end ,
        typename traits::time_type< Stepper >::type dt )
     *
     * \brief Factory function to construct a single pass range of adaptive iterators. A range is here a pair of adaptive_iterator.
     *
     * \param stepper The stepper to use during the iteration.
     * \param system The system function (ODE) to solve.
     * \param x The initial state.
     * \param t_start The initial time.
     * \param t_end The end time, at which the iteration should stop.
     * \param dt The initial time step.
     * \returns The adaptive range.
     */

} // namespace odeint
} // namespace numeric
} // namespace boost

#endif // BOOST_NUMERIC_ODEINT_ITERATOR_ADAPTIVE_ITERATOR_HPP_INCLUDED


code:
// Copyright David Abrahams 2002.
// Copyright Stefan Seefeld 2016.
// 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)

#ifndef boost_python_converter_shared_ptr_from_python_hpp_
#define boost_python_converter_shared_ptr_from_python_hpp_

#include <boost/python/handle.hpp>
#include <boost/python/converter/shared_ptr_deleter.hpp>
#include <boost/python/converter/from_python.hpp>
#include <boost/python/converter/rvalue_from_python_data.hpp>
#include <boost/python/converter/registered.hpp>
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
# include <boost/python/converter/pytype_function.hpp>
#endif
#include <boost/shared_ptr.hpp>
#include <memory>

namespace boost { namespace python { namespace converter {

template <class T, template <typename> class SP>
struct shared_ptr_from_python
{
  shared_ptr_from_python()
  {
    converter::registry::insert(&convertible, &construct, type_id<SP<T> >()
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
				, &converter::expected_from_python_type_direct<T>::get_pytype
#endif
				);
  }

 private:
  static void* convertible(PyObject* p)
  {
    if (p == Py_None)
      return p;

    return converter::get_lvalue_from_python(p, registered<T>::converters);
  }

  static void construct(PyObject* source, rvalue_from_python_stage1_data* data)
  {
    void* const storage = ((converter::rvalue_from_python_storage<SP<T> >*)data)->storage.bytes;
    // Deal with the "None" case.
    if (data->convertible == source)
      new (storage) SP<T>();
    else
    {
      SP<void> hold_convertible_ref_count(
	 (void*)0, shared_ptr_deleter(handle<>(borrowed(source))) );
      // use aliasing constructor
      new (storage) SP<T>(hold_convertible_ref_count,
			  static_cast<T*>(data->convertible));
    }

    data->convertible = storage;
  }
};

}}} // namespace boost::python::converter

#endif


code:
// Boost.Range library
//
//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
//  distribution is subject to 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)
//
// For more information, see http://www.boost.org/libs/range/
//

#ifndef BOOST_RANGE_DETAIL_SIZE_TYPE_HPP
#define BOOST_RANGE_DETAIL_SIZE_TYPE_HPP

#include <boost/range/detail/common.hpp>

//////////////////////////////////////////////////////////////////////////////
// missing partial specialization  workaround.
//////////////////////////////////////////////////////////////////////////////

namespace boost
{
    namespace range_detail
    {
        template< typename T >
        struct range_size_type_
        {
            template< typename C >
            struct pts
            {
                typedef std::size_t type;
            };
        };

        template<>
        struct range_size_type_<std_container_>
        {
            template< typename C >
            struct pts
            {
                typedef BOOST_RANGE_DEDUCED_TYPENAME C::size_type type;
            };
        };
    }

    template< typename C >
    class range_size
    {
        typedef typename range_detail::range<C>::type c_type;
    public:
        typedef typename range_detail::range_size_type_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type;
    };
}

#endif


code:
//  (C) Copyright Gennadiy Rozental 2001.
//  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)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision$
//
//  Description : simple helpers for creating cusom output manipulators
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_CUSTOM_MANIP_HPP
#define BOOST_TEST_UTILS_CUSTOM_MANIP_HPP

// STL
#include <iosfwd>

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

namespace boost {
namespace unit_test {
namespace utils {

// ************************************************************************** //
// **************          custom manipulators helpers         ************** //
// ************************************************************************** //

template<typename Manip>
struct custom_printer {
    explicit custom_printer( std::ostream& ostr ) : m_ostr( &ostr ) {}

    std::ostream& operator*() const { return *m_ostr; }

private:
    std::ostream* const m_ostr;
};

//____________________________________________________________________________//

template<typename Uniq> struct custom_manip {};

//____________________________________________________________________________//

template<typename Uniq>
inline custom_printer<custom_manip<Uniq> >
operator<<( std::ostream& ostr, custom_manip<Uniq> const& ) { return custom_printer<custom_manip<Uniq> >( ostr ); }

//____________________________________________________________________________//

} // namespace utils
} // namespace unit_test
} // namespace boost

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_UTILS_CUSTOM_MANIP_HPP


code:
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).

//------------------------------------------------------------------------------

#ifndef BOOST_FT_CONFIG_COMPILER_HPP_INCLUDED
#define BOOST_FT_CONFIG_COMPILER_HPP_INCLUDED

#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>

#if defined(BOOST_MSVC)

#   if BOOST_MSVC < 1310
#     error "unsupported compiler version"
#   endif

#   ifdef BOOST_FT_AUTODETECT_CALLING_CONVENTIONS

      // enable clrcall calling covention (call to .NET managed code) when
      // compiling with /clr
#     if BOOST_MSVC >= 1400 && defined(__cplusplus_cli)
#       ifndef BOOST_FT_CC_CLRCALL
#       define BOOST_FT_CC_CLRCALL callable_builtin
#       endif
#     endif

      // Intel x86 architecture specific calling conventions
#     ifdef _M_IX86
#       define BOOST_FT_COMMON_X86_CCs callable_builtin
#       if BOOST_MSVC < 1400
          // version 7.1 is missing a keyword to specify the thiscall cc ...
#         ifndef BOOST_FT_CC_IMPLICIT_THISCALL
#         define BOOST_FT_CC_IMPLICIT_THISCALL non_variadic|member|callable_builtin
#         ifndef BOOST_FT_CONFIG_OK
#           pragma message("INFO| /Gd /Gr /Gz will compiler options will cause")
#           pragma message("INFO| a compile error.")
#           pragma message("INFO| Reconfigure Boost.FunctionTypes in this case.")
#           pragma message("INFO| This message can be suppressed by defining")
#           pragma message("INFO| BOOST_FT_CONFIG_OK.")
#         endif
#         endif
#       else
          // ...introduced in version 8
#         ifndef BOOST_FT_CC_THISCALL
#         define BOOST_FT_CC_THISCALL non_variadic|member|callable_builtin
#         endif
#       endif
#     endif
#   endif

#elif defined(__GNUC__) && !defined(BOOST_INTEL_LINUX)

#   if __GNUC__ < 3
#     error "unsupported compiler version"
#   endif

#   ifdef BOOST_FT_AUTODETECT_CALLING_CONVENTIONS

#     if defined(__i386__)
#       // see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20439
#       // see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29328
#       if BOOST_WORKAROUND(__GNUC__,BOOST_TESTED_AT(4))
#         ifndef BOOST_FT_CC_IMPLICIT
#         define BOOST_FT_CC_IMPLICIT member|callable_builtin
#         endif
#         define BOOST_FT_COMMON_X86_CCs non_member|callable_builtin
#       else
#         define BOOST_FT_COMMON_X86_CCs callable_builtin
#       endif
#     else
#       ifndef BOOST_FT_CC_IMPLICIT
#       define BOOST_FT_CC_IMPLICIT callable_builtin
#       endif
#     endif
#   endif

#   if (defined(BOOST_FT_CC_CDECL) || defined(BOOST_FT_COMMON_X86_CCs)) \
        && !defined(__cdecl)
#     define __cdecl __attribute__((__cdecl__))
#   endif
#   if (defined(BOOST_FT_CC_STDCALL) || defined(BOOST_FT_COMMON_X86_CCs)) \
        && !defined(__stdcall)
#     define __stdcall __attribute__((__stdcall__))
#   endif
#   if (defined(BOOST_FT_CC_FASTCALL) || defined(BOOST_FT_COMMON_X86_CCs)) \
        && !defined(__fastcall)
#     define __fastcall __attribute__((__fastcall__))
#   endif

#elif defined(__BORLANDC__)

#   if __BORLANDC__ < 0x550
#     error "unsupported compiler version"
#   elif __BORLANDC__ > 0x565
#     pragma message("WARNING: library untested with this compiler version")
#   endif

#   ifdef BOOST_FT_AUTODETECT_CALLING_CONVENTIONS
#     define BOOST_FT_COMMON_X86_CCs callable_builtin
#   endif

    // syntactic specialities of cc specifier
#   define BOOST_FT_SYNTAX(result,lparen,cc_spec,type_mod,name,rparen) \
                        result() cc_spec() lparen() type_mod() name() rparen()
#else
    // only enable default calling convention
#   define BOOST_FT_CC_IMPLICIT callable_builtin
#endif

#endif


code:
subroutine chkhist(mrsym,nmax,ipk)

  integer mrsym(63)
  integer hist(0:63)

  hist=0
  do j=1,63
     i=mrsym(j)
     hist(i)=hist(i)+1
  enddo

  nmax=0
  do i=0,63
     if(hist(i).gt.nmax) then
        nmax=hist(i)
        ipk=i+1
     endif
  enddo

  return
end subroutine chkhist


code:
// Copyright (C) 2004-2006 The Trustees of Indiana University.

// Use, modification and distribution is subject to 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)

//  Authors: Douglas Gregor
//           Andrew Lumsdaine
#ifndef BOOST_GRAPH_DISTRIBUTED_QUEUE_HPP
#define BOOST_GRAPH_DISTRIBUTED_QUEUE_HPP

#ifndef BOOST_GRAPH_USE_MPI
#error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
#endif

#include <boost/graph/parallel/process_group.hpp>
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
#include <vector>

namespace boost { namespace graph { namespace distributed {

/// A unary predicate that always returns "true".
struct always_push
{
  template<typename T> bool operator()(const T&) const { return true; }
};

/** A distributed queue adaptor.
 *
 * Class template @c distributed_queue implements a distributed queue
 * across a process group. The distributed queue is an adaptor over an
 * existing (local) queue, which must model the @ref Buffer
 * concept. Each process stores a distinct copy of the local queue,
 * from which it draws or removes elements via the @ref pop and @ref
 * top members.
 *
 * The value type of the local queue must be a model of the @ref
 * GlobalDescriptor concept. The @ref push operation of the
 * distributed queue passes (via a message) the value to its owning
 * processor. Thus, the elements within a particular local queue are
 * guaranteed to have the process owning that local queue as an owner.
 *
 * Synchronization of distributed queues occurs in the @ref empty and
 * @ref size functions, which will only return "empty" values (true or
 * 0, respectively) when the entire distributed queue is empty. If the
 * local queue is empty but the distributed queue is not, the
 * operation will block until either condition changes. When the @ref
 * size function of a nonempty queue returns, it returns the size of
 * the local queue. These semantics were selected so that sequential
 * code that processes elements in the queue via the following idiom
 * can be parallelized via introduction of a distributed queue:
 *
 *   distributed_queue<...> Q;
 *   Q.push(x);
 *   while (!Q.empty()) {
 *     // do something, that may push a value onto Q
 *   }
 *
 * In the parallel version, the initial @ref push operation will place
 * the value @c x onto its owner's queue. All processes will
 * synchronize at the call to empty, and only the process owning @c x
 * will be allowed to execute the loop (@ref Q.empty() returns
 * false). This iteration may in turn push values onto other remote
 * queues, so when that process finishes execution of the loop body
 * and all processes synchronize again in @ref empty, more processes
 * may have nonempty local queues to execute. Once all local queues
 * are empty, @ref Q.empty() returns @c false for all processes.
 *
 * The distributed queue can receive messages at two different times:
 * during synchronization and when polling @ref empty. Messages are
 * always received during synchronization, to ensure that accurate
 * local queue sizes can be determines. However, whether @ref empty
 * should poll for messages is specified as an option to the
 * constructor. Polling may be desired when the order in which
 * elements in the queue are processed is not important, because it
 * permits fewer synchronization steps and less communication
 * overhead. However, when more strict ordering guarantees are
 * required, polling may be semantically incorrect. By disabling
 * polling, one ensures that parallel execution using the idiom above
 * will not process an element at a later "level" before an earlier
 * "level".
 *
 * The distributed queue nearly models the @ref Buffer
 * concept. However, the @ref push routine does not necessarily
 * increase the result of @c size() by one (although the size of the
 * global queue does increase by one).
 */
template<typename ProcessGroup, typename OwnerMap, typename Buffer,
         typename UnaryPredicate = always_push>
class distributed_queue
{
  typedef distributed_queue self_type;

  enum {
    /** Message indicating a remote push. The message contains a
     * single value x of type value_type that is to be pushed on the
     * receiver's queue.
     */
    msg_push,
    /** Push many elements at once. */
    msg_multipush
  };

 public:
  typedef ProcessGroup                     process_group_type;
  typedef Buffer                           buffer_type;
  typedef typename buffer_type::value_type value_type;
  typedef typename buffer_type::size_type  size_type;

  /** Construct a new distributed queue.
   *
   * Build a new distributed queue that communicates over the given @p
   * process_group, whose local queue is initialized via @p buffer and
   * which may or may not poll for messages.
   */
  explicit
  distributed_queue(const ProcessGroup& process_group,
                    const OwnerMap& owner,
                    const Buffer& buffer,
                    bool polling = false);

  /** Construct a new distributed queue.
   *
   * Build a new distributed queue that communicates over the given @p
   * process_group, whose local queue is initialized via @p buffer and
   * which may or may not poll for messages.
   */
  explicit
  distributed_queue(const ProcessGroup& process_group = ProcessGroup(),
                    const OwnerMap& owner = OwnerMap(),
                    const Buffer& buffer = Buffer(),
                    const UnaryPredicate& pred = UnaryPredicate(),
                    bool polling = false);

  /** Construct a new distributed queue.
   *
   * Build a new distributed queue that communicates over the given @p
   * process_group, whose local queue is default-initalized and which
   * may or may not poll for messages.
   */
  distributed_queue(const ProcessGroup& process_group, const OwnerMap& owner,
                    const UnaryPredicate& pred, bool polling = false);

  /** Virtual destructor required with virtual functions.
   *
   */
  virtual ~distributed_queue() {}

  /** Push an element onto the distributed queue.
   *
   * The element will be sent to its owner process to be added to that
   * process's local queue. If polling is enabled for this queue and
   * the owner process is the current process, the value will be
   * immediately pushed onto the local queue.
   *
   * Complexity: O(1) messages of size O(sizeof(value_type)) will be
   * transmitted.
   */
  void push(const value_type& x);

  /** Pop an element off the local queue.
   *
   * @p @c !empty()
   */
  void pop() { buffer.pop(); }

  /**
   * Return the element at the top of the local queue.
   *
   * @p @c !empty()
   */
  value_type& top() { return buffer.top(); }

  /**
   * \overload
   */
  const value_type& top() const { return buffer.top(); }

  /** Determine if the queue is empty.
   *
   * When the local queue is nonempty, returns @c true. If the local
   * queue is empty, synchronizes with all other processes in the
   * process group until either (1) the local queue is nonempty
   * (returns @c true) (2) the entire distributed queue is empty
   * (returns @c false).
   */
  bool empty() const;

  /** Determine the size of the local queue.
   *
   * The behavior of this routine is equivalent to the behavior of
   * @ref empty, except that when @ref empty returns true this
   * function returns the size of the local queue and when @ref empty
   * returns false this function returns zero.
   */
  size_type size() const;

  // private:
  /** Synchronize the distributed queue and determine if all queues
   * are empty.
   *
   * \returns \c true when all local queues are empty, or false if at least
   * one of the local queues is nonempty.
   * Defined as virtual for derived classes like depth_limited_distributed_queue.
   */
  virtual bool do_synchronize() const;

 private:
  // Setup triggers
  void setup_triggers();

  // Message handlers
  void
  handle_push(int source, int tag, const value_type& value,
              trigger_receive_context);

  void
  handle_multipush(int source, int tag, const std::vector<value_type>& values,
                   trigger_receive_context);

  mutable ProcessGroup process_group;
  OwnerMap owner;
  mutable Buffer buffer;
  UnaryPredicate pred;
  bool polling;

  typedef std::vector<value_type> outgoing_buffer_t;
  typedef std::vector<outgoing_buffer_t> outgoing_buffers_t;
  shared_ptr<outgoing_buffers_t> outgoing_buffers;
};

/// Helper macro containing the normal names for the template
/// parameters to distributed_queue.
#define BOOST_DISTRIBUTED_QUEUE_PARMS                           \
  typename ProcessGroup, typename OwnerMap, typename Buffer,    \
  typename UnaryPredicate

/// Helper macro containing the normal template-id for
/// distributed_queue.
#define BOOST_DISTRIBUTED_QUEUE_TYPE                                    \
  distributed_queue<ProcessGroup, OwnerMap, Buffer, UnaryPredicate>

/** Synchronize all processes involved with the given distributed queue.
 *
 * This function will synchronize all of the local queues for a given
 * distributed queue, by ensuring that no additional messages are in
 * transit. It is rarely required by the user, because most
 * synchronization of distributed queues occurs via the @c empty or @c
 * size methods.
 */
template<BOOST_DISTRIBUTED_QUEUE_PARMS>
inline void
synchronize(const BOOST_DISTRIBUTED_QUEUE_TYPE& Q)
{ Q.do_synchronize(); }

/// Construct a new distributed queue.
template<typename ProcessGroup, typename OwnerMap, typename Buffer>
inline distributed_queue<ProcessGroup, OwnerMap, Buffer>
make_distributed_queue(const ProcessGroup& process_group,
                       const OwnerMap& owner,
                       const Buffer& buffer,
                       bool polling = false)
{
  typedef distributed_queue<ProcessGroup, OwnerMap, Buffer> result_type;
  return result_type(process_group, owner, buffer, polling);
}

} } } // end namespace boost::graph::distributed

#include <boost/graph/distributed/detail/queue.ipp>

#undef BOOST_DISTRIBUTED_QUEUE_TYPE
#undef BOOST_DISTRIBUTED_QUEUE_PARMS

#endif // BOOST_GRAPH_DISTRIBUTED_QUEUE_HPP


code:
/*=============================================================================
    Copyright (c) 1999-2003 Jaakko Jarvi
    Copyright (c) 2001-2011 Joel de Guzman

    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)
==============================================================================*/
#if !defined(FUSION_LESS_05052005_0432)
#define FUSION_LESS_05052005_0432

#include <boost/fusion/support/config.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/fusion/sequence/comparison/detail/less.hpp>
#include <boost/fusion/sequence/comparison/enable_comparison.hpp>

namespace boost { namespace fusion
{
    template <typename Seq1, typename Seq2>
    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
    inline bool
    less(Seq1 const& a, Seq2 const& b)
    {
        return detail::sequence_less<Seq1 const, Seq2 const>::
            call(fusion::begin(a), fusion::begin(b));
    }

    namespace operators
    {
        template <typename Seq1, typename Seq2>
        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
        inline typename
            boost::enable_if<
                traits::enable_comparison<Seq1, Seq2>
              , bool
            >::type
        operator<(Seq1 const& a, Seq2 const& b)
        {
            return fusion::less(a, b);
        }
    }
    using operators::operator<;
}}

#endif


code:
//  (C) Copyright John Maddock 2007.
//  Use, modification and distribution are subject to 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).
//
//  See http://www.boost.org/libs/type_traits for most recent version including documentation.

#ifndef BOOST_TT_MAKE_SIGNED_HPP_INCLUDED
#define BOOST_TT_MAKE_SIGNED_HPP_INCLUDED

#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_signed.hpp>
#include <boost/type_traits/is_unsigned.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_volatile.hpp>
#include <boost/static_assert.hpp>

namespace boost {

template <class T>
struct make_signed
{
private:
   BOOST_STATIC_ASSERT_MSG(( ::boost::is_integral<T>::value || ::boost::is_enum<T>::value), "The template argument to make_signed must be an integer or enum type.");
   BOOST_STATIC_ASSERT_MSG(!(::boost::is_same<typename remove_cv<T>::type, bool>::value), "The template argument to make_signed must not be the type bool.");

   typedef typename remove_cv<T>::type t_no_cv;
   typedef typename conditional<
      (::boost::is_signed<T>::value
      && ::boost::is_integral<T>::value
      && ! ::boost::is_same<t_no_cv, char>::value
      && ! ::boost::is_same<t_no_cv, wchar_t>::value
      && ! ::boost::is_same<t_no_cv, bool>::value),
      T,
      typename conditional<
         (::boost::is_integral<T>::value
         && ! ::boost::is_same<t_no_cv, char>::value
         && ! ::boost::is_same<t_no_cv, wchar_t>::value
         && ! ::boost::is_same<t_no_cv, bool>::value),
         typename conditional<
            is_same<t_no_cv, unsigned char>::value,
            signed char,
            typename conditional<
               is_same<t_no_cv, unsigned short>::value,
               signed short,
               typename conditional<
                  is_same<t_no_cv, unsigned int>::value,
                  int,
                  typename conditional<
                     is_same<t_no_cv, unsigned long>::value,
                     long,
#if defined(BOOST_HAS_LONG_LONG)
#ifdef BOOST_HAS_INT128
                     typename conditional<
                        sizeof(t_no_cv) == sizeof(boost::long_long_type),
                        boost::long_long_type,
                        boost::int128_type
                     >::type
#else
                     boost::long_long_type
#endif
#elif defined(BOOST_HAS_MS_INT64)
                     __int64
#else
                     long
#endif
                  >::type
               >::type
            >::type
         >::type,
         // Not a regular integer type:
         typename conditional<
            sizeof(t_no_cv) == sizeof(unsigned char),
            signed char,
            typename conditional<
               sizeof(t_no_cv) == sizeof(unsigned short),
               signed short,
               typename conditional<
                  sizeof(t_no_cv) == sizeof(unsigned int),
                  int,
                  typename conditional<
                     sizeof(t_no_cv) == sizeof(unsigned long),
                     long,
#if defined(BOOST_HAS_LONG_LONG)
#ifdef BOOST_HAS_INT128
                     typename conditional<
                        sizeof(t_no_cv) == sizeof(boost::long_long_type),
                        boost::long_long_type,
                        boost::int128_type
                     >::type
#else
                     boost::long_long_type
#endif
#elif defined(BOOST_HAS_MS_INT64)
                     __int64
#else
                     long
#endif
                  >::type
               >::type
            >::type
         >::type
      >::type
   >::type base_integer_type;

   // Add back any const qualifier:
   typedef typename conditional<
      is_const<T>::value,
      typename add_const<base_integer_type>::type,
      base_integer_type
   >::type const_base_integer_type;
public:
   // Add back any volatile qualifier:
   typedef typename conditional<
      is_volatile<T>::value,
      typename add_volatile<const_base_integer_type>::type,
      const_base_integer_type
   >::type type;
};

} // namespace boost

#endif // BOOST_TT_ADD_REFERENCE_HPP_INCLUDED


code:
// npfwht.c
// Basic implementation of the Fast Walsh-Hadamard Transforms
//
// (c) 2016 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
// ------------------------------------------------------------------------------
// This file is part of the qracodes project, a Forward Error Control
// encoding/decoding package based on Q-ary RA (repeat and accumulate) LDPC codes.
//
//    qracodes is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//    qracodes is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.

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

#include "npfwht.h"

#define WHBFY(dst,src,base,offs,dist) { dst[base+offs]=src[base+offs]+src[base+offs+dist]; dst[base+offs+dist]=src[base+offs]-src[base+offs+dist]; }

typedef void (*pnp_fwht)(float*,float*);

static void np_fwht2(float *dst, float *src);

static void np_fwht1(float *dst, float *src);
static void np_fwht2(float *dst, float *src);
static void np_fwht4(float *dst, float *src);
static void np_fwht8(float *dst, float *src);
static void np_fwht16(float *dst, float *src);
static void np_fwht32(float *dst, float *src);
static void np_fwht64(float *dst, float *src);

static pnp_fwht np_fwht_tab[7] = {
	np_fwht1,
	np_fwht2,
	np_fwht4,
	np_fwht8,
	np_fwht16,
	np_fwht32,
	np_fwht64
};

void np_fwht(int nlogdim, float *dst, float *src)
{
	np_fwht_tab[nlogdim](dst,src);
}

static void np_fwht1(float *dst, float *src)
{
	dst[0] = src[0];
}

static void np_fwht2(float *dst, float *src)
{
	float t[2];

	WHBFY(t,src,0,0,1);
	dst[0]= t[0];
	dst[1]= t[1];
}

static void np_fwht4(float *dst, float *src)
{
	float t[4];

	// group 1
	WHBFY(t,src,0,0,2); WHBFY(t,src,0,1,2);
	// group 2
	WHBFY(dst,t,0,0,1); WHBFY(dst,t,2,0,1);
};

static void np_fwht8(float *dst, float *src)
{
	float t[16];
	float *t1=t, *t2=t+8;

	// group 1
	WHBFY(t1,src,0,0,4); WHBFY(t1,src,0,1,4); WHBFY(t1,src,0,2,4); WHBFY(t1,src,0,3,4);
	// group 2
	WHBFY(t2,t1,0,0,2);  WHBFY(t2,t1,0,1,2);  WHBFY(t2,t1,4,0,2);	WHBFY(t2,t1,4,1,2);
	// group 3
	WHBFY(dst,t2,0,0,1); WHBFY(dst,t2,2,0,1); WHBFY(dst,t2,4,0,1); WHBFY(dst,t2,6,0,1);
};

static void np_fwht16(float *dst, float *src)
{
	float t[32];
	float *t1=t, *t2=t+16;

	// group 1
	WHBFY(t1,src,0,0,8); WHBFY(t1,src,0,1,8);  WHBFY(t1,src,0,2,8);  WHBFY(t1,src,0,3,8);
	WHBFY(t1,src,0,4,8); WHBFY(t1,src,0,5,8);  WHBFY(t1,src,0,6,8);  WHBFY(t1,src,0,7,8);
	// group 2
	WHBFY(t2,t1,0,0,4);  WHBFY(t2,t1,0,1,4);   WHBFY(t2,t1,0,2,4);	 WHBFY(t2,t1,0,3,4);
	WHBFY(t2,t1,8,0,4);  WHBFY(t2,t1,8,1,4);   WHBFY(t2,t1,8,2,4);   WHBFY(t2,t1,8,3,4);
	// group 3
	WHBFY(t1,t2,0,0,2);  WHBFY(t1,t2,0,1,2);   WHBFY(t1,t2,4,0,2);   WHBFY(t1,t2,4,1,2);
	WHBFY(t1,t2,8,0,2);  WHBFY(t1,t2,8,1,2);   WHBFY(t1,t2,12,0,2);  WHBFY(t1,t2,12,1,2);
	// group 4
	WHBFY(dst,t1,0,0,1); WHBFY(dst,t1,2,0,1);  WHBFY(dst,t1,4,0,1);  WHBFY(dst,t1,6,0,1);
	WHBFY(dst,t1,8,0,1); WHBFY(dst,t1,10,0,1); WHBFY(dst,t1,12,0,1); WHBFY(dst,t1,14,0,1);

}

static void np_fwht32(float *dst, float *src)
{
	float t[64];
	float *t1=t, *t2=t+32;

	// group 1
	WHBFY(t1,src,0,0,16);  WHBFY(t1,src,0,1,16);  WHBFY(t1,src,0,2,16);  WHBFY(t1,src,0,3,16);
	WHBFY(t1,src,0,4,16);  WHBFY(t1,src,0,5,16);  WHBFY(t1,src,0,6,16);  WHBFY(t1,src,0,7,16);
	WHBFY(t1,src,0,8,16);  WHBFY(t1,src,0,9,16);  WHBFY(t1,src,0,10,16); WHBFY(t1,src,0,11,16);
	WHBFY(t1,src,0,12,16); WHBFY(t1,src,0,13,16); WHBFY(t1,src,0,14,16); WHBFY(t1,src,0,15,16);

	// group 2
	WHBFY(t2,t1,0,0,8);  WHBFY(t2,t1,0,1,8);  WHBFY(t2,t1,0,2,8);  WHBFY(t2,t1,0,3,8);
	WHBFY(t2,t1,0,4,8);  WHBFY(t2,t1,0,5,8);  WHBFY(t2,t1,0,6,8);  WHBFY(t2,t1,0,7,8);
	WHBFY(t2,t1,16,0,8); WHBFY(t2,t1,16,1,8); WHBFY(t2,t1,16,2,8); WHBFY(t2,t1,16,3,8);
	WHBFY(t2,t1,16,4,8); WHBFY(t2,t1,16,5,8); WHBFY(t2,t1,16,6,8); WHBFY(t2,t1,16,7,8);

	// group 3
	WHBFY(t1,t2,0,0,4);  WHBFY(t1,t2,0,1,4);  WHBFY(t1,t2,0,2,4);  WHBFY(t1,t2,0,3,4);
	WHBFY(t1,t2,8,0,4);  WHBFY(t1,t2,8,1,4);  WHBFY(t1,t2,8,2,4);  WHBFY(t1,t2,8,3,4);
	WHBFY(t1,t2,16,0,4); WHBFY(t1,t2,16,1,4); WHBFY(t1,t2,16,2,4); WHBFY(t1,t2,16,3,4);
	WHBFY(t1,t2,24,0,4); WHBFY(t1,t2,24,1,4); WHBFY(t1,t2,24,2,4); WHBFY(t1,t2,24,3,4);

	// group 4
	WHBFY(t2,t1,0,0,2);  WHBFY(t2,t1,0,1,2);  WHBFY(t2,t1,4,0,2);  WHBFY(t2,t1,4,1,2);
	WHBFY(t2,t1,8,0,2);  WHBFY(t2,t1,8,1,2);  WHBFY(t2,t1,12,0,2); WHBFY(t2,t1,12,1,2);
	WHBFY(t2,t1,16,0,2); WHBFY(t2,t1,16,1,2); WHBFY(t2,t1,20,0,2); WHBFY(t2,t1,20,1,2);
	WHBFY(t2,t1,24,0,2); WHBFY(t2,t1,24,1,2); WHBFY(t2,t1,28,0,2); WHBFY(t2,t1,28,1,2);

	// group 5
	WHBFY(dst,t2,0,0,1);   WHBFY(dst,t2,2,0,1);  WHBFY(dst,t2,4,0,1);   WHBFY(dst,t2,6,0,1);
	WHBFY(dst,t2,8,0,1);   WHBFY(dst,t2,10,0,1); WHBFY(dst,t2,12,0,1);  WHBFY(dst,t2,14,0,1);
	WHBFY(dst,t2,16,0,1);  WHBFY(dst,t2,18,0,1); WHBFY(dst,t2,20,0,1);  WHBFY(dst,t2,22,0,1);
	WHBFY(dst,t2,24,0,1);  WHBFY(dst,t2,26,0,1); WHBFY(dst,t2,28,0,1);  WHBFY(dst,t2,30,0,1);

}

static void np_fwht64(float *dst, float *src)
{
	float t[128];
	float *t1=t, *t2=t+64;

	// group 1
	WHBFY(t1,src,0,0,32);  WHBFY(t1,src,0,1,32);  WHBFY(t1,src,0,2,32);  WHBFY(t1,src,0,3,32);
	WHBFY(t1,src,0,4,32);  WHBFY(t1,src,0,5,32);  WHBFY(t1,src,0,6,32);  WHBFY(t1,src,0,7,32);
	WHBFY(t1,src,0,8,32);  WHBFY(t1,src,0,9,32);  WHBFY(t1,src,0,10,32); WHBFY(t1,src,0,11,32);
	WHBFY(t1,src,0,12,32); WHBFY(t1,src,0,13,32); WHBFY(t1,src,0,14,32); WHBFY(t1,src,0,15,32);
	WHBFY(t1,src,0,16,32); WHBFY(t1,src,0,17,32); WHBFY(t1,src,0,18,32); WHBFY(t1,src,0,19,32);
	WHBFY(t1,src,0,20,32); WHBFY(t1,src,0,21,32); WHBFY(t1,src,0,22,32); WHBFY(t1,src,0,23,32);
	WHBFY(t1,src,0,24,32); WHBFY(t1,src,0,25,32); WHBFY(t1,src,0,26,32); WHBFY(t1,src,0,27,32);
	WHBFY(t1,src,0,28,32); WHBFY(t1,src,0,29,32); WHBFY(t1,src,0,30,32); WHBFY(t1,src,0,31,32);

	// group 2
	WHBFY(t2,t1,0,0,16);   WHBFY(t2,t1,0,1,16);  WHBFY(t2,t1,0,2,16);   WHBFY(t2,t1,0,3,16);
	WHBFY(t2,t1,0,4,16);   WHBFY(t2,t1,0,5,16);  WHBFY(t2,t1,0,6,16);   WHBFY(t2,t1,0,7,16);
	WHBFY(t2,t1,0,8,16);   WHBFY(t2,t1,0,9,16);  WHBFY(t2,t1,0,10,16);  WHBFY(t2,t1,0,11,16);
	WHBFY(t2,t1,0,12,16);  WHBFY(t2,t1,0,13,16); WHBFY(t2,t1,0,14,16);  WHBFY(t2,t1,0,15,16);

	WHBFY(t2,t1,32,0,16);  WHBFY(t2,t1,32,1,16);  WHBFY(t2,t1,32,2,16);  WHBFY(t2,t1,32,3,16);
	WHBFY(t2,t1,32,4,16);  WHBFY(t2,t1,32,5,16);  WHBFY(t2,t1,32,6,16);  WHBFY(t2,t1,32,7,16);
	WHBFY(t2,t1,32,8,16);  WHBFY(t2,t1,32,9,16);  WHBFY(t2,t1,32,10,16); WHBFY(t2,t1,32,11,16);
	WHBFY(t2,t1,32,12,16); WHBFY(t2,t1,32,13,16); WHBFY(t2,t1,32,14,16); WHBFY(t2,t1,32,15,16);

	// group 3
	WHBFY(t1,t2,0,0,8);    WHBFY(t1,t2,0,1,8); 	 WHBFY(t1,t2,0,2,8);    WHBFY(t1,t2,0,3,8);
	WHBFY(t1,t2,0,4,8);    WHBFY(t1,t2,0,5,8); 	 WHBFY(t1,t2,0,6,8);    WHBFY(t1,t2,0,7,8);
	WHBFY(t1,t2,16,0,8);   WHBFY(t1,t2,16,1,8);  WHBFY(t1,t2,16,2,8);   WHBFY(t1,t2,16,3,8);
	WHBFY(t1,t2,16,4,8);   WHBFY(t1,t2,16,5,8);  WHBFY(t1,t2,16,6,8);   WHBFY(t1,t2,16,7,8);
	WHBFY(t1,t2,32,0,8);   WHBFY(t1,t2,32,1,8);  WHBFY(t1,t2,32,2,8);   WHBFY(t1,t2,32,3,8);
	WHBFY(t1,t2,32,4,8);   WHBFY(t1,t2,32,5,8);  WHBFY(t1,t2,32,6,8);   WHBFY(t1,t2,32,7,8);
	WHBFY(t1,t2,48,0,8);   WHBFY(t1,t2,48,1,8);  WHBFY(t1,t2,48,2,8);   WHBFY(t1,t2,48,3,8);
	WHBFY(t1,t2,48,4,8);   WHBFY(t1,t2,48,5,8);  WHBFY(t1,t2,48,6,8);   WHBFY(t1,t2,48,7,8);

	// group 4
	WHBFY(t2,t1,0,0,4);   WHBFY(t2,t1,0,1,4); 	WHBFY(t2,t1,0,2,4);  WHBFY(t2,t1,0,3,4);
	WHBFY(t2,t1,8,0,4);   WHBFY(t2,t1,8,1,4); 	WHBFY(t2,t1,8,2,4);  WHBFY(t2,t1,8,3,4);
	WHBFY(t2,t1,16,0,4);  WHBFY(t2,t1,16,1,4); 	WHBFY(t2,t1,16,2,4); WHBFY(t2,t1,16,3,4);
	WHBFY(t2,t1,24,0,4);  WHBFY(t2,t1,24,1,4); 	WHBFY(t2,t1,24,2,4); WHBFY(t2,t1,24,3,4);
	WHBFY(t2,t1,32,0,4);  WHBFY(t2,t1,32,1,4); 	WHBFY(t2,t1,32,2,4); WHBFY(t2,t1,32,3,4);
	WHBFY(t2,t1,40,0,4);  WHBFY(t2,t1,40,1,4); 	WHBFY(t2,t1,40,2,4); WHBFY(t2,t1,40,3,4);
	WHBFY(t2,t1,48,0,4);  WHBFY(t2,t1,48,1,4); 	WHBFY(t2,t1,48,2,4); WHBFY(t2,t1,48,3,4);
	WHBFY(t2,t1,56,0,4);  WHBFY(t2,t1,56,1,4); 	WHBFY(t2,t1,56,2,4); WHBFY(t2,t1,56,3,4);

	// group 5
	WHBFY(t1,t2,0,0,2);  WHBFY(t1,t2,0,1,2);  WHBFY(t1,t2,4,0,2);  WHBFY(t1,t2,4,1,2);
	WHBFY(t1,t2,8,0,2);  WHBFY(t1,t2,8,1,2);  WHBFY(t1,t2,12,0,2); WHBFY(t1,t2,12,1,2);
	WHBFY(t1,t2,16,0,2); WHBFY(t1,t2,16,1,2); WHBFY(t1,t2,20,0,2); WHBFY(t1,t2,20,1,2);
	WHBFY(t1,t2,24,0,2); WHBFY(t1,t2,24,1,2); WHBFY(t1,t2,28,0,2); WHBFY(t1,t2,28,1,2);
	WHBFY(t1,t2,32,0,2); WHBFY(t1,t2,32,1,2); WHBFY(t1,t2,36,0,2); WHBFY(t1,t2,36,1,2);
	WHBFY(t1,t2,40,0,2); WHBFY(t1,t2,40,1,2); WHBFY(t1,t2,44,0,2); WHBFY(t1,t2,44,1,2);
	WHBFY(t1,t2,48,0,2); WHBFY(t1,t2,48,1,2); WHBFY(t1,t2,52,0,2); WHBFY(t1,t2,52,1,2);
	WHBFY(t1,t2,56,0,2); WHBFY(t1,t2,56,1,2); WHBFY(t1,t2,60,0,2); WHBFY(t1,t2,60,1,2);

	// group 6
	WHBFY(dst,t1,0,0,1);   WHBFY(dst,t1,2,0,1);  WHBFY(dst,t1,4,0,1);  WHBFY(dst,t1,6,0,1);
	WHBFY(dst,t1,8,0,1);   WHBFY(dst,t1,10,0,1); WHBFY(dst,t1,12,0,1); WHBFY(dst,t1,14,0,1);
	WHBFY(dst,t1,16,0,1);  WHBFY(dst,t1,18,0,1); WHBFY(dst,t1,20,0,1); WHBFY(dst,t1,22,0,1);
	WHBFY(dst,t1,24,0,1);  WHBFY(dst,t1,26,0,1); WHBFY(dst,t1,28,0,1); WHBFY(dst,t1,30,0,1);
	WHBFY(dst,t1,32,0,1);  WHBFY(dst,t1,34,0,1); WHBFY(dst,t1,36,0,1); WHBFY(dst,t1,38,0,1);
	WHBFY(dst,t1,40,0,1);  WHBFY(dst,t1,42,0,1); WHBFY(dst,t1,44,0,1); WHBFY(dst,t1,46,0,1);
	WHBFY(dst,t1,48,0,1);  WHBFY(dst,t1,50,0,1); WHBFY(dst,t1,52,0,1); WHBFY(dst,t1,54,0,1);
	WHBFY(dst,t1,56,0,1);  WHBFY(dst,t1,58,0,1); WHBFY(dst,t1,60,0,1); WHBFY(dst,t1,62,0,1);
}


code:
#include "CandidateKeyFilter.hpp"

#include <QModelIndex>
#include <QAbstractItemModel>

#include "pimpl_impl.hpp"

class CandidateKeyFilter::impl final
{
public:
  explicit impl (int referenced_key_column
                 , int referenced_key_role
                 , QAbstractItemModel const * referencing_model
                 , int referencing_key_column
                 , int referencing_key_role)
    : referencing_ {referencing_model}
    , referencing_key_column_ {referencing_key_column}
    , referencing_key_role_ {referencing_key_role}
    , referenced_key_column_ {referenced_key_column}
    , referenced_key_role_ {referenced_key_role}
  {
  }

  QAbstractItemModel const * referencing_;
  int referencing_key_column_;
  int referencing_key_role_;
  int referenced_key_column_;
  int referenced_key_role_;
  QModelIndex active_key_;
};

CandidateKeyFilter::CandidateKeyFilter (QAbstractItemModel * referenced_model
                                        , int referenced_key_column
                                        , QObject * parent
                                        , int referenced_key_role)
  : QSortFilterProxyModel {parent}
  , m_ {referenced_key_column, referenced_key_role, nullptr, 0, Qt::EditRole}
{
  setSourceModel (referenced_model);
}

CandidateKeyFilter::CandidateKeyFilter (QAbstractItemModel * referenced_model
                                        , QAbstractItemModel const * referencing_model
                                        , int referenced_key_column
                                        , int referencing_key_column
                                        , QObject * parent
                                        , int referenced_key_role
                                        , int referencing_key_role)
  : QSortFilterProxyModel {parent}
  , m_ {referenced_key_column, referenced_key_role, referencing_model, referencing_key_column, referencing_key_role}
{
  setSourceModel (referenced_model);
}

CandidateKeyFilter::~CandidateKeyFilter ()
{
}

void CandidateKeyFilter::set_active_key (QModelIndex const& index)
{
  if (m_->referencing_)
    {
      if (index.isValid () )
        {
          Q_ASSERT (index.column () == m_->referencing_key_column_);
          m_->active_key_ = index;
        }
      invalidateFilter ();
    }
}

bool CandidateKeyFilter::filterAcceptsRow (int candidate_row, QModelIndex const& candidate_parent) const
{
  if (!m_->referencing_)            // many to many passes all
    {
      return true;
    }

  auto candidate_key = sourceModel ()->index (candidate_row, m_->referenced_key_column_, candidate_parent).data (m_->referenced_key_role_);

  // Include the current key.
  if (m_->active_key_.isValid () && candidate_key == m_->active_key_.data (m_->referencing_key_role_))
    {
      return true;
    }

  // Filter out any candidates already in the referencing key rows.
  return m_->referencing_->match (m_->referencing_->index (0, m_->referencing_key_column_), m_->referencing_key_role_, candidate_key, 1, Qt::MatchExactly).isEmpty ();
}


code:
//---------------------------------------------------------------------------//
// Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
//
// 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
//
// See http://boostorg.github.com/compute for more information.
//---------------------------------------------------------------------------//

#ifndef BOOST_COMPUTE_CONTAINER_DETAIL_SCALAR_HPP
#define BOOST_COMPUTE_CONTAINER_DETAIL_SCALAR_HPP

#include <boost/compute/buffer.hpp>
#include <boost/compute/detail/read_write_single_value.hpp>

namespace boost {
namespace compute {
namespace detail {

// scalar<T> provides a trivial "container" that stores a
// single value in a memory buffer on a compute device
template<class T>
class scalar
{
public:
    typedef T value_type;

    scalar(const context &context)
        : m_buffer(context, sizeof(T))
    {
    }

    ~scalar()
    {
    }

    T read(command_queue &queue) const
    {
        return read_single_value<T>(m_buffer, 0, queue);
    }

    void write(const T &value, command_queue &queue)
    {
        write_single_value<T>(value, m_buffer, 0, queue);
    }

    const buffer& get_buffer() const
    {
        return m_buffer;
    }

private:
    buffer m_buffer;
};

} // end detail namespace
} // end compute namespace
} // end boost namespace

#endif // BOOST_COMPUTE_CONTAINER_DETAIL_SCALAR_HPP


code:
subroutine packtext2(msg,n1,ng)

  character*8 msg
  real*8 dn
  character*41 c
  data c/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +./?'/

  dn=0.
  do i=1,8
     do j=1,41
        if(msg(i:i).eq.c(j:j)) go to 10
     enddo
     j=37
10   j=j-1                                !Codes should start at zero
     dn=41.d0*dn + j
  enddo

  ng=mod(dn,32768.d0)
  n1=(dn-ng)/32768.d0

  return
end subroutine packtext2


code:
// Boost.Assign library
//
//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
//  distribution is subject to 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)
//
// For more information, see http://www.boost.org/libs/assign/
//

#ifndef BOOST_ASSIGN_STD_QUEUE_HPP
#define BOOST_ASSIGN_STD_QUEUE_HPP

#if defined(_MSC_VER)
# pragma once
#endif

#include <boost/assign/list_inserter.hpp>
#include <boost/config.hpp>
#include <queue>

namespace boost
{
namespace assign
{

    template< class V, class C, class V2 >
    inline list_inserter< assign_detail::call_push< std::queue<V,C> >, V >
    operator+=( std::queue<V,C>& c, V2 v )
    {
        return push( c )( v );
    }

    template< class V, class C, class V2 >
    inline list_inserter< assign_detail::call_push< std::priority_queue<V,C> >, V >
    operator+=( std::priority_queue<V,C>& c, V2 v )
    {
        return push( c )( v );
    }

}
}

#endif


code:
/*=============================================================================
    Copyright (c) 2001-2011 Joel de Guzman

    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)

    This is an auto-generated file. Do not edit!
==============================================================================*/

#if FUSION_MAX_LIST_SIZE <= 10
#include <boost/fusion/container/list/detail/cpp03/preprocessed/list10.hpp>
#elif FUSION_MAX_LIST_SIZE <= 20
#include <boost/fusion/container/list/detail/cpp03/preprocessed/list20.hpp>
#elif FUSION_MAX_LIST_SIZE <= 30
#include <boost/fusion/container/list/detail/cpp03/preprocessed/list30.hpp>
#elif FUSION_MAX_LIST_SIZE <= 40
#include <boost/fusion/container/list/detail/cpp03/preprocessed/list40.hpp>
#elif FUSION_MAX_LIST_SIZE <= 50
#include <boost/fusion/container/list/detail/cpp03/preprocessed/list50.hpp>
#else
#error "FUSION_MAX_LIST_SIZE out of bounds for preprocessed headers"
#endif


code:
//
// Copyright (c) Antony Polukhin, 2013-2014.
//
//
// 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)
//

#ifndef BOOST_TYPE_INDEX_STL_REGISTER_CLASS_HPP
#define BOOST_TYPE_INDEX_STL_REGISTER_CLASS_HPP

/// \file stl_register_class.hpp
/// \brief Contains BOOST_TYPE_INDEX_REGISTER_CLASS macro implementation that uses boost::typeindex::stl_type_index.
/// Not intended for inclusion from user's code.

#include <boost/type_index/stl_type_index.hpp>

#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif

namespace boost { namespace typeindex { namespace detail {

template <class T>
inline const stl_type_index::type_info_t& stl_construct_typeid_ref(const T*) BOOST_NOEXCEPT {
    return typeid(T);
}

}}} // namespace boost::typeindex::detail

/// @cond
#define BOOST_TYPE_INDEX_REGISTER_CLASS                                                                                \
    virtual const boost::typeindex::stl_type_index::type_info_t& boost_type_index_type_id_runtime_() const BOOST_NOEXCEPT { \
        return boost::typeindex::detail::stl_construct_typeid_ref(this);                                                    \
    }                                                                                \
/**/
/// @endcond

#endif // BOOST_TYPE_INDEX_STL_REGISTER_CLASS_HPP


code:
#include "TransceiverFactory.hpp"

#include <QMetaType>

#include "HamlibTransceiver.hpp"
#include "DXLabSuiteCommanderTransceiver.hpp"
#include "HRDTransceiver.hpp"
#include "EmulateSplitTransceiver.hpp"

#if defined (WIN32)
#include "OmniRigTransceiver.hpp"
#endif

#include "moc_TransceiverFactory.cpp"

// we use the hamlib "Hamlib Dummy" transceiver for non-CAT radios,
// this allows us to still use the hamlib PTT control features for a
// unified PTT control solution

char const * const TransceiverFactory::basic_transceiver_name_ = "None";

namespace
{
  enum				// supported non-hamlib radio interfaces
    {
      NonHamlibBaseId = 9899
      , CommanderId
      , HRDId
      , OmniRigOneId
      , OmniRigTwoId
    };
}

TransceiverFactory::TransceiverFactory ()
{
  HamlibTransceiver::register_transceivers (&transceivers_);
  DXLabSuiteCommanderTransceiver::register_transceivers (&transceivers_, CommanderId);
  HRDTransceiver::register_transceivers (&transceivers_, HRDId);

#if defined (WIN32)
  // OmniRig is ActiveX/COM server so only on Windows
  OmniRigTransceiver::register_transceivers (&transceivers_, OmniRigOneId, OmniRigTwoId);
#endif
}

TransceiverFactory::~TransceiverFactory ()
{
  HamlibTransceiver::unregister_transceivers ();
}

auto TransceiverFactory::supported_transceivers () const -> Transceivers const&
{
  return transceivers_;
}

auto TransceiverFactory::CAT_port_type (QString const& name) const -> Capabilities::PortType
{
  return supported_transceivers ()[name].port_type_;
}

bool TransceiverFactory::has_CAT_PTT (QString const& name) const
{
  return
    supported_transceivers ()[name].has_CAT_PTT_
    || supported_transceivers ()[name].model_number_ > NonHamlibBaseId;
}

bool TransceiverFactory::has_CAT_PTT_mic_data (QString const& name) const
{
  return supported_transceivers ()[name].has_CAT_PTT_mic_data_;
}

bool TransceiverFactory::has_CAT_indirect_serial_PTT (QString const& name) const
{
  return supported_transceivers ()[name].has_CAT_indirect_serial_PTT_;
}

bool TransceiverFactory::has_asynchronous_CAT (QString const& name) const
{
  return supported_transceivers ()[name].asynchronous_;
}

std::unique_ptr<Transceiver> TransceiverFactory::create (ParameterPack const& params, QThread * target_thread)
{
  std::unique_ptr<Transceiver> result;
  switch (supported_transceivers ()[params.rig_name].model_number_)
    {
    case CommanderId:
      {
        std::unique_ptr<TransceiverBase> basic_transceiver;
        if (PTT_method_CAT != params.ptt_type)
          {
            // we start with a dummy HamlibTransceiver object instance that can support direct PTT
            basic_transceiver.reset (new HamlibTransceiver {params.ptt_type, params.ptt_port});
            if (target_thread)
              {
                basic_transceiver.get ()->moveToThread (target_thread);
              }
          }

        // wrap the basic Transceiver object instance with a decorator object that talks to DX Lab Suite Commander
        result.reset (new DXLabSuiteCommanderTransceiver {std::move (basic_transceiver), params.network_port, PTT_method_CAT == params.ptt_type, params.poll_interval});
        if (target_thread)
          {
            result->moveToThread (target_thread);
          }
      }
      break;

    case HRDId:
      {
        std::unique_ptr<TransceiverBase> basic_transceiver;
        if (PTT_method_CAT != params.ptt_type)
          {
            // we start with a dummy HamlibTransceiver object instance that can support direct PTT
            basic_transceiver.reset (new HamlibTransceiver {params.ptt_type, params.ptt_port});
            if (target_thread)
              {
                basic_transceiver.get ()->moveToThread (target_thread);
              }
          }

        // wrap the basic Transceiver object instance with a decorator object that talks to ham Radio Deluxe
        result.reset (new HRDTransceiver {std::move (basic_transceiver), params.network_port, PTT_method_CAT == params.ptt_type, params.audio_source, params.poll_interval});
        if (target_thread)
          {
            result->moveToThread (target_thread);
          }
      }
      break;

#if defined (WIN32)
    case OmniRigOneId:
      {
        std::unique_ptr<TransceiverBase> basic_transceiver;
        if (PTT_method_CAT != params.ptt_type && "CAT" != params.ptt_port)
          {
            // we start with a dummy HamlibTransceiver object instance that can support direct PTT
            basic_transceiver.reset (new HamlibTransceiver {params.ptt_type, params.ptt_port});
            if (target_thread)
              {
                basic_transceiver.get ()->moveToThread (target_thread);
              }
          }

        // wrap the basic Transceiver object instance with a decorator object that talks to OmniRig rig one
        result.reset (new OmniRigTransceiver {std::move (basic_transceiver), OmniRigTransceiver::One, params.ptt_type, params.ptt_port});
        if (target_thread)
          {
            result->moveToThread (target_thread);
          }
      }
      break;

    case OmniRigTwoId:
      {
        std::unique_ptr<TransceiverBase> basic_transceiver;
        if (PTT_method_CAT != params.ptt_type && "CAT" != params.ptt_port)
          {
            // we start with a dummy HamlibTransceiver object instance that can support direct PTT
            basic_transceiver.reset (new HamlibTransceiver {params.ptt_type, params.ptt_port});
            if (target_thread)
              {
                basic_transceiver.get ()->moveToThread (target_thread);
              }
          }

        // wrap the basic Transceiver object instance with a decorator object that talks to OmniRig rig two
        result.reset (new OmniRigTransceiver {std::move (basic_transceiver), OmniRigTransceiver::Two, params.ptt_type, params.ptt_port});
        if (target_thread)
          {
            result->moveToThread (target_thread);
          }
      }
      break;
#endif

    default:
      result.reset (new HamlibTransceiver {supported_transceivers ()[params.rig_name].model_number_, params});
      if (target_thread)
        {
          result->moveToThread (target_thread);
        }
      break;
    }

  if (split_mode_emulate == params.split_mode)
    {
      // wrap the Transceiver object instance with a decorator that emulates split mode
      result.reset (new EmulateSplitTransceiver {std::move (result)});
      if (target_thread)
        {
          result->moveToThread (target_thread);
        }
    }

  return result;
}

#if !defined (QT_NO_DEBUG_STREAM)
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, DataBits);
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, StopBits);
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, Handshake);
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, PTTMethod);
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, TXAudioSource);
ENUM_QDEBUG_OPS_IMPL (TransceiverFactory, SplitMode);
#endif

ENUM_QDATASTREAM_OPS_IMPL (TransceiverFactory, DataBits);
ENUM_QDATASTREAM_OPS_IMPL (TransceiverFactory, StopBits);
ENUM_QDATASTREAM_OPS_IMPL (TransceiverFactory, Handshake);
ENUM_QDATASTREAM_OPS_IMPL (TransceiverFactory, PTTMethod);
ENUM_QDATASTREAM_OPS_IMPL (TransceiverFactory, TXAudioSource);
ENUM_QDATASTREAM_OPS_IMPL (TransceiverFactory, SplitMode);

ENUM_CONVERSION_OPS_IMPL (TransceiverFactory, DataBits);
ENUM_CONVERSION_OPS_IMPL (TransceiverFactory, StopBits);
ENUM_CONVERSION_OPS_IMPL (TransceiverFactory, Handshake);
ENUM_CONVERSION_OPS_IMPL (TransceiverFactory, PTTMethod);
ENUM_CONVERSION_OPS_IMPL (TransceiverFactory, TXAudioSource);
ENUM_CONVERSION_OPS_IMPL (TransceiverFactory, SplitMode);