Initial Commit
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
FC = gfortran
|
||||
CC = gcc
|
||||
CFLAGS = -O2 -Wall -I. -D_WIN32
|
||||
|
||||
# Default rules
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -c $<
|
||||
%.o: %.f
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.f90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
|
||||
all: qra64.exe
|
||||
|
||||
OBJS1 = main.o qra64.o
|
||||
qra64.exe: $(OBJS1)
|
||||
${CC} -o qra64.exe $(OBJS1) ../qracodes/libqra64.a -lm
|
||||
|
||||
OBJS2 = qra64sim.o options.o wavhdr.o
|
||||
qra64sim.exe: $(OBJS2)
|
||||
${FC} -o qra64sim.exe $(OBJS2) ../qracodes/libqra64.a -lm
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
clean:
|
||||
$(RM) *.o qra64.exe qra64sim.exe
|
||||
@@ -0,0 +1,48 @@
|
||||
|
||||
#ifndef BOOST_MPL_FOLD_HPP_INCLUDED
|
||||
#define BOOST_MPL_FOLD_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2001-2004
|
||||
// Copyright David Abrahams 2001-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)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#include <boost/mpl/begin_end.hpp>
|
||||
#include <boost/mpl/O1_size.hpp>
|
||||
#include <boost/mpl/aux_/fold_impl.hpp>
|
||||
#include <boost/mpl/aux_/na_spec.hpp>
|
||||
#include <boost/mpl/aux_/lambda_support.hpp>
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
template<
|
||||
typename BOOST_MPL_AUX_NA_PARAM(Sequence)
|
||||
, typename BOOST_MPL_AUX_NA_PARAM(State)
|
||||
, typename BOOST_MPL_AUX_NA_PARAM(ForwardOp)
|
||||
>
|
||||
struct fold
|
||||
{
|
||||
typedef typename aux::fold_impl<
|
||||
::boost::mpl::O1_size<Sequence>::value
|
||||
, typename begin<Sequence>::type
|
||||
, typename end<Sequence>::type
|
||||
, State
|
||||
, ForwardOp
|
||||
>::state type;
|
||||
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(3,fold,(Sequence,State,ForwardOp))
|
||||
};
|
||||
|
||||
BOOST_MPL_AUX_NA_SPEC(3, fold)
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_MPL_FOLD_HPP_INCLUDED
|
||||
@@ -0,0 +1,23 @@
|
||||
# /* **************************************************************************
|
||||
# * *
|
||||
# * (C) Copyright Paul Mensonides 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)
|
||||
# * *
|
||||
# ************************************************************************** */
|
||||
#
|
||||
# /* See http://www.boost.org for most recent version. */
|
||||
#
|
||||
# ifndef BOOST_PREPROCESSOR_PUNCTUATION_PAREN_HPP
|
||||
# define BOOST_PREPROCESSOR_PUNCTUATION_PAREN_HPP
|
||||
#
|
||||
# /* BOOST_PP_LPAREN */
|
||||
#
|
||||
# define BOOST_PP_LPAREN() (
|
||||
#
|
||||
# /* BOOST_PP_RPAREN */
|
||||
#
|
||||
# define BOOST_PP_RPAREN() )
|
||||
#
|
||||
# endif
|
||||
@@ -0,0 +1,365 @@
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Copyright 2011 John Maddock. 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_
|
||||
|
||||
#ifndef BOOST_MATH_RATIONAL_ADAPTER_HPP
|
||||
#define BOOST_MATH_RATIONAL_ADAPTER_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
#include <boost/multiprecision/number.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4512 4127)
|
||||
#endif
|
||||
#include <boost/rational.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
namespace multiprecision{
|
||||
namespace backends{
|
||||
|
||||
template <class IntBackend>
|
||||
struct rational_adaptor
|
||||
{
|
||||
typedef number<IntBackend> integer_type;
|
||||
typedef boost::rational<integer_type> rational_type;
|
||||
|
||||
typedef typename IntBackend::signed_types signed_types;
|
||||
typedef typename IntBackend::unsigned_types unsigned_types;
|
||||
typedef typename IntBackend::float_types float_types;
|
||||
|
||||
rational_adaptor() BOOST_MP_NOEXCEPT_IF(noexcept(rational_type())) {}
|
||||
rational_adaptor(const rational_adaptor& o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<rational_type&>() = std::declval<const rational_type&>()))
|
||||
{
|
||||
m_value = o.m_value;
|
||||
}
|
||||
rational_adaptor(const IntBackend& o) BOOST_MP_NOEXCEPT_IF(noexcept(rational_type(std::declval<const IntBackend&>()))) : m_value(o) {}
|
||||
|
||||
template <class U>
|
||||
rational_adaptor(const U& u, typename enable_if_c<is_convertible<U, IntBackend>::value>::type* = 0)
|
||||
: m_value(static_cast<integer_type>(u)){}
|
||||
template <class U>
|
||||
explicit rational_adaptor(const U& u,
|
||||
typename enable_if_c<
|
||||
boost::multiprecision::detail::is_explicitly_convertible<U, IntBackend>::value && !is_convertible<U, IntBackend>::value
|
||||
>::type* = 0)
|
||||
: m_value(IntBackend(u)){}
|
||||
template <class U>
|
||||
typename enable_if_c<(boost::multiprecision::detail::is_explicitly_convertible<U, IntBackend>::value && !is_arithmetic<U>::value), rational_adaptor&>::type operator = (const U& u)
|
||||
{
|
||||
m_value = IntBackend(u);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
rational_adaptor(rational_adaptor&& o) BOOST_MP_NOEXCEPT_IF(noexcept(rational_type(std::declval<rational_type>()))) : m_value(static_cast<rational_type&&>(o.m_value)) {}
|
||||
rational_adaptor(IntBackend&& o) BOOST_MP_NOEXCEPT_IF(noexcept(rational_type(std::declval<IntBackend>()))) : m_value(static_cast<IntBackend&&>(o)) {}
|
||||
rational_adaptor& operator = (rational_adaptor&& o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<rational_type&>() = std::declval<rational_type>()))
|
||||
{
|
||||
m_value = static_cast<rational_type&&>(o.m_value);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
rational_adaptor& operator = (const rational_adaptor& o)
|
||||
{
|
||||
m_value = o.m_value;
|
||||
return *this;
|
||||
}
|
||||
rational_adaptor& operator = (const IntBackend& o)
|
||||
{
|
||||
m_value = o;
|
||||
return *this;
|
||||
}
|
||||
template <class Int>
|
||||
typename enable_if<is_integral<Int>, rational_adaptor&>::type operator = (Int i)
|
||||
{
|
||||
m_value = i;
|
||||
return *this;
|
||||
}
|
||||
template <class Float>
|
||||
typename enable_if<is_floating_point<Float>, rational_adaptor&>::type operator = (Float i)
|
||||
{
|
||||
int e;
|
||||
Float f = std::frexp(i, &e);
|
||||
f = std::ldexp(f, std::numeric_limits<Float>::digits);
|
||||
e -= std::numeric_limits<Float>::digits;
|
||||
integer_type num(f);
|
||||
integer_type denom(1u);
|
||||
if(e > 0)
|
||||
{
|
||||
num <<= e;
|
||||
}
|
||||
else if(e < 0)
|
||||
{
|
||||
denom <<= -e;
|
||||
}
|
||||
m_value.assign(num, denom);
|
||||
return *this;
|
||||
}
|
||||
rational_adaptor& operator = (const char* s)
|
||||
{
|
||||
std::string s1;
|
||||
multiprecision::number<IntBackend> v1, v2;
|
||||
char c;
|
||||
bool have_hex = false;
|
||||
const char* p = s; // saved for later
|
||||
|
||||
while((0 != (c = *s)) && (c == 'x' || c == 'X' || c == '-' || c == '+' || (c >= '0' && c <= '9') || (have_hex && (c >= 'a' && c <= 'f')) || (have_hex && (c >= 'A' && c <= 'F'))))
|
||||
{
|
||||
if(c == 'x' || c == 'X')
|
||||
have_hex = true;
|
||||
s1.append(1, c);
|
||||
++s;
|
||||
}
|
||||
v1.assign(s1);
|
||||
s1.erase();
|
||||
if(c == '/')
|
||||
{
|
||||
++s;
|
||||
while((0 != (c = *s)) && (c == 'x' || c == 'X' || c == '-' || c == '+' || (c >= '0' && c <= '9') || (have_hex && (c >= 'a' && c <= 'f')) || (have_hex && (c >= 'A' && c <= 'F'))))
|
||||
{
|
||||
if(c == 'x' || c == 'X')
|
||||
have_hex = true;
|
||||
s1.append(1, c);
|
||||
++s;
|
||||
}
|
||||
v2.assign(s1);
|
||||
}
|
||||
else
|
||||
v2 = 1;
|
||||
if(*s)
|
||||
{
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Could not parse the string \"") + p + std::string("\" as a valid rational number.")));
|
||||
}
|
||||
data().assign(v1, v2);
|
||||
return *this;
|
||||
}
|
||||
void swap(rational_adaptor& o)
|
||||
{
|
||||
std::swap(m_value, o.m_value);
|
||||
}
|
||||
std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
|
||||
{
|
||||
//
|
||||
// We format the string ourselves so we can match what GMP's mpq type does:
|
||||
//
|
||||
std::string result = data().numerator().str(digits, f);
|
||||
if(data().denominator() != 1)
|
||||
{
|
||||
result.append(1, '/');
|
||||
result.append(data().denominator().str(digits, f));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
void negate()
|
||||
{
|
||||
m_value = -m_value;
|
||||
}
|
||||
int compare(const rational_adaptor& o)const
|
||||
{
|
||||
return m_value > o.m_value ? 1 : (m_value < o.m_value ? -1 : 0);
|
||||
}
|
||||
template <class Arithmatic>
|
||||
typename enable_if_c<is_arithmetic<Arithmatic>::value && !is_floating_point<Arithmatic>::value, int>::type compare(Arithmatic i)const
|
||||
{
|
||||
return m_value > i ? 1 : (m_value < i ? -1 : 0);
|
||||
}
|
||||
template <class Arithmatic>
|
||||
typename enable_if_c<is_floating_point<Arithmatic>::value, int>::type compare(Arithmatic i)const
|
||||
{
|
||||
rational_adaptor r;
|
||||
r = i;
|
||||
return this->compare(r);
|
||||
}
|
||||
rational_type& data() { return m_value; }
|
||||
const rational_type& data()const { return m_value; }
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const mpl::true_&)
|
||||
{
|
||||
// Saving
|
||||
integer_type n(m_value.numerator()), d(m_value.denominator());
|
||||
ar & n;
|
||||
ar & d;
|
||||
}
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const mpl::false_&)
|
||||
{
|
||||
// Loading
|
||||
integer_type n, d;
|
||||
ar & n;
|
||||
ar & d;
|
||||
m_value.assign(n, d);
|
||||
}
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int /*version*/)
|
||||
{
|
||||
typedef typename Archive::is_saving tag;
|
||||
serialize(ar, tag());
|
||||
}
|
||||
private:
|
||||
rational_type m_value;
|
||||
};
|
||||
|
||||
template <class IntBackend>
|
||||
inline void eval_add(rational_adaptor<IntBackend>& result, const rational_adaptor<IntBackend>& o)
|
||||
{
|
||||
result.data() += o.data();
|
||||
}
|
||||
template <class IntBackend>
|
||||
inline void eval_subtract(rational_adaptor<IntBackend>& result, const rational_adaptor<IntBackend>& o)
|
||||
{
|
||||
result.data() -= o.data();
|
||||
}
|
||||
template <class IntBackend>
|
||||
inline void eval_multiply(rational_adaptor<IntBackend>& result, const rational_adaptor<IntBackend>& o)
|
||||
{
|
||||
result.data() *= o.data();
|
||||
}
|
||||
template <class IntBackend>
|
||||
inline void eval_divide(rational_adaptor<IntBackend>& result, const rational_adaptor<IntBackend>& o)
|
||||
{
|
||||
using default_ops::eval_is_zero;
|
||||
if(eval_is_zero(o))
|
||||
{
|
||||
BOOST_THROW_EXCEPTION(std::overflow_error("Divide by zero."));
|
||||
}
|
||||
result.data() /= o.data();
|
||||
}
|
||||
|
||||
template <class R, class IntBackend>
|
||||
inline typename enable_if_c<number_category<R>::value == number_kind_floating_point>::type eval_convert_to(R* result, const rational_adaptor<IntBackend>& backend)
|
||||
{
|
||||
//
|
||||
// The generic conversion is as good as anything we can write here:
|
||||
//
|
||||
::boost::multiprecision::detail::generic_convert_rational_to_float(*result, backend);
|
||||
}
|
||||
|
||||
template <class R, class IntBackend>
|
||||
inline typename enable_if_c<(number_category<R>::value != number_kind_integer) && (number_category<R>::value != number_kind_floating_point)>::type eval_convert_to(R* result, const rational_adaptor<IntBackend>& backend)
|
||||
{
|
||||
typedef typename component_type<number<rational_adaptor<IntBackend> > >::type comp_t;
|
||||
comp_t num(backend.data().numerator());
|
||||
comp_t denom(backend.data().denominator());
|
||||
*result = num.template convert_to<R>();
|
||||
*result /= denom.template convert_to<R>();
|
||||
}
|
||||
|
||||
template <class R, class IntBackend>
|
||||
inline typename enable_if_c<number_category<R>::value == number_kind_integer>::type eval_convert_to(R* result, const rational_adaptor<IntBackend>& backend)
|
||||
{
|
||||
typedef typename component_type<number<rational_adaptor<IntBackend> > >::type comp_t;
|
||||
comp_t t = backend.data().numerator();
|
||||
t /= backend.data().denominator();
|
||||
*result = t.template convert_to<R>();
|
||||
}
|
||||
|
||||
template <class IntBackend>
|
||||
inline bool eval_is_zero(const rational_adaptor<IntBackend>& val)
|
||||
{
|
||||
return eval_is_zero(val.data().numerator().backend());
|
||||
}
|
||||
template <class IntBackend>
|
||||
inline int eval_get_sign(const rational_adaptor<IntBackend>& val)
|
||||
{
|
||||
return eval_get_sign(val.data().numerator().backend());
|
||||
}
|
||||
|
||||
template<class IntBackend, class V>
|
||||
inline void assign_components(rational_adaptor<IntBackend>& result, const V& v1, const V& v2)
|
||||
{
|
||||
result.data().assign(v1, v2);
|
||||
}
|
||||
|
||||
template <class IntBackend>
|
||||
inline std::size_t hash_value(const rational_adaptor<IntBackend>& val)
|
||||
{
|
||||
std::size_t result = hash_value(val.data().numerator());
|
||||
boost::hash_combine(result, val.data().denominator());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
} // namespace backends
|
||||
|
||||
template<class IntBackend>
|
||||
struct expression_template_default<backends::rational_adaptor<IntBackend> > : public expression_template_default<IntBackend> {};
|
||||
|
||||
template<class IntBackend>
|
||||
struct number_category<backends::rational_adaptor<IntBackend> > : public mpl::int_<number_kind_rational>{};
|
||||
|
||||
using boost::multiprecision::backends::rational_adaptor;
|
||||
|
||||
template <class T>
|
||||
struct component_type<rational_adaptor<T> >
|
||||
{
|
||||
typedef number<T> type;
|
||||
};
|
||||
|
||||
template <class IntBackend, expression_template_option ET>
|
||||
inline number<IntBackend, ET> numerator(const number<rational_adaptor<IntBackend>, ET>& val)
|
||||
{
|
||||
return val.backend().data().numerator();
|
||||
}
|
||||
template <class IntBackend, expression_template_option ET>
|
||||
inline number<IntBackend, ET> denominator(const number<rational_adaptor<IntBackend>, ET>& val)
|
||||
{
|
||||
return val.backend().data().denominator();
|
||||
}
|
||||
|
||||
#ifdef BOOST_NO_SFINAE_EXPR
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<class U, class IntBackend>
|
||||
struct is_explicitly_convertible<U, rational_adaptor<IntBackend> > : public is_explicitly_convertible<U, IntBackend> {};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}} // namespaces
|
||||
|
||||
|
||||
namespace std{
|
||||
|
||||
template <class IntBackend, boost::multiprecision::expression_template_option ExpressionTemplates>
|
||||
class numeric_limits<boost::multiprecision::number<boost::multiprecision::rational_adaptor<IntBackend>, ExpressionTemplates> > : public std::numeric_limits<boost::multiprecision::number<IntBackend, ExpressionTemplates> >
|
||||
{
|
||||
typedef std::numeric_limits<boost::multiprecision::number<IntBackend> > base_type;
|
||||
typedef boost::multiprecision::number<boost::multiprecision::rational_adaptor<IntBackend> > number_type;
|
||||
public:
|
||||
BOOST_STATIC_CONSTEXPR bool is_integer = false;
|
||||
BOOST_STATIC_CONSTEXPR bool is_exact = true;
|
||||
BOOST_STATIC_CONSTEXPR number_type (min)() { return (base_type::min)(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type (max)() { return (base_type::max)(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type lowest() { return -(max)(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type epsilon() { return base_type::epsilon(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type round_error() { return epsilon() / 2; }
|
||||
BOOST_STATIC_CONSTEXPR number_type infinity() { return base_type::infinity(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type quiet_NaN() { return base_type::quiet_NaN(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type signaling_NaN() { return base_type::signaling_NaN(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type denorm_min() { return base_type::denorm_min(); }
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
|
||||
|
||||
template <class IntBackend, boost::multiprecision::expression_template_option ExpressionTemplates>
|
||||
BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::rational_adaptor<IntBackend>, ExpressionTemplates> >::is_integer;
|
||||
template <class IntBackend, boost::multiprecision::expression_template_option ExpressionTemplates>
|
||||
BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::rational_adaptor<IntBackend>, ExpressionTemplates> >::is_exact;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,108 @@
|
||||
// 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_FILTERED_QUEUE_HPP
|
||||
#define BOOST_FILTERED_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 <algorithm>
|
||||
|
||||
namespace boost {
|
||||
|
||||
/** Queue adaptor that filters elements pushed into the queue
|
||||
* according to some predicate.
|
||||
*/
|
||||
template<typename Buffer, typename Predicate>
|
||||
class filtered_queue
|
||||
{
|
||||
public:
|
||||
typedef Buffer buffer_type;
|
||||
typedef Predicate predicate_type;
|
||||
typedef typename Buffer::value_type value_type;
|
||||
typedef typename Buffer::size_type size_type;
|
||||
|
||||
/**
|
||||
* Constructs a new filtered queue with an initial buffer and a
|
||||
* predicate.
|
||||
*
|
||||
* @param buffer the initial buffer
|
||||
* @param pred the predicate
|
||||
*/
|
||||
explicit
|
||||
filtered_queue(const buffer_type& buffer = buffer_type(),
|
||||
const predicate_type& pred = predicate_type())
|
||||
: buffer(buffer), pred(pred) {}
|
||||
|
||||
/** Push a value into the queue.
|
||||
*
|
||||
* If the predicate returns @c true for @p x, pushes @p x into the
|
||||
* buffer.
|
||||
*/
|
||||
void push(const value_type& x) { if (pred(x)) buffer.push(x); }
|
||||
|
||||
/** Pop the front element off the buffer.
|
||||
*
|
||||
* @pre @c !empty()
|
||||
*/
|
||||
void pop() { buffer.pop(); }
|
||||
|
||||
/** Retrieve the front (top) element in the buffer.
|
||||
*
|
||||
* @pre @c !empty()
|
||||
*/
|
||||
value_type& top() { return buffer.top(); }
|
||||
|
||||
/**
|
||||
* \overload
|
||||
*/
|
||||
const value_type& top() const { return buffer.top(); }
|
||||
|
||||
/** Determine the number of elements in the buffer. */
|
||||
size_type size() const { return buffer.size(); }
|
||||
|
||||
/** Determine if the buffer is empty. */
|
||||
bool empty() const { return buffer.empty(); }
|
||||
|
||||
/** Get a reference to the underlying buffer. */
|
||||
buffer_type& base() { return buffer; }
|
||||
const buffer_type& base() const { return buffer; }
|
||||
|
||||
/** Swap the contents of this with @p other. */
|
||||
void swap(filtered_queue& other)
|
||||
{
|
||||
using std::swap;
|
||||
swap(buffer, other.buffer);
|
||||
swap(pred, other.pred);
|
||||
}
|
||||
|
||||
private:
|
||||
buffer_type buffer;
|
||||
predicate_type pred;
|
||||
};
|
||||
|
||||
/** Create a filtered queue. */
|
||||
template<typename Buffer, typename Predicate>
|
||||
inline filtered_queue<Buffer, Predicate>
|
||||
make_filtered_queue(const Buffer& buffer, const Predicate& pred)
|
||||
{ return filtered_queue<Buffer, Predicate>(buffer, pred); }
|
||||
|
||||
/** Swap a filtered_queue. */
|
||||
template<typename Buffer, typename Predicate>
|
||||
inline void
|
||||
swap(filtered_queue<Buffer, Predicate>& x,
|
||||
filtered_queue<Buffer, Predicate>& y)
|
||||
{
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
} // end namespace boost
|
||||
|
||||
#endif // BOOST_FILTERED_QUEUE_HPP
|
||||
@@ -0,0 +1,313 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// boost variant/get.hpp header file
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2003 Eric Friedman, Itay Maman
|
||||
// Copyright (c) 2014 Antony Polukhin
|
||||
//
|
||||
// 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_VARIANT_GET_HPP
|
||||
#define BOOST_VARIANT_GET_HPP
|
||||
|
||||
#include <exception>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
#include <boost/variant/detail/element_index.hpp>
|
||||
|
||||
#include <boost/type_traits/add_reference.hpp>
|
||||
#include <boost/type_traits/add_pointer.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
#if defined(BOOST_CLANG)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wweak-vtables"
|
||||
#endif
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// class bad_get
|
||||
//
|
||||
// The exception thrown in the event of a failed get of a value.
|
||||
//
|
||||
class BOOST_SYMBOL_VISIBLE bad_get
|
||||
: public std::exception
|
||||
{
|
||||
public: // std::exception implementation
|
||||
|
||||
virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
return "boost::bad_get: "
|
||||
"failed value get using boost::get";
|
||||
}
|
||||
|
||||
};
|
||||
#if defined(BOOST_CLANG)
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// function template get<T>
|
||||
//
|
||||
// Retrieves content of given variant object if content is of type T.
|
||||
// Otherwise: pointer ver. returns 0; reference ver. throws bad_get.
|
||||
//
|
||||
|
||||
namespace detail { namespace variant {
|
||||
|
||||
// (detail) class template get_visitor
|
||||
//
|
||||
// Generic static visitor that: if the value is of the specified type,
|
||||
// returns a pointer to the value it visits; else a null pointer.
|
||||
//
|
||||
template <typename T>
|
||||
struct get_visitor
|
||||
{
|
||||
private: // private typedefs
|
||||
|
||||
typedef typename add_pointer<T>::type pointer;
|
||||
typedef typename add_reference<T>::type reference;
|
||||
|
||||
public: // visitor typedefs
|
||||
|
||||
typedef pointer result_type;
|
||||
|
||||
public: // visitor interfaces
|
||||
|
||||
pointer operator()(reference operand) const BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::addressof(operand);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
pointer operator()(const U&) const BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<pointer>(0);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::variant
|
||||
|
||||
#ifndef BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE
|
||||
# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
|
||||
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)
|
||||
# else
|
||||
# define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
|
||||
, t* = 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// relaxed_get<U>(variant) methods
|
||||
//
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<U>::type
|
||||
relaxed_get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
typedef typename add_pointer<U>::type U_ptr;
|
||||
if (!operand) return static_cast<U_ptr>(0);
|
||||
|
||||
detail::variant::get_visitor<U> v;
|
||||
return operand->apply_visitor(v);
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<const U>::type
|
||||
relaxed_get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
typedef typename add_pointer<const U>::type U_ptr;
|
||||
if (!operand) return static_cast<U_ptr>(0);
|
||||
|
||||
detail::variant::get_visitor<const U> v;
|
||||
return operand->apply_visitor(v);
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<U>::type
|
||||
relaxed_get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
typedef typename add_pointer<U>::type U_ptr;
|
||||
U_ptr result = relaxed_get<U>(boost::addressof(operand));
|
||||
|
||||
if (!result)
|
||||
boost::throw_exception(bad_get());
|
||||
return *result;
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<const U>::type
|
||||
relaxed_get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
typedef typename add_pointer<const U>::type U_ptr;
|
||||
U_ptr result = relaxed_get<const U>(boost::addressof(operand));
|
||||
|
||||
if (!result)
|
||||
boost::throw_exception(bad_get());
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// strict_get<U>(variant) methods
|
||||
//
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<U>::type
|
||||
strict_get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
(boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
|
||||
"boost::variant does not contain specified type U, "
|
||||
"call to boost::get<U>(boost::variant<T...>*) will always return NULL"
|
||||
);
|
||||
|
||||
return relaxed_get<U>(operand);
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<const U>::type
|
||||
strict_get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
(boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, const U >::value),
|
||||
"boost::variant does not contain specified type U, "
|
||||
"call to boost::get<U>(const boost::variant<T...>*) will always return NULL"
|
||||
);
|
||||
|
||||
return relaxed_get<U>(operand);
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<U>::type
|
||||
strict_get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
(boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
|
||||
"boost::variant does not contain specified type U, "
|
||||
"call to boost::get<U>(boost::variant<T...>&) will always throw boost::bad_get exception"
|
||||
);
|
||||
|
||||
return relaxed_get<U>(operand);
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<const U>::type
|
||||
strict_get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
(boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, const U >::value),
|
||||
"boost::variant does not contain specified type U, "
|
||||
"call to boost::get<U>(const boost::variant<T...>&) will always throw boost::bad_get exception"
|
||||
);
|
||||
|
||||
return relaxed_get<U>(operand);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// get<U>(variant) methods
|
||||
//
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<U>::type
|
||||
get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
|
||||
return relaxed_get<U>(operand);
|
||||
#else
|
||||
return strict_get<U>(operand);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_pointer<const U>::type
|
||||
get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
|
||||
return relaxed_get<U>(operand);
|
||||
#else
|
||||
return strict_get<U>(operand);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<U>::type
|
||||
get(
|
||||
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
|
||||
return relaxed_get<U>(operand);
|
||||
#else
|
||||
return strict_get<U>(operand);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
||||
inline
|
||||
typename add_reference<const U>::type
|
||||
get(
|
||||
const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
||||
BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
||||
)
|
||||
{
|
||||
#ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
|
||||
return relaxed_get<U>(operand);
|
||||
#else
|
||||
return strict_get<U>(operand);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_VARIANT_GET_HPP
|
||||
@@ -0,0 +1,187 @@
|
||||
#include "decodedtext.h"
|
||||
|
||||
#include <QStringList>
|
||||
#include <QRegularExpression>
|
||||
|
||||
QString DecodedText::CQersCall()
|
||||
{
|
||||
// extract the CQer's call TODO: does this work with all call formats?
|
||||
int s1 {0};
|
||||
int position;
|
||||
QString t=_string;
|
||||
if ((position = _string.indexOf (" CQ DX ")) >= 0)
|
||||
{
|
||||
s1 = 7 + position;
|
||||
}
|
||||
else if ((position = _string.indexOf (" CQDX ")) >= 0)
|
||||
{
|
||||
s1 = 6 + position;
|
||||
}
|
||||
else if ((position = _string.indexOf (" CQ ")) >= 0)
|
||||
{
|
||||
s1 = 4 + position;
|
||||
if(_string.mid(s1,3).toInt() > 0 and _string.mid(s1,3).toInt() <= 999) s1 += 4;
|
||||
}
|
||||
else if ((position = _string.indexOf (" DE ")) >= 0)
|
||||
{
|
||||
s1 = 4 + position;
|
||||
}
|
||||
else if ((position = _string.indexOf (" QRZ ")) >= 0)
|
||||
{
|
||||
s1 = 5 + position;
|
||||
}
|
||||
auto s2 = _string.indexOf (" ", s1);
|
||||
return _string.mid (s1, s2 - s1);
|
||||
}
|
||||
|
||||
|
||||
bool DecodedText::isJT65()
|
||||
{
|
||||
return _string.indexOf("#") == column_mode;
|
||||
}
|
||||
|
||||
bool DecodedText::isJT9()
|
||||
{
|
||||
return _string.indexOf("@") == column_mode;
|
||||
}
|
||||
|
||||
bool DecodedText::isTX()
|
||||
{
|
||||
int i = _string.indexOf("Tx");
|
||||
return (i >= 0 && i < 15); // TODO guessing those numbers. Does Tx ever move?
|
||||
}
|
||||
|
||||
int DecodedText::frequencyOffset()
|
||||
{
|
||||
return _string.mid(column_freq,4).toInt();
|
||||
}
|
||||
|
||||
int DecodedText::snr()
|
||||
{
|
||||
int i1=_string.indexOf(" ")+1;
|
||||
return _string.mid(i1,3).toInt();
|
||||
}
|
||||
|
||||
float DecodedText::dt()
|
||||
{
|
||||
return _string.mid(column_dt,5).toFloat();
|
||||
}
|
||||
|
||||
/*
|
||||
2343 -11 0.8 1259 # YV6BFE F6GUU R-08
|
||||
2343 -19 0.3 718 # VE6WQ SQ2NIJ -14
|
||||
2343 -7 0.3 815 # KK4DSD W7VP -16
|
||||
2343 -13 0.1 3627 @ CT1FBK IK5YZT R+02
|
||||
|
||||
0605 Tx 1259 # CQ VK3ACF QF22
|
||||
*/
|
||||
|
||||
// find and extract any report. Returns true if this is a standard message
|
||||
bool DecodedText::report(QString const& myBaseCall, QString const& dxBaseCall, /*mod*/QString& report)
|
||||
{
|
||||
QString msg=_string.mid(column_qsoText).trimmed();
|
||||
if(msg.length() < 1) return false;
|
||||
msg = msg.remove (QRegularExpression {"[<>]"});
|
||||
int i1=msg.indexOf('\r');
|
||||
if (i1>0)
|
||||
msg=msg.left (i1-1);
|
||||
bool b = stdmsg_ ((msg + " ").toLatin1().constData(),22); // stdmsg is a fortran routine that packs the text, unpacks it and compares the result
|
||||
|
||||
QStringList w=msg.split(" ",QString::SkipEmptyParts);
|
||||
if(w.size ()
|
||||
&& b && (w[0] == myBaseCall
|
||||
|| w[0].endsWith ("/" + myBaseCall)
|
||||
|| w[0].startsWith (myBaseCall + "/")
|
||||
|| (w.size () > 1 && !dxBaseCall.isEmpty ()
|
||||
&& (w[1] == dxBaseCall
|
||||
|| w[1].endsWith ("/" + dxBaseCall)
|
||||
|| w[1].startsWith (dxBaseCall + "/")))))
|
||||
{
|
||||
QString tt="";
|
||||
if(w.size() > 2) tt=w[2];
|
||||
bool ok;
|
||||
i1=tt.toInt(&ok);
|
||||
if (ok and i1>=-50 and i1<50)
|
||||
{
|
||||
report = tt;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tt.mid(0,1)=="R")
|
||||
{
|
||||
i1=tt.mid(1).toInt(&ok);
|
||||
if(ok and i1>=-50 and i1<50)
|
||||
{
|
||||
report = tt.mid(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
// get the first text word, usually the call
|
||||
QString DecodedText::call()
|
||||
{
|
||||
auto call = _string;
|
||||
call = call.replace (QRegularExpression {" CQ ([A-Z]{2,2}|[0-9]{3,3}) "}, " CQ_\\1 ").mid (column_qsoText);
|
||||
int i = call.indexOf(" ");
|
||||
return call.mid(0,i);
|
||||
}
|
||||
|
||||
// get the second word, most likely the de call and the third word, most likely grid
|
||||
void DecodedText::deCallAndGrid(/*out*/QString& call, QString& grid)
|
||||
{
|
||||
auto msg = _string;
|
||||
msg = msg.replace (QRegularExpression {" CQ ([A-Z]{2,2}|[0-9]{3,3}) "}, " CQ_\\1 ").mid (column_qsoText);
|
||||
int i1 = msg.indexOf (" ");
|
||||
call = msg.mid (i1 + 1);
|
||||
int i2 = call.indexOf (" ");
|
||||
if (" R " == call.mid (i2, 3)) // MSK144 contest mode report
|
||||
{
|
||||
grid = call.mid (i2 + 3, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
grid = call.mid (i2 + 1, 4);
|
||||
}
|
||||
call = call.left (i2).replace (">", "");
|
||||
}
|
||||
|
||||
int DecodedText::timeInSeconds()
|
||||
{
|
||||
return 60*_string.mid(column_time,2).toInt() + _string.mid(2,2).toInt();
|
||||
}
|
||||
|
||||
/*
|
||||
2343 -11 0.8 1259 # YV6BFE F6GUU R-08
|
||||
2343 -19 0.3 718 # VE6WQ SQ2NIJ -14
|
||||
2343 -7 0.3 815 # KK4DSD W7VP -16
|
||||
2343 -13 0.1 3627 @ CT1FBK IK5YZT R+02
|
||||
|
||||
0605 Tx 1259 # CQ VK3ACF QF22
|
||||
*/
|
||||
|
||||
QString DecodedText::report() // returns a string of the SNR field with a leading + or - followed by two digits
|
||||
{
|
||||
int sr = snr();
|
||||
if (sr<-50)
|
||||
sr = -50;
|
||||
else
|
||||
if (sr > 49)
|
||||
sr = 49;
|
||||
|
||||
QString rpt;
|
||||
rpt.sprintf("%d",abs(sr));
|
||||
if (sr > 9)
|
||||
rpt = "+" + rpt;
|
||||
else
|
||||
if (sr >= 0)
|
||||
rpt = "+0" + rpt;
|
||||
else
|
||||
if (sr >= -9)
|
||||
rpt = "-0" + rpt;
|
||||
else
|
||||
rpt = "-" + rpt;
|
||||
return rpt;
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
# Makefile for MinGW on Windows
|
||||
# Windows re-direct:
|
||||
# C> make > junk1 2>&1
|
||||
|
||||
# Set paths
|
||||
EXE_DIR = ../../wsjtx_install
|
||||
INCPATH = -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/QtCore' \
|
||||
-I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include' \
|
||||
-I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/ActiveQt' \
|
||||
-I'release' -I'.' -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/mkspecs/win32-g++'
|
||||
|
||||
# Compilers
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
FC = g95
|
||||
|
||||
FFLAGS = -O2 -fbounds-check -Wall -Wno-precision-loss -fno-second-underscore
|
||||
CFLAGS = -I. -fbounds-check -mno-stack-arg-probe
|
||||
|
||||
# Default rules
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -c $<
|
||||
%.o: %.f
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.f90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
|
||||
all: libjt9.a jt9sim.exe jt9.exe jt9code.exe jt65.exe
|
||||
|
||||
OBJS1 = pctile.o graycode.o sort.o ssort.o \
|
||||
unpackmsg.o igray.o unpackcall.o unpackgrid.o \
|
||||
grid2k.o unpacktext.o getpfx2.o packmsg.o deg2grid.o \
|
||||
packtext.o getpfx1.o packcall.o k2grid.o packgrid.o \
|
||||
nchar.o four2a.o grid2deg.o pfxdump.o f77_wisdom.o \
|
||||
symspec.o analytic.o db.o genjt9.o \
|
||||
packbits.o unpackbits.o encode232.o interleave9.o \
|
||||
entail.o fano232.o gran.o sync9.o decode9.o \
|
||||
fil3.o decoder.o grid2n.o n2grid.o timer.o \
|
||||
softsym.o getlags.o afc9.o fchisq.o twkfreq.o downsam9.o \
|
||||
peakdt9.o symspec2.o stdmsg.o morse.o azdist.o geodist.o \
|
||||
fillcom.o chkss2.o zplot9.o flat2.o \
|
||||
jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
|
||||
filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
|
||||
extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
|
||||
move.o indexx.o graycode65.o twkfreq65.o smo121.o \
|
||||
wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o
|
||||
|
||||
libjt9.a: $(OBJS1)
|
||||
ar cr libjt9.a $(OBJS1)
|
||||
ranlib libjt9.a
|
||||
|
||||
OBJS2 = jt9.o jt9a.o jt9b.o jt9c.o ipcomm.o sec_midn.o usleep.o
|
||||
LIBS2 = -L'c:/QtSDK/Desktop/Qt/4.7.4/mingw/lib' -lQtCore4
|
||||
jt9.exe: $(OBJS2) libjt9.a
|
||||
$(CXX) -o jt9.exe $(OBJS2) $(LIBS2) libjt9.a ../libfftw3f_win.a \
|
||||
c:/MinGW/lib/libf95.a
|
||||
mkdir -p $(EXE_DIR)
|
||||
cp jt9.exe $(EXE_DIR)
|
||||
|
||||
OBJS3 = jt9sim.o
|
||||
jt9sim.exe: $(OBJS3) libjt9.a
|
||||
$(FC) -o jt9sim.exe $(OBJS3) libjt9.a
|
||||
|
||||
OBJS4 = jt9code.o
|
||||
jt9code.exe: $(OBJS4) libjt9.a
|
||||
$(FC) -o jt9code.exe $(OBJS4) libjt9.a
|
||||
|
||||
OBJS5 = jt65.o
|
||||
jt65.exe: $(OBJS5) libjt9.a
|
||||
$(FC) -o jt65.exe $(OBJS5) libjt9.a ../libfftw3f_win.a
|
||||
|
||||
sync9.o: sync9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c sync9.f90
|
||||
|
||||
spec9.o: spec9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c spec9.f90
|
||||
|
||||
peakdt9.o: peakdt9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c peakdt9.f90
|
||||
|
||||
jt9sim.o: jt9sim.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c jt9sim.f90
|
||||
|
||||
genjt9.o: genjt9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c genjt9.f90
|
||||
|
||||
redsync.o: redsync.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c redsync.f90
|
||||
|
||||
unpackmsg.o: unpackmsg.f90
|
||||
$(FC) -c -O0 -fbounds-check -Wall -Wno-precision-loss unpackmsg.f90
|
||||
|
||||
ipcomm.o: ipcomm.cpp
|
||||
$(CXX) -c $(INCPATH) ipcomm.cpp
|
||||
|
||||
sec_midn.o: sec_midn.f90
|
||||
$(FC) -c -fno-second-underscore sec_midn.f90
|
||||
|
||||
#rig_control.o: rig_control.c
|
||||
# $(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include rig_control.c
|
||||
|
||||
tstrig.o: tstrig.c
|
||||
$(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include tstrig.c
|
||||
|
||||
init_rs.o: init_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
|
||||
|
||||
encode_rs.o: encode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
|
||||
|
||||
decode_rs.o: decode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
|
||||
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
clean:
|
||||
rm -f *.o libjt9.a wsjtx.exe jt9sim.exe jt9.exe jt65.exe
|
||||
@@ -0,0 +1,42 @@
|
||||
// (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)
|
||||
//
|
||||
// This file is machine generated, do not edit by hand
|
||||
|
||||
// Polynomial evaluation using Horners rule
|
||||
#ifndef BOOST_MATH_TOOLS_POLY_RAT_2_HPP
|
||||
#define BOOST_MATH_TOOLS_POLY_RAT_2_HPP
|
||||
|
||||
namespace boost{ namespace math{ namespace tools{ namespace detail{
|
||||
|
||||
template <class T, class U, class V>
|
||||
inline V evaluate_rational_c_imp(const T*, const U*, const V&, const mpl::int_<0>*) BOOST_MATH_NOEXCEPT(V)
|
||||
{
|
||||
return static_cast<V>(0);
|
||||
}
|
||||
|
||||
template <class T, class U, class V>
|
||||
inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const mpl::int_<1>*) BOOST_MATH_NOEXCEPT(V)
|
||||
{
|
||||
return static_cast<V>(a[0]) / static_cast<V>(b[0]);
|
||||
}
|
||||
|
||||
template <class T, class U, class V>
|
||||
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<2>*) BOOST_MATH_NOEXCEPT(V)
|
||||
{
|
||||
if(x <= 1)
|
||||
return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
|
||||
else
|
||||
{
|
||||
V z = 1 / x;
|
||||
return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}}}} // namespaces
|
||||
|
||||
#endif // include guard
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// 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_ALGORITHM_GENERATE_N_HPP
|
||||
#define BOOST_COMPUTE_ALGORITHM_GENERATE_N_HPP
|
||||
|
||||
#include <boost/compute/system.hpp>
|
||||
#include <boost/compute/command_queue.hpp>
|
||||
#include <boost/compute/algorithm/generate.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
|
||||
/// Stores the result of \p generator for each element in the range
|
||||
/// [\p first, \p first + \p count).
|
||||
template<class OutputIterator, class Size, class Generator>
|
||||
inline void generate_n(OutputIterator first,
|
||||
Size count,
|
||||
Generator generator,
|
||||
command_queue &queue = system::default_queue())
|
||||
{
|
||||
::boost::compute::generate(first, first + count, generator, queue);
|
||||
}
|
||||
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_ALGORITHM_GENERATE_N_HPP
|
||||
@@ -0,0 +1,90 @@
|
||||
#ifndef MESSAGE_SERVER_HPP__
|
||||
#define MESSAGE_SERVER_HPP__
|
||||
|
||||
#include <QObject>
|
||||
#include <QTime>
|
||||
#include <QDateTime>
|
||||
#include <QHostAddress>
|
||||
|
||||
#include "udp_export.h"
|
||||
#include "Radio.hpp"
|
||||
|
||||
#include "pimpl_h.hpp"
|
||||
|
||||
class QString;
|
||||
|
||||
//
|
||||
// MessageServer - a reference implementation of a message server
|
||||
// matching the MessageClient class at the other end
|
||||
// of the wire
|
||||
//
|
||||
// This class is fully functioning and suitable for use in C++
|
||||
// applications that use the Qt framework. Other applications should
|
||||
// use this classes' implementation as a reference implementation.
|
||||
//
|
||||
class UDP_EXPORT MessageServer
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
using port_type = quint16;
|
||||
using Frequency = Radio::Frequency;
|
||||
|
||||
MessageServer (QObject * parent = nullptr,
|
||||
QString const& version = QString {}, QString const& revision = QString {});
|
||||
|
||||
// start or restart the server, if the multicast_group_address
|
||||
// argument is given it is assumed to be a multicast group address
|
||||
// which the server will join
|
||||
Q_SLOT void start (port_type port,
|
||||
QHostAddress const& multicast_group_address = QHostAddress {});
|
||||
|
||||
// ask the client with identification 'id' to make the same action
|
||||
// as a double click on the decode would
|
||||
//
|
||||
// note that the client is not obliged to take any action and only
|
||||
// takes any action if the decode is present and is a CQ or QRZ message
|
||||
Q_SLOT void reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
||||
, QString const& mode, QString const& message, bool low_confidence);
|
||||
|
||||
// ask the client with identification 'id' to replay all decodes
|
||||
Q_SLOT void replay (QString const& id);
|
||||
|
||||
// ask the client with identification 'id' to halt transmitting
|
||||
// auto_only just disables auto Tx, otherwise halt is immediate
|
||||
Q_SLOT void halt_tx (QString const& id, bool auto_only);
|
||||
|
||||
// ask the client with identification 'id' to set the free text
|
||||
// message and optionally send it ASAP
|
||||
Q_SLOT void free_text (QString const& id, QString const& text, bool send);
|
||||
|
||||
// the following signals are emitted when a client broadcasts the
|
||||
// matching message
|
||||
Q_SIGNAL void client_opened (QString const& id, QString const& version, QString const& revision);
|
||||
Q_SIGNAL void status_update (QString const& id, Frequency, QString const& mode, QString const& dx_call
|
||||
, QString const& report, QString const& tx_mode, bool tx_enabled
|
||||
, bool transmitting, bool decoding, qint32 rx_df, qint32 tx_df
|
||||
, QString const& de_call, QString const& de_grid, QString const& dx_grid
|
||||
, bool watchdog_timeout, QString const& sub_mode, bool fast_mode);
|
||||
Q_SIGNAL void client_closed (QString const& id);
|
||||
Q_SIGNAL void decode (bool is_new, QString const& id, QTime time, qint32 snr, float delta_time
|
||||
, quint32 delta_frequency, QString const& mode, QString const& message
|
||||
, bool low_confidence);
|
||||
Q_SIGNAL void WSPR_decode (bool is_new, QString const& id, QTime time, qint32 snr, float delta_time, Frequency
|
||||
, qint32 drift, QString const& callsign, QString const& grid, qint32 power);
|
||||
Q_SIGNAL void qso_logged (QString const& id, QDateTime timeOff, QString const& dx_call, QString const& dx_grid
|
||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||
, QString const& report_received, QString const& tx_power, QString const& comments
|
||||
, QString const& name, QDateTime timeOn);
|
||||
Q_SIGNAL void clear_decodes (QString const& id);
|
||||
|
||||
// this signal is emitted when a network error occurs
|
||||
Q_SIGNAL void error (QString const&) const;
|
||||
|
||||
private:
|
||||
class UDP_NO_EXPORT impl;
|
||||
pimpl<impl> m_;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,92 @@
|
||||
=== AP Decoding
|
||||
|
||||
With the QRA64 decoder Nico Palermo, IV3NWV, introduced a technique
|
||||
for decoding with the aid of information that naturally accumulates
|
||||
during a minimal QSO. This _a priori_ (AP) information can be
|
||||
used to increase the sensitivity of the decoder.
|
||||
|
||||
When an operator decides to answer a CQ, he already knows his own
|
||||
callsign and that of his potential QSO partner. He therefore knows
|
||||
what to expect for at least 56 of the 72 message bits in a
|
||||
standard-format response to his call. The _WSJT-X_ decoders for QRA64
|
||||
and FT8 can use these AP bits to decode messages containing them with
|
||||
higher sensitivity than otherwise possible.
|
||||
|
||||
We have implemented AP decoding in slightly different ways in QRA64
|
||||
and FT8. To provide some explicit examples for users, we provide here
|
||||
a brief description of the FT8 behavior.
|
||||
|
||||
The FT8 decoder always tries first to decode a signal without using
|
||||
any AP information. If this attempt fails, and if *Enable AP* is
|
||||
checked on the *Decode* menu, a second attempt hypothesizes that the
|
||||
message contains callsigns MyCall and DxCall. If the QSO has
|
||||
progressed to the point where signal reports have been exchanged, a
|
||||
third attempt hypothesizes that the message contains the known
|
||||
callsigns followed by RRR, RR73, or 73.
|
||||
|
||||
AP decoding attempts effectively set the AP bits to the hypothesized
|
||||
values, as if they had been received perfectly. The decoder then
|
||||
proceeds to determine whether the remaining message and parity bits
|
||||
are consistent with the hypothesized AP bits. If a codeword is found
|
||||
that the decoder judges to have high (but not overwhelmingly high)
|
||||
probability of being correct, a ? character is appended when the
|
||||
decoded message is displayed.
|
||||
|
||||
Successful AP decodes are always labeled with an end-of-line indicator
|
||||
of the form aP, where P is one of the single-digit AP decoding types
|
||||
listed in Table 1. For example, an a2 designator says that the
|
||||
successful decode used MyCall as hypothetically known information.
|
||||
|
||||
[[AP_INFO_TABLE]]
|
||||
.AP information types
|
||||
[width="25%",cols="h10,<m20",frame=topbot,options="header"]
|
||||
|===============================================
|
||||
|P | Message components
|
||||
|1 | CQ     ?     ?
|
||||
|2 | MyCall     ?     ?
|
||||
|3 | MyCall DxCall     ?
|
||||
|4 | MyCall DxCall RRR
|
||||
|5 | MyCall DxCall 73
|
||||
|6 | MyCall DxCall RR73
|
||||
|===============================================
|
||||
|
||||
=== Decoded Lines
|
||||
|
||||
Displayed information accompanying decoded messages generally includes UTC,
|
||||
signal-to-noise ratio in dB, time offset DT in seconds, and
|
||||
audio frequency in Hz. Some modes include additional information such
|
||||
as frequency offset from nominal (DF), frequency drift (Drift or F1),
|
||||
or distance (km or mi).
|
||||
|
||||
There may also be some cryptic characters with special meanings
|
||||
summarized in the following Table:
|
||||
|
||||
[[DECODED_LINES_TABLE]]
|
||||
.Notations used on decoded text lines
|
||||
[width="50%",cols="h,3*^",frame=topbot,options="header"]
|
||||
|===========================================
|
||||
|Mode |Mode character|Sync character|End of line information
|
||||
|FT8 | ~ | | aP
|
||||
|JT4 | $ | *, # | f, fN, dNC
|
||||
|JT9 | @ | |
|
||||
|JT65 | # | |
|
||||
|JT65 VHF| # | *, # | f, fN, dNC
|
||||
|QRA64 | : | * | R
|
||||
|ISCAT | | * | M N C T
|
||||
|MSK144 | & | | N
|
||||
|===========================================
|
||||
Sync character::
|
||||
`*` - Normal sync +
|
||||
`#` - Alternate sync
|
||||
|
||||
End of line information::
|
||||
`a` - Decoded with aid of some a priori (AP) information
|
||||
`C` - Confidence indicator [ISCAT and Deep Search; (0-9,*)] +
|
||||
`d` - Deep Search algorithm +
|
||||
`f` - Franke-Taylor or Fano algorithm +
|
||||
`M` - Message length (characters) +
|
||||
`N` - Number of Rx intervals or frames averaged +
|
||||
`P` - Number indicating type of AP information (Table 1, above) +
|
||||
`R` - Return code from QRA64 decoder +
|
||||
`T` - Length of analyzed region (s)
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
#ifndef BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP
|
||||
#define BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// basic_pointer_oserializer.hpp: extenstion of type_info required for
|
||||
// serialization.
|
||||
|
||||
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
||||
// 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)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/archive/detail/auto_link_archive.hpp>
|
||||
#include <boost/archive/detail/basic_serializer.hpp>
|
||||
|
||||
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4511 4512)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
class extended_type_info;
|
||||
} // namespace serialization
|
||||
|
||||
// forward declarations
|
||||
namespace archive {
|
||||
namespace detail {
|
||||
|
||||
class basic_iarchive;
|
||||
class basic_iserializer;
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE basic_pointer_iserializer
|
||||
: public basic_serializer {
|
||||
protected:
|
||||
explicit BOOST_ARCHIVE_DECL basic_pointer_iserializer(
|
||||
const boost::serialization::extended_type_info & type_
|
||||
);
|
||||
virtual BOOST_ARCHIVE_DECL ~basic_pointer_iserializer();
|
||||
public:
|
||||
virtual void * heap_allocation() const = 0;
|
||||
virtual const basic_iserializer & get_basic_serializer() const = 0;
|
||||
virtual void load_object_ptr(
|
||||
basic_iarchive & ar,
|
||||
void * x,
|
||||
const unsigned int file_version
|
||||
) const = 0;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace archive
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
|
||||
|
||||
#endif // BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP
|
||||
@@ -0,0 +1,86 @@
|
||||
|
||||
// Copyright (c) 2011 John Maddock
|
||||
// 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_MATH_TOOLS_BIG_CONSTANT_HPP
|
||||
#define BOOST_MATH_TOOLS_BIG_CONSTANT_HPP
|
||||
|
||||
#include <boost/math/tools/config.hpp>
|
||||
#ifndef BOOST_MATH_NO_LEXICAL_CAST
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#endif
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
namespace tools{
|
||||
|
||||
template <class T>
|
||||
struct numeric_traits : public std::numeric_limits< T > {};
|
||||
|
||||
#ifdef BOOST_MATH_USE_FLOAT128
|
||||
typedef __float128 largest_float;
|
||||
#define BOOST_MATH_LARGEST_FLOAT_C(x) x##Q
|
||||
template <>
|
||||
struct numeric_traits<__float128>
|
||||
{
|
||||
static const int digits = 113;
|
||||
static const int digits10 = 33;
|
||||
static const int max_exponent = 16384;
|
||||
static const bool is_specialized = true;
|
||||
};
|
||||
#else
|
||||
typedef long double largest_float;
|
||||
#define BOOST_MATH_LARGEST_FLOAT_C(x) x##L
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
inline BOOST_CONSTEXPR_OR_CONST T make_big_value(largest_float v, const char*, mpl::true_ const&, mpl::false_ const&) BOOST_MATH_NOEXCEPT(T)
|
||||
{
|
||||
return static_cast<T>(v);
|
||||
}
|
||||
template <class T>
|
||||
inline BOOST_CONSTEXPR_OR_CONST T make_big_value(largest_float v, const char*, mpl::true_ const&, mpl::true_ const&) BOOST_MATH_NOEXCEPT(T)
|
||||
{
|
||||
return static_cast<T>(v);
|
||||
}
|
||||
#ifndef BOOST_MATH_NO_LEXICAL_CAST
|
||||
template <class T>
|
||||
inline T make_big_value(largest_float, const char* s, mpl::false_ const&, mpl::false_ const&)
|
||||
{
|
||||
return boost::lexical_cast<T>(s);
|
||||
}
|
||||
#endif
|
||||
template <class T>
|
||||
inline BOOST_MATH_CONSTEXPR const char* make_big_value(largest_float, const char* s, mpl::false_ const&, mpl::true_ const&) BOOST_MATH_NOEXCEPT(T)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
//
|
||||
// For constants which might fit in a long double (if it's big enough):
|
||||
//
|
||||
#define BOOST_MATH_BIG_CONSTANT(T, D, x)\
|
||||
boost::math::tools::make_big_value<T>(\
|
||||
BOOST_MATH_LARGEST_FLOAT_C(x), \
|
||||
BOOST_STRINGIZE(x), \
|
||||
mpl::bool_< (is_convertible<boost::math::tools::largest_float, T>::value) && \
|
||||
((D <= boost::math::tools::numeric_traits<boost::math::tools::largest_float>::digits) \
|
||||
|| is_floating_point<T>::value \
|
||||
|| (boost::math::tools::numeric_traits<T>::is_specialized && \
|
||||
(boost::math::tools::numeric_traits<T>::digits10 <= boost::math::tools::numeric_traits<boost::math::tools::largest_float>::digits10))) >(), \
|
||||
boost::is_convertible<const char*, T>())
|
||||
//
|
||||
// For constants too huge for any conceivable long double (and which generate compiler errors if we try and declare them as such):
|
||||
//
|
||||
#define BOOST_MATH_HUGE_CONSTANT(T, D, x)\
|
||||
boost::math::tools::make_big_value<T>(0.0L, BOOST_STRINGIZE(x), \
|
||||
mpl::bool_<is_floating_point<T>::value || (boost::math::tools::numeric_traits<T>::is_specialized && boost::math::tools::numeric_traits<T>::max_exponent <= boost::math::tools::numeric_traits<boost::math::tools::largest_float>::max_exponent && boost::math::tools::numeric_traits<T>::digits <= boost::math::tools::numeric_traits<boost::math::tools::largest_float>::digits)>(), \
|
||||
boost::is_convertible<const char*, T>())
|
||||
|
||||
}}} // namespaces
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// Copyright (c) 2008, 2011 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/detail/yield_k.hpp>
|
||||
|
||||
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)
|
||||
|
||||
# define BOOST_SP_ARM_BARRIER "dmb"
|
||||
# define BOOST_SP_ARM_HAS_LDREX
|
||||
|
||||
#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
|
||||
|
||||
# define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5"
|
||||
# define BOOST_SP_ARM_HAS_LDREX
|
||||
|
||||
#else
|
||||
|
||||
# define BOOST_SP_ARM_BARRIER ""
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
int v_;
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
int r;
|
||||
|
||||
#ifdef BOOST_SP_ARM_HAS_LDREX
|
||||
|
||||
__asm__ __volatile__(
|
||||
"ldrex %0, [%2]; \n"
|
||||
"cmp %0, %1; \n"
|
||||
"strexne %0, %1, [%2]; \n"
|
||||
BOOST_SP_ARM_BARRIER :
|
||||
"=&r"( r ): // outputs
|
||||
"r"( 1 ), "r"( &v_ ): // inputs
|
||||
"memory", "cc" );
|
||||
|
||||
#else
|
||||
|
||||
__asm__ __volatile__(
|
||||
"swp %0, %1, [%2];\n"
|
||||
BOOST_SP_ARM_BARRIER :
|
||||
"=&r"( r ): // outputs
|
||||
"r"( 1 ), "r"( &v_ ): // inputs
|
||||
"memory", "cc" );
|
||||
|
||||
#endif
|
||||
|
||||
return r == 0;
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
for( unsigned k = 0; !try_lock(); ++k )
|
||||
{
|
||||
boost::detail::yield( k );
|
||||
}
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
__asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
|
||||
*const_cast< int volatile* >( &v_ ) = 0;
|
||||
__asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||
|
||||
#undef BOOST_SP_ARM_BARRIER
|
||||
#undef BOOST_SP_ARM_HAS_LDREX
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
||||
@@ -0,0 +1,29 @@
|
||||
# /* Copyright (C) 2001
|
||||
# * Housemarque Oy
|
||||
# * http://www.housemarque.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)
|
||||
# */
|
||||
#
|
||||
# /* Revised by Paul Mensonides (2002) */
|
||||
#
|
||||
# /* See http://www.boost.org for most recent version. */
|
||||
#
|
||||
# ifndef BOOST_PREPROCESSOR_LOGICAL_HPP
|
||||
# define BOOST_PREPROCESSOR_LOGICAL_HPP
|
||||
#
|
||||
# include <boost/preprocessor/logical/and.hpp>
|
||||
# include <boost/preprocessor/logical/bitand.hpp>
|
||||
# include <boost/preprocessor/logical/bitnor.hpp>
|
||||
# include <boost/preprocessor/logical/bitor.hpp>
|
||||
# include <boost/preprocessor/logical/bitxor.hpp>
|
||||
# include <boost/preprocessor/logical/bool.hpp>
|
||||
# include <boost/preprocessor/logical/compl.hpp>
|
||||
# include <boost/preprocessor/logical/nor.hpp>
|
||||
# include <boost/preprocessor/logical/not.hpp>
|
||||
# include <boost/preprocessor/logical/or.hpp>
|
||||
# include <boost/preprocessor/logical/xor.hpp>
|
||||
#
|
||||
# endif
|
||||
@@ -0,0 +1,41 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2014 Roshan <thisisroshansmail@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_ALGORITHM_ROTATE_COPY_HPP
|
||||
#define BOOST_COMPUTE_ALGORITHM_ROTATE_COPY_HPP
|
||||
|
||||
#include <boost/compute/system.hpp>
|
||||
#include <boost/compute/algorithm/copy.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
|
||||
/// Performs left rotation such that element at n_first comes to the
|
||||
/// beginning and the output is stored in range starting at result.
|
||||
///
|
||||
/// \see rotate()
|
||||
template<class InputIterator, class OutputIterator>
|
||||
inline void rotate_copy(InputIterator first,
|
||||
InputIterator n_first,
|
||||
InputIterator last,
|
||||
OutputIterator result,
|
||||
command_queue &queue = system::default_queue())
|
||||
{
|
||||
size_t count = detail::iterator_range_size(first, n_first);
|
||||
size_t count2 = detail::iterator_range_size(n_first, last);
|
||||
|
||||
::boost::compute::copy(first+count, last, result, queue);
|
||||
::boost::compute::copy(first, first+count, result+count2, queue);
|
||||
}
|
||||
|
||||
} //end compute namespace
|
||||
} //end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_ALGORITHM_ROTATE_COPY_HPP
|
||||
@@ -0,0 +1,892 @@
|
||||
// Boost operators.hpp header file ----------------------------------------//
|
||||
|
||||
// (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-2001.
|
||||
// (C) Copyright Daniel Frey 2002-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)
|
||||
|
||||
// See http://www.boost.org/libs/utility/operators.htm for documentation.
|
||||
|
||||
// Revision History
|
||||
// 22 Feb 16 Added ADL protection, preserve old work-arounds in
|
||||
// operators_v1.hpp and clean up this file. (Daniel Frey)
|
||||
// 16 Dec 10 Limit warning suppression for 4284 to older versions of VC++
|
||||
// (Matthew Bradbury, fixes #4432)
|
||||
// 07 Aug 08 Added "euclidean" spelling. (Daniel Frey)
|
||||
// 03 Apr 08 Make sure "convertible to bool" is sufficient
|
||||
// for T::operator<, etc. (Daniel Frey)
|
||||
// 24 May 07 Changed empty_base to depend on T, see
|
||||
// http://svn.boost.org/trac/boost/ticket/979
|
||||
// 21 Oct 02 Modified implementation of operators to allow compilers with a
|
||||
// correct named return value optimization (NRVO) to produce optimal
|
||||
// code. (Daniel Frey)
|
||||
// 02 Dec 01 Bug fixed in random_access_iteratable. (Helmut Zeisel)
|
||||
// 28 Sep 01 Factored out iterator operator groups. (Daryle Walker)
|
||||
// 27 Aug 01 'left' form for non commutative operators added;
|
||||
// additional classes for groups of related operators added;
|
||||
// workaround for empty base class optimization
|
||||
// bug of GCC 3.0 (Helmut Zeisel)
|
||||
// 25 Jun 01 output_iterator_helper changes: removed default template
|
||||
// parameters, added support for self-proxying, additional
|
||||
// documentation and tests (Aleksey Gurtovoy)
|
||||
// 29 May 01 Added operator classes for << and >>. Added input and output
|
||||
// iterator helper classes. Added classes to connect equality and
|
||||
// relational operators. Added classes for groups of related
|
||||
// operators. Reimplemented example operator and iterator helper
|
||||
// classes in terms of the new groups. (Daryle Walker, with help
|
||||
// from Alexy Gurtovoy)
|
||||
// 11 Feb 01 Fixed bugs in the iterator helpers which prevented explicitly
|
||||
// supplied arguments from actually being used (Dave Abrahams)
|
||||
// 04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
|
||||
// refactoring of compiler workarounds, additional documentation
|
||||
// (Alexy Gurtovoy and Mark Rodgers with some help and prompting from
|
||||
// Dave Abrahams)
|
||||
// 28 Jun 00 General cleanup and integration of bugfixes from Mark Rodgers and
|
||||
// Jeremy Siek (Dave Abrahams)
|
||||
// 20 Jun 00 Changes to accommodate Borland C++Builder 4 and Borland C++ 5.5
|
||||
// (Mark Rodgers)
|
||||
// 20 Jun 00 Minor fixes to the prior revision (Aleksey Gurtovoy)
|
||||
// 10 Jun 00 Support for the base class chaining technique was added
|
||||
// (Aleksey Gurtovoy). See documentation and the comments below
|
||||
// for the details.
|
||||
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
|
||||
// 18 Nov 99 Change name "divideable" to "dividable", remove unnecessary
|
||||
// specializations of dividable, subtractable, modable (Ed Brey)
|
||||
// 17 Nov 99 Add comments (Beman Dawes)
|
||||
// Remove unnecessary specialization of operators<> (Ed Brey)
|
||||
// 15 Nov 99 Fix less_than_comparable<T,U> second operand type for first two
|
||||
// operators.(Beman Dawes)
|
||||
// 12 Nov 99 Add operators templates (Ed Brey)
|
||||
// 11 Nov 99 Add single template parameter version for compilers without
|
||||
// partial specialization (Beman Dawes)
|
||||
// 10 Nov 99 Initial version
|
||||
|
||||
// 10 Jun 00:
|
||||
// An additional optional template parameter was added to most of
|
||||
// operator templates to support the base class chaining technique (see
|
||||
// documentation for the details). Unfortunately, a straightforward
|
||||
// implementation of this change would have broken compatibility with the
|
||||
// previous version of the library by making it impossible to use the same
|
||||
// template name (e.g. 'addable') for both the 1- and 2-argument versions of
|
||||
// an operator template. This implementation solves the backward-compatibility
|
||||
// issue at the cost of some simplicity.
|
||||
//
|
||||
// One of the complications is an existence of special auxiliary class template
|
||||
// 'is_chained_base<>' (see 'operators_detail' namespace below), which is used
|
||||
// to determine whether its template parameter is a library's operator template
|
||||
// or not. You have to specialize 'is_chained_base<>' for each new
|
||||
// operator template you add to the library.
|
||||
//
|
||||
// However, most of the non-trivial implementation details are hidden behind
|
||||
// several local macros defined below, and as soon as you understand them,
|
||||
// you understand the whole library implementation.
|
||||
|
||||
#ifndef BOOST_OPERATORS_HPP
|
||||
#define BOOST_OPERATORS_HPP
|
||||
|
||||
// If old work-arounds are needed, refer to the preserved version without
|
||||
// ADL protection.
|
||||
#if defined(BOOST_NO_OPERATORS_IN_NAMESPACE) || defined(BOOST_USE_OPERATORS_V1)
|
||||
#include "operators_v1.hpp"
|
||||
#else
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#if defined(__sgi) && !defined(__GNUC__)
|
||||
# pragma set woff 1234
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1600)
|
||||
# pragma warning( disable : 4284 ) // complaint about return type of
|
||||
#endif // operator-> not begin a UDT
|
||||
|
||||
// In this section we supply the xxxx1 and xxxx2 forms of the operator
|
||||
// templates, which are explicitly targeted at the 1-type-argument and
|
||||
// 2-type-argument operator forms, respectively.
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace operators_impl
|
||||
{
|
||||
namespace operators_detail
|
||||
{
|
||||
|
||||
template <typename T> class empty_base {};
|
||||
|
||||
} // namespace operators_detail
|
||||
|
||||
// Basic operator classes (contributed by Dave Abrahams) ------------------//
|
||||
|
||||
// Note that friend functions defined in a class are implicitly inline.
|
||||
// See the C++ std, 11.4 [class.friend] paragraph 5
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct less_than_comparable2 : B
|
||||
{
|
||||
friend bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
|
||||
friend bool operator>=(const T& x, const U& y) { return !static_cast<bool>(x < y); }
|
||||
friend bool operator>(const U& x, const T& y) { return y < x; }
|
||||
friend bool operator<(const U& x, const T& y) { return y > x; }
|
||||
friend bool operator<=(const U& x, const T& y) { return !static_cast<bool>(y < x); }
|
||||
friend bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
|
||||
};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct less_than_comparable1 : B
|
||||
{
|
||||
friend bool operator>(const T& x, const T& y) { return y < x; }
|
||||
friend bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); }
|
||||
friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
|
||||
};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct equality_comparable2 : B
|
||||
{
|
||||
friend bool operator==(const U& y, const T& x) { return x == y; }
|
||||
friend bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
|
||||
friend bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
|
||||
};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct equality_comparable1 : B
|
||||
{
|
||||
friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
|
||||
};
|
||||
|
||||
// A macro which produces "name_2left" from "name".
|
||||
#define BOOST_OPERATOR2_LEFT(name) name##2##_##left
|
||||
|
||||
// NRVO-friendly implementation (contributed by Daniel Frey) ---------------//
|
||||
|
||||
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||
|
||||
// This is the optimal implementation for ISO/ANSI C++,
|
||||
// but it requires the compiler to implement the NRVO.
|
||||
// If the compiler has no NRVO, this is the best symmetric
|
||||
// implementation available.
|
||||
|
||||
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||
struct NAME##2 : B \
|
||||
{ \
|
||||
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||
friend T operator OP( const U& lhs, const T& rhs ) \
|
||||
{ T nrv( rhs ); nrv OP##= lhs; return nrv; } \
|
||||
}; \
|
||||
\
|
||||
template <class T, class B = operators_detail::empty_base<T> > \
|
||||
struct NAME##1 : B \
|
||||
{ \
|
||||
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||
};
|
||||
|
||||
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||
struct NAME##2 : B \
|
||||
{ \
|
||||
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||
}; \
|
||||
\
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||
struct BOOST_OPERATOR2_LEFT(NAME) : B \
|
||||
{ \
|
||||
friend T operator OP( const U& lhs, const T& rhs ) \
|
||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||
}; \
|
||||
\
|
||||
template <class T, class B = operators_detail::empty_base<T> > \
|
||||
struct NAME##1 : B \
|
||||
{ \
|
||||
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||
};
|
||||
|
||||
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||
|
||||
// For compilers without NRVO the following code is optimal, but not
|
||||
// symmetric! Note that the implementation of
|
||||
// BOOST_OPERATOR2_LEFT(NAME) only looks cool, but doesn't provide
|
||||
// optimization opportunities to the compiler :)
|
||||
|
||||
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||
struct NAME##2 : B \
|
||||
{ \
|
||||
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||
friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \
|
||||
}; \
|
||||
\
|
||||
template <class T, class B = operators_detail::empty_base<T> > \
|
||||
struct NAME##1 : B \
|
||||
{ \
|
||||
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||
};
|
||||
|
||||
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||
struct NAME##2 : B \
|
||||
{ \
|
||||
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||
}; \
|
||||
\
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||
struct BOOST_OPERATOR2_LEFT(NAME) : B \
|
||||
{ \
|
||||
friend T operator OP( const U& lhs, const T& rhs ) \
|
||||
{ return T( lhs ) OP##= rhs; } \
|
||||
}; \
|
||||
\
|
||||
template <class T, class B = operators_detail::empty_base<T> > \
|
||||
struct NAME##1 : B \
|
||||
{ \
|
||||
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||
};
|
||||
|
||||
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||
|
||||
BOOST_BINARY_OPERATOR_COMMUTATIVE( multipliable, * )
|
||||
BOOST_BINARY_OPERATOR_COMMUTATIVE( addable, + )
|
||||
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( subtractable, - )
|
||||
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( dividable, / )
|
||||
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( modable, % )
|
||||
BOOST_BINARY_OPERATOR_COMMUTATIVE( xorable, ^ )
|
||||
BOOST_BINARY_OPERATOR_COMMUTATIVE( andable, & )
|
||||
BOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | )
|
||||
|
||||
#undef BOOST_BINARY_OPERATOR_COMMUTATIVE
|
||||
#undef BOOST_BINARY_OPERATOR_NON_COMMUTATIVE
|
||||
#undef BOOST_OPERATOR2_LEFT
|
||||
|
||||
// incrementable and decrementable contributed by Jeremy Siek
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct incrementable : B
|
||||
{
|
||||
friend T operator++(T& x, int)
|
||||
{
|
||||
incrementable_type nrv(x);
|
||||
++x;
|
||||
return nrv;
|
||||
}
|
||||
private: // The use of this typedef works around a Borland bug
|
||||
typedef T incrementable_type;
|
||||
};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct decrementable : B
|
||||
{
|
||||
friend T operator--(T& x, int)
|
||||
{
|
||||
decrementable_type nrv(x);
|
||||
--x;
|
||||
return nrv;
|
||||
}
|
||||
private: // The use of this typedef works around a Borland bug
|
||||
typedef T decrementable_type;
|
||||
};
|
||||
|
||||
// Iterator operator classes (contributed by Jeremy Siek) ------------------//
|
||||
|
||||
template <class T, class P, class B = operators_detail::empty_base<T> >
|
||||
struct dereferenceable : B
|
||||
{
|
||||
P operator->() const
|
||||
{
|
||||
return &*static_cast<const T&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class I, class R, class B = operators_detail::empty_base<T> >
|
||||
struct indexable : B
|
||||
{
|
||||
R operator[](I n) const
|
||||
{
|
||||
return *(static_cast<const T&>(*this) + n);
|
||||
}
|
||||
};
|
||||
|
||||
// More operator classes (contributed by Daryle Walker) --------------------//
|
||||
// (NRVO-friendly implementation contributed by Daniel Frey) ---------------//
|
||||
|
||||
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||
|
||||
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||
struct NAME##2 : B \
|
||||
{ \
|
||||
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||
}; \
|
||||
\
|
||||
template <class T, class B = operators_detail::empty_base<T> > \
|
||||
struct NAME##1 : B \
|
||||
{ \
|
||||
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||
};
|
||||
|
||||
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||
|
||||
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||
struct NAME##2 : B \
|
||||
{ \
|
||||
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||
}; \
|
||||
\
|
||||
template <class T, class B = operators_detail::empty_base<T> > \
|
||||
struct NAME##1 : B \
|
||||
{ \
|
||||
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||
};
|
||||
|
||||
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||
|
||||
BOOST_BINARY_OPERATOR( left_shiftable, << )
|
||||
BOOST_BINARY_OPERATOR( right_shiftable, >> )
|
||||
|
||||
#undef BOOST_BINARY_OPERATOR
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct equivalent2 : B
|
||||
{
|
||||
friend bool operator==(const T& x, const U& y)
|
||||
{
|
||||
return !static_cast<bool>(x < y) && !static_cast<bool>(x > y);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct equivalent1 : B
|
||||
{
|
||||
friend bool operator==(const T&x, const T&y)
|
||||
{
|
||||
return !static_cast<bool>(x < y) && !static_cast<bool>(y < x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct partially_ordered2 : B
|
||||
{
|
||||
friend bool operator<=(const T& x, const U& y)
|
||||
{ return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
|
||||
friend bool operator>=(const T& x, const U& y)
|
||||
{ return static_cast<bool>(x > y) || static_cast<bool>(x == y); }
|
||||
friend bool operator>(const U& x, const T& y)
|
||||
{ return y < x; }
|
||||
friend bool operator<(const U& x, const T& y)
|
||||
{ return y > x; }
|
||||
friend bool operator<=(const U& x, const T& y)
|
||||
{ return static_cast<bool>(y > x) || static_cast<bool>(y == x); }
|
||||
friend bool operator>=(const U& x, const T& y)
|
||||
{ return static_cast<bool>(y < x) || static_cast<bool>(y == x); }
|
||||
};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct partially_ordered1 : B
|
||||
{
|
||||
friend bool operator>(const T& x, const T& y)
|
||||
{ return y < x; }
|
||||
friend bool operator<=(const T& x, const T& y)
|
||||
{ return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
|
||||
friend bool operator>=(const T& x, const T& y)
|
||||
{ return static_cast<bool>(y < x) || static_cast<bool>(x == y); }
|
||||
};
|
||||
|
||||
// Combined operator classes (contributed by Daryle Walker) ----------------//
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct totally_ordered2
|
||||
: less_than_comparable2<T, U
|
||||
, equality_comparable2<T, U, B
|
||||
> > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct totally_ordered1
|
||||
: less_than_comparable1<T
|
||||
, equality_comparable1<T, B
|
||||
> > {};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct additive2
|
||||
: addable2<T, U
|
||||
, subtractable2<T, U, B
|
||||
> > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct additive1
|
||||
: addable1<T
|
||||
, subtractable1<T, B
|
||||
> > {};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct multiplicative2
|
||||
: multipliable2<T, U
|
||||
, dividable2<T, U, B
|
||||
> > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct multiplicative1
|
||||
: multipliable1<T
|
||||
, dividable1<T, B
|
||||
> > {};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct integer_multiplicative2
|
||||
: multiplicative2<T, U
|
||||
, modable2<T, U, B
|
||||
> > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct integer_multiplicative1
|
||||
: multiplicative1<T
|
||||
, modable1<T, B
|
||||
> > {};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct arithmetic2
|
||||
: additive2<T, U
|
||||
, multiplicative2<T, U, B
|
||||
> > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct arithmetic1
|
||||
: additive1<T
|
||||
, multiplicative1<T, B
|
||||
> > {};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct integer_arithmetic2
|
||||
: additive2<T, U
|
||||
, integer_multiplicative2<T, U, B
|
||||
> > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct integer_arithmetic1
|
||||
: additive1<T
|
||||
, integer_multiplicative1<T, B
|
||||
> > {};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct bitwise2
|
||||
: xorable2<T, U
|
||||
, andable2<T, U
|
||||
, orable2<T, U, B
|
||||
> > > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct bitwise1
|
||||
: xorable1<T
|
||||
, andable1<T
|
||||
, orable1<T, B
|
||||
> > > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct unit_steppable
|
||||
: incrementable<T
|
||||
, decrementable<T, B
|
||||
> > {};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct shiftable2
|
||||
: left_shiftable2<T, U
|
||||
, right_shiftable2<T, U, B
|
||||
> > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct shiftable1
|
||||
: left_shiftable1<T
|
||||
, right_shiftable1<T, B
|
||||
> > {};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct ring_operators2
|
||||
: additive2<T, U
|
||||
, subtractable2_left<T, U
|
||||
, multipliable2<T, U, B
|
||||
> > > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct ring_operators1
|
||||
: additive1<T
|
||||
, multipliable1<T, B
|
||||
> > {};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct ordered_ring_operators2
|
||||
: ring_operators2<T, U
|
||||
, totally_ordered2<T, U, B
|
||||
> > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct ordered_ring_operators1
|
||||
: ring_operators1<T
|
||||
, totally_ordered1<T, B
|
||||
> > {};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct field_operators2
|
||||
: ring_operators2<T, U
|
||||
, dividable2<T, U
|
||||
, dividable2_left<T, U, B
|
||||
> > > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct field_operators1
|
||||
: ring_operators1<T
|
||||
, dividable1<T, B
|
||||
> > {};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct ordered_field_operators2
|
||||
: field_operators2<T, U
|
||||
, totally_ordered2<T, U, B
|
||||
> > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct ordered_field_operators1
|
||||
: field_operators1<T
|
||||
, totally_ordered1<T, B
|
||||
> > {};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct euclidian_ring_operators2
|
||||
: ring_operators2<T, U
|
||||
, dividable2<T, U
|
||||
, dividable2_left<T, U
|
||||
, modable2<T, U
|
||||
, modable2_left<T, U, B
|
||||
> > > > > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct euclidian_ring_operators1
|
||||
: ring_operators1<T
|
||||
, dividable1<T
|
||||
, modable1<T, B
|
||||
> > > {};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct ordered_euclidian_ring_operators2
|
||||
: totally_ordered2<T, U
|
||||
, euclidian_ring_operators2<T, U, B
|
||||
> > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct ordered_euclidian_ring_operators1
|
||||
: totally_ordered1<T
|
||||
, euclidian_ring_operators1<T, B
|
||||
> > {};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct euclidean_ring_operators2
|
||||
: ring_operators2<T, U
|
||||
, dividable2<T, U
|
||||
, dividable2_left<T, U
|
||||
, modable2<T, U
|
||||
, modable2_left<T, U, B
|
||||
> > > > > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct euclidean_ring_operators1
|
||||
: ring_operators1<T
|
||||
, dividable1<T
|
||||
, modable1<T, B
|
||||
> > > {};
|
||||
|
||||
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||
struct ordered_euclidean_ring_operators2
|
||||
: totally_ordered2<T, U
|
||||
, euclidean_ring_operators2<T, U, B
|
||||
> > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct ordered_euclidean_ring_operators1
|
||||
: totally_ordered1<T
|
||||
, euclidean_ring_operators1<T, B
|
||||
> > {};
|
||||
|
||||
template <class T, class P, class B = operators_detail::empty_base<T> >
|
||||
struct input_iteratable
|
||||
: equality_comparable1<T
|
||||
, incrementable<T
|
||||
, dereferenceable<T, P, B
|
||||
> > > {};
|
||||
|
||||
template <class T, class B = operators_detail::empty_base<T> >
|
||||
struct output_iteratable
|
||||
: incrementable<T, B
|
||||
> {};
|
||||
|
||||
template <class T, class P, class B = operators_detail::empty_base<T> >
|
||||
struct forward_iteratable
|
||||
: input_iteratable<T, P, B
|
||||
> {};
|
||||
|
||||
template <class T, class P, class B = operators_detail::empty_base<T> >
|
||||
struct bidirectional_iteratable
|
||||
: forward_iteratable<T, P
|
||||
, decrementable<T, B
|
||||
> > {};
|
||||
|
||||
// To avoid repeated derivation from equality_comparable,
|
||||
// which is an indirect base class of bidirectional_iterable,
|
||||
// random_access_iteratable must not be derived from totally_ordered1
|
||||
// but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
|
||||
template <class T, class P, class D, class R, class B = operators_detail::empty_base<T> >
|
||||
struct random_access_iteratable
|
||||
: bidirectional_iteratable<T, P
|
||||
, less_than_comparable1<T
|
||||
, additive2<T, D
|
||||
, indexable<T, D, R, B
|
||||
> > > > {};
|
||||
|
||||
|
||||
//
|
||||
// Here's where we put it all together, defining the xxxx forms of the templates.
|
||||
// We also define specializations of is_chained_base<> for
|
||||
// the xxxx, xxxx1, and xxxx2 templates.
|
||||
//
|
||||
|
||||
namespace operators_detail
|
||||
{
|
||||
|
||||
// A type parameter is used instead of a plain bool because Borland's compiler
|
||||
// didn't cope well with the more obvious non-type template parameter.
|
||||
struct true_t {};
|
||||
struct false_t {};
|
||||
|
||||
} // namespace operators_detail
|
||||
|
||||
// is_chained_base<> - a traits class used to distinguish whether an operator
|
||||
// template argument is being used for base class chaining, or is specifying a
|
||||
// 2nd argument type.
|
||||
|
||||
// Unspecialized version assumes that most types are not being used for base
|
||||
// class chaining. We specialize for the operator templates defined in this
|
||||
// library.
|
||||
template<class T> struct is_chained_base {
|
||||
typedef operators_detail::false_t value;
|
||||
};
|
||||
|
||||
// Provide a specialization of 'is_chained_base<>'
|
||||
// for a 4-type-argument operator template.
|
||||
# define BOOST_OPERATOR_TEMPLATE4(template_name4) \
|
||||
template<class T, class U, class V, class W, class B> \
|
||||
struct is_chained_base< template_name4<T, U, V, W, B> > { \
|
||||
typedef operators_detail::true_t value; \
|
||||
};
|
||||
|
||||
// Provide a specialization of 'is_chained_base<>'
|
||||
// for a 3-type-argument operator template.
|
||||
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
|
||||
template<class T, class U, class V, class B> \
|
||||
struct is_chained_base< template_name3<T, U, V, B> > { \
|
||||
typedef operators_detail::true_t value; \
|
||||
};
|
||||
|
||||
// Provide a specialization of 'is_chained_base<>'
|
||||
// for a 2-type-argument operator template.
|
||||
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
||||
template<class T, class U, class B> \
|
||||
struct is_chained_base< template_name2<T, U, B> > { \
|
||||
typedef operators_detail::true_t value; \
|
||||
};
|
||||
|
||||
// Provide a specialization of 'is_chained_base<>'
|
||||
// for a 1-type-argument operator template.
|
||||
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
|
||||
template<class T, class B> \
|
||||
struct is_chained_base< template_name1<T, B> > { \
|
||||
typedef operators_detail::true_t value; \
|
||||
};
|
||||
|
||||
// BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
|
||||
// can be used for specifying both 1-argument and 2-argument forms. Requires the
|
||||
// existence of two previously defined class templates named '<template_name>1'
|
||||
// and '<template_name>2' which must implement the corresponding 1- and 2-
|
||||
// argument forms.
|
||||
//
|
||||
// The template type parameter O == is_chained_base<U>::value is used to
|
||||
// distinguish whether the 2nd argument to <template_name> is being used for
|
||||
// base class chaining from another boost operator template or is describing a
|
||||
// 2nd operand type. O == true_t only when U is actually an another operator
|
||||
// template from the library. Partial specialization is used to select an
|
||||
// implementation in terms of either '<template_name>1' or '<template_name>2'.
|
||||
//
|
||||
|
||||
# define BOOST_OPERATOR_TEMPLATE(template_name) \
|
||||
template <class T \
|
||||
,class U = T \
|
||||
,class B = operators_detail::empty_base<T> \
|
||||
,class O = typename is_chained_base<U>::value \
|
||||
> \
|
||||
struct template_name; \
|
||||
\
|
||||
template<class T, class U, class B> \
|
||||
struct template_name<T, U, B, operators_detail::false_t> \
|
||||
: template_name##2<T, U, B> {}; \
|
||||
\
|
||||
template<class T, class U> \
|
||||
struct template_name<T, U, operators_detail::empty_base<T>, operators_detail::true_t> \
|
||||
: template_name##1<T, U> {}; \
|
||||
\
|
||||
template <class T, class B> \
|
||||
struct template_name<T, T, B, operators_detail::false_t> \
|
||||
: template_name##1<T, B> {}; \
|
||||
\
|
||||
template<class T, class U, class B, class O> \
|
||||
struct is_chained_base< template_name<T, U, B, O> > { \
|
||||
typedef operators_detail::true_t value; \
|
||||
}; \
|
||||
\
|
||||
BOOST_OPERATOR_TEMPLATE2(template_name##2) \
|
||||
BOOST_OPERATOR_TEMPLATE1(template_name##1)
|
||||
|
||||
BOOST_OPERATOR_TEMPLATE(less_than_comparable)
|
||||
BOOST_OPERATOR_TEMPLATE(equality_comparable)
|
||||
BOOST_OPERATOR_TEMPLATE(multipliable)
|
||||
BOOST_OPERATOR_TEMPLATE(addable)
|
||||
BOOST_OPERATOR_TEMPLATE(subtractable)
|
||||
BOOST_OPERATOR_TEMPLATE2(subtractable2_left)
|
||||
BOOST_OPERATOR_TEMPLATE(dividable)
|
||||
BOOST_OPERATOR_TEMPLATE2(dividable2_left)
|
||||
BOOST_OPERATOR_TEMPLATE(modable)
|
||||
BOOST_OPERATOR_TEMPLATE2(modable2_left)
|
||||
BOOST_OPERATOR_TEMPLATE(xorable)
|
||||
BOOST_OPERATOR_TEMPLATE(andable)
|
||||
BOOST_OPERATOR_TEMPLATE(orable)
|
||||
|
||||
BOOST_OPERATOR_TEMPLATE1(incrementable)
|
||||
BOOST_OPERATOR_TEMPLATE1(decrementable)
|
||||
|
||||
BOOST_OPERATOR_TEMPLATE2(dereferenceable)
|
||||
BOOST_OPERATOR_TEMPLATE3(indexable)
|
||||
|
||||
BOOST_OPERATOR_TEMPLATE(left_shiftable)
|
||||
BOOST_OPERATOR_TEMPLATE(right_shiftable)
|
||||
BOOST_OPERATOR_TEMPLATE(equivalent)
|
||||
BOOST_OPERATOR_TEMPLATE(partially_ordered)
|
||||
|
||||
BOOST_OPERATOR_TEMPLATE(totally_ordered)
|
||||
BOOST_OPERATOR_TEMPLATE(additive)
|
||||
BOOST_OPERATOR_TEMPLATE(multiplicative)
|
||||
BOOST_OPERATOR_TEMPLATE(integer_multiplicative)
|
||||
BOOST_OPERATOR_TEMPLATE(arithmetic)
|
||||
BOOST_OPERATOR_TEMPLATE(integer_arithmetic)
|
||||
BOOST_OPERATOR_TEMPLATE(bitwise)
|
||||
BOOST_OPERATOR_TEMPLATE1(unit_steppable)
|
||||
BOOST_OPERATOR_TEMPLATE(shiftable)
|
||||
BOOST_OPERATOR_TEMPLATE(ring_operators)
|
||||
BOOST_OPERATOR_TEMPLATE(ordered_ring_operators)
|
||||
BOOST_OPERATOR_TEMPLATE(field_operators)
|
||||
BOOST_OPERATOR_TEMPLATE(ordered_field_operators)
|
||||
BOOST_OPERATOR_TEMPLATE(euclidian_ring_operators)
|
||||
BOOST_OPERATOR_TEMPLATE(ordered_euclidian_ring_operators)
|
||||
BOOST_OPERATOR_TEMPLATE(euclidean_ring_operators)
|
||||
BOOST_OPERATOR_TEMPLATE(ordered_euclidean_ring_operators)
|
||||
BOOST_OPERATOR_TEMPLATE2(input_iteratable)
|
||||
BOOST_OPERATOR_TEMPLATE1(output_iteratable)
|
||||
BOOST_OPERATOR_TEMPLATE2(forward_iteratable)
|
||||
BOOST_OPERATOR_TEMPLATE2(bidirectional_iteratable)
|
||||
BOOST_OPERATOR_TEMPLATE4(random_access_iteratable)
|
||||
|
||||
#undef BOOST_OPERATOR_TEMPLATE
|
||||
#undef BOOST_OPERATOR_TEMPLATE4
|
||||
#undef BOOST_OPERATOR_TEMPLATE3
|
||||
#undef BOOST_OPERATOR_TEMPLATE2
|
||||
#undef BOOST_OPERATOR_TEMPLATE1
|
||||
|
||||
template <class T, class U>
|
||||
struct operators2
|
||||
: totally_ordered2<T,U
|
||||
, integer_arithmetic2<T,U
|
||||
, bitwise2<T,U
|
||||
> > > {};
|
||||
|
||||
template <class T, class U = T>
|
||||
struct operators : operators2<T, U> {};
|
||||
|
||||
template <class T> struct operators<T, T>
|
||||
: totally_ordered<T
|
||||
, integer_arithmetic<T
|
||||
, bitwise<T
|
||||
, unit_steppable<T
|
||||
> > > > {};
|
||||
|
||||
// Iterator helper classes (contributed by Jeremy Siek) -------------------//
|
||||
// (Input and output iterator helpers contributed by Daryle Walker) -------//
|
||||
// (Changed to use combined operator classes by Daryle Walker) ------------//
|
||||
template <class T,
|
||||
class V,
|
||||
class D = std::ptrdiff_t,
|
||||
class P = V const *,
|
||||
class R = V const &>
|
||||
struct input_iterator_helper
|
||||
: input_iteratable<T, P
|
||||
, std::iterator<std::input_iterator_tag, V, D, P, R
|
||||
> > {};
|
||||
|
||||
template<class T>
|
||||
struct output_iterator_helper
|
||||
: output_iteratable<T
|
||||
, std::iterator<std::output_iterator_tag, void, void, void, void
|
||||
> >
|
||||
{
|
||||
T& operator*() { return static_cast<T&>(*this); }
|
||||
T& operator++() { return static_cast<T&>(*this); }
|
||||
};
|
||||
|
||||
template <class T,
|
||||
class V,
|
||||
class D = std::ptrdiff_t,
|
||||
class P = V*,
|
||||
class R = V&>
|
||||
struct forward_iterator_helper
|
||||
: forward_iteratable<T, P
|
||||
, std::iterator<std::forward_iterator_tag, V, D, P, R
|
||||
> > {};
|
||||
|
||||
template <class T,
|
||||
class V,
|
||||
class D = std::ptrdiff_t,
|
||||
class P = V*,
|
||||
class R = V&>
|
||||
struct bidirectional_iterator_helper
|
||||
: bidirectional_iteratable<T, P
|
||||
, std::iterator<std::bidirectional_iterator_tag, V, D, P, R
|
||||
> > {};
|
||||
|
||||
template <class T,
|
||||
class V,
|
||||
class D = std::ptrdiff_t,
|
||||
class P = V*,
|
||||
class R = V&>
|
||||
struct random_access_iterator_helper
|
||||
: random_access_iteratable<T, P, D, R
|
||||
, std::iterator<std::random_access_iterator_tag, V, D, P, R
|
||||
> >
|
||||
{
|
||||
friend D requires_difference_operator(const T& x, const T& y) {
|
||||
return x - y;
|
||||
}
|
||||
}; // random_access_iterator_helper
|
||||
|
||||
} // namespace operators_impl
|
||||
using namespace operators_impl;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined(__sgi) && !defined(__GNUC__)
|
||||
#pragma reset woff 1234
|
||||
#endif
|
||||
|
||||
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
#endif // BOOST_OPERATORS_HPP
|
||||
@@ -0,0 +1,90 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-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)
|
||||
//
|
||||
// See http://www.boost.org/libs/intrusive for documentation.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTRUSIVE_DETAIL_EXCEPTION_DISPOSER_HPP
|
||||
#define BOOST_INTRUSIVE_DETAIL_EXCEPTION_DISPOSER_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/intrusive/detail/workaround.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace intrusive {
|
||||
namespace detail {
|
||||
|
||||
template<class Container, class Disposer>
|
||||
class exception_disposer
|
||||
{
|
||||
Container *cont_;
|
||||
Disposer &disp_;
|
||||
|
||||
exception_disposer(const exception_disposer&);
|
||||
exception_disposer &operator=(const exception_disposer&);
|
||||
|
||||
public:
|
||||
exception_disposer(Container &cont, Disposer &disp)
|
||||
: cont_(&cont), disp_(disp)
|
||||
{}
|
||||
|
||||
BOOST_INTRUSIVE_FORCEINLINE void release()
|
||||
{ cont_ = 0; }
|
||||
|
||||
~exception_disposer()
|
||||
{
|
||||
if(cont_){
|
||||
cont_->clear_and_dispose(disp_);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<class Container, class Disposer, class SizeType>
|
||||
class exception_array_disposer
|
||||
{
|
||||
Container *cont_;
|
||||
Disposer &disp_;
|
||||
SizeType &constructed_;
|
||||
|
||||
exception_array_disposer(const exception_array_disposer&);
|
||||
exception_array_disposer &operator=(const exception_array_disposer&);
|
||||
|
||||
public:
|
||||
|
||||
exception_array_disposer
|
||||
(Container &cont, Disposer &disp, SizeType &constructed)
|
||||
: cont_(&cont), disp_(disp), constructed_(constructed)
|
||||
{}
|
||||
|
||||
BOOST_INTRUSIVE_FORCEINLINE void release()
|
||||
{ cont_ = 0; }
|
||||
|
||||
~exception_array_disposer()
|
||||
{
|
||||
SizeType n = constructed_;
|
||||
if(cont_){
|
||||
while(n--){
|
||||
cont_[n].clear_and_dispose(disp_);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace intrusive{
|
||||
} //namespace boost{
|
||||
|
||||
#endif //BOOST_INTRUSIVE_DETAIL_EXCEPTION_DISPOSER_HPP
|
||||
@@ -0,0 +1,156 @@
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-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)
|
||||
//
|
||||
|
||||
// Preprocessed version of "boost/mpl/minus.hpp" header
|
||||
// -- DO NOT modify by hand!
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
template<
|
||||
typename Tag1
|
||||
, typename Tag2
|
||||
>
|
||||
struct minus_impl
|
||||
: if_c<
|
||||
( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1)
|
||||
> BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2)
|
||||
)
|
||||
|
||||
, aux::cast2nd_impl< minus_impl< Tag1,Tag1 >,Tag1, Tag2 >
|
||||
, aux::cast1st_impl< minus_impl< Tag2,Tag2 >,Tag1, Tag2 >
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
/// for Digital Mars C++/compilers with no CTPS/TTP support
|
||||
template<> struct minus_impl< na,na >
|
||||
{
|
||||
template< typename U1, typename U2 > struct apply
|
||||
{
|
||||
typedef apply type;
|
||||
BOOST_STATIC_CONSTANT(int, value = 0);
|
||||
};
|
||||
};
|
||||
|
||||
template< typename Tag > struct minus_impl< na,Tag >
|
||||
{
|
||||
template< typename U1, typename U2 > struct apply
|
||||
{
|
||||
typedef apply type;
|
||||
BOOST_STATIC_CONSTANT(int, value = 0);
|
||||
};
|
||||
};
|
||||
|
||||
template< typename Tag > struct minus_impl< Tag,na >
|
||||
{
|
||||
template< typename U1, typename U2 > struct apply
|
||||
{
|
||||
typedef apply type;
|
||||
BOOST_STATIC_CONSTANT(int, value = 0);
|
||||
};
|
||||
};
|
||||
|
||||
template< typename T > struct minus_tag
|
||||
{
|
||||
typedef typename T::tag type;
|
||||
};
|
||||
|
||||
template<
|
||||
typename BOOST_MPL_AUX_NA_PARAM(N1)
|
||||
, typename BOOST_MPL_AUX_NA_PARAM(N2)
|
||||
, typename N3 = na, typename N4 = na, typename N5 = na
|
||||
>
|
||||
struct minus
|
||||
: minus< minus< minus< minus< N1,N2 >, N3>, N4>, N5>
|
||||
{
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(
|
||||
5
|
||||
, minus
|
||||
, ( N1, N2, N3, N4, N5 )
|
||||
)
|
||||
};
|
||||
|
||||
template<
|
||||
typename N1, typename N2, typename N3, typename N4
|
||||
>
|
||||
struct minus< N1,N2,N3,N4,na >
|
||||
|
||||
: minus< minus< minus< N1,N2 >, N3>, N4>
|
||||
{
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(
|
||||
5
|
||||
, minus
|
||||
, ( N1, N2, N3, N4, na )
|
||||
)
|
||||
};
|
||||
|
||||
template<
|
||||
typename N1, typename N2, typename N3
|
||||
>
|
||||
struct minus< N1,N2,N3,na,na >
|
||||
|
||||
: minus< minus< N1,N2 >, N3>
|
||||
{
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(
|
||||
5
|
||||
, minus
|
||||
, ( N1, N2, N3, na, na )
|
||||
)
|
||||
};
|
||||
|
||||
template<
|
||||
typename N1, typename N2
|
||||
>
|
||||
struct minus< N1,N2,na,na,na >
|
||||
: minus_impl<
|
||||
typename minus_tag<N1>::type
|
||||
, typename minus_tag<N2>::type
|
||||
>::template apply< N1,N2 >::type
|
||||
{
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(
|
||||
5
|
||||
, minus
|
||||
, ( N1, N2, na, na, na )
|
||||
)
|
||||
|
||||
};
|
||||
|
||||
BOOST_MPL_AUX_NA_SPEC2(2, 5, minus)
|
||||
|
||||
}}
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
namespace aux {
|
||||
template< typename T, T n1, T n2 >
|
||||
struct minus_wknd
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(T, value = (n1 - n2));
|
||||
typedef integral_c< T,value > type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<>
|
||||
struct minus_impl< integral_c_tag,integral_c_tag >
|
||||
{
|
||||
template< typename N1, typename N2 > struct apply
|
||||
: aux::minus_wknd<
|
||||
typename aux::largest_int<
|
||||
typename N1::value_type
|
||||
, typename N2::value_type
|
||||
>::type
|
||||
, N1::value
|
||||
, N2::value
|
||||
>::type
|
||||
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,167 @@
|
||||
#ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
|
||||
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||
// Copyright (c) 2001, 2002 Peter Dimov
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
# include <memory> // for std::auto_ptr
|
||||
#endif
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// Debug hooks
|
||||
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
|
||||
void sp_scalar_constructor_hook(void * p);
|
||||
void sp_scalar_destructor_hook(void * p);
|
||||
|
||||
#endif
|
||||
|
||||
// scoped_ptr mimics a built-in pointer except that it guarantees deletion
|
||||
// of the object pointed to, either on destruction of the scoped_ptr or via
|
||||
// an explicit reset(). scoped_ptr is a simple solution for simple needs;
|
||||
// use shared_ptr or std::auto_ptr if your needs are more complex.
|
||||
|
||||
template<class T> class scoped_ptr // noncopyable
|
||||
{
|
||||
private:
|
||||
|
||||
T * px;
|
||||
|
||||
scoped_ptr(scoped_ptr const &);
|
||||
scoped_ptr & operator=(scoped_ptr const &);
|
||||
|
||||
typedef scoped_ptr<T> this_type;
|
||||
|
||||
void operator==( scoped_ptr const& ) const;
|
||||
void operator!=( scoped_ptr const& ) const;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
explicit scoped_ptr( T * p = 0 ): px( p ) // never throws
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_scalar_constructor_hook( px );
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
|
||||
explicit scoped_ptr( std::auto_ptr<T> p ) BOOST_NOEXCEPT : px( p.release() )
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_scalar_constructor_hook( px );
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
~scoped_ptr() // never throws
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_scalar_destructor_hook( px );
|
||||
#endif
|
||||
boost::checked_delete( px );
|
||||
}
|
||||
|
||||
void reset(T * p = 0) // never throws
|
||||
{
|
||||
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
|
||||
this_type(p).swap(*this);
|
||||
}
|
||||
|
||||
T & operator*() const // never throws
|
||||
{
|
||||
BOOST_ASSERT( px != 0 );
|
||||
return *px;
|
||||
}
|
||||
|
||||
T * operator->() const // never throws
|
||||
{
|
||||
BOOST_ASSERT( px != 0 );
|
||||
return px;
|
||||
}
|
||||
|
||||
T * get() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px;
|
||||
}
|
||||
|
||||
// implicit conversion to "bool"
|
||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
||||
|
||||
void swap(scoped_ptr & b) BOOST_NOEXCEPT
|
||||
{
|
||||
T * tmp = b.px;
|
||||
b.px = px;
|
||||
px = tmp;
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
template<class T> inline bool operator==( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) BOOST_NOEXCEPT
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
// get_pointer(p) is a generic way to say p.get()
|
||||
|
||||
template<class T> inline T * get_pointer(scoped_ptr<T> const & p) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get();
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright 2004 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
|
||||
|
||||
//
|
||||
// This file contains helps that enable concept-based overloading
|
||||
// within the Boost Graph Library.
|
||||
//
|
||||
#ifndef BOOST_GRAPH_OVERLOADING_HPP
|
||||
#define BOOST_GRAPH_OVERLOADING_HPP
|
||||
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
namespace boost { namespace graph { namespace detail {
|
||||
|
||||
struct no_parameter {};
|
||||
|
||||
} } } // end namespace boost::graph::detail
|
||||
|
||||
#ifndef BOOST_NO_SFINAE
|
||||
|
||||
#define BOOST_GRAPH_ENABLE_IF_MODELS(Graph, Tag, Type) \
|
||||
typename enable_if_c<(is_base_and_derived< \
|
||||
Tag, \
|
||||
typename graph_traits<Graph>::traversal_category>::value), \
|
||||
Type>::type
|
||||
|
||||
#define BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph, Tag) \
|
||||
, BOOST_GRAPH_ENABLE_IF_MODELS(Graph, Tag, \
|
||||
::boost::graph::detail::no_parameter) \
|
||||
= ::boost::graph::detail::no_parameter()
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_GRAPH_ENABLE_IF_MODELS(Graph, Tag, Type) Type
|
||||
#define BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph, Tag)
|
||||
|
||||
#endif // no SFINAE support
|
||||
|
||||
#endif // BOOST_GRAPH_OVERLOADING_HPP
|
||||
@@ -0,0 +1,39 @@
|
||||
# /* Copyright (C) 2001
|
||||
# * Housemarque Oy
|
||||
# * http://www.housemarque.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)
|
||||
# */
|
||||
#
|
||||
# /* Revised by Paul Mensonides (2002) */
|
||||
#
|
||||
# /* See http://www.boost.org for most recent version. */
|
||||
#
|
||||
# ifndef BOOST_PREPROCESSOR_LIST_AT_HPP
|
||||
# define BOOST_PREPROCESSOR_LIST_AT_HPP
|
||||
#
|
||||
# include <boost/preprocessor/config/config.hpp>
|
||||
# include <boost/preprocessor/list/adt.hpp>
|
||||
# include <boost/preprocessor/list/rest_n.hpp>
|
||||
#
|
||||
# /* BOOST_PP_LIST_AT */
|
||||
#
|
||||
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
|
||||
# define BOOST_PP_LIST_AT(list, index) BOOST_PP_LIST_FIRST(BOOST_PP_LIST_REST_N(index, list))
|
||||
# else
|
||||
# define BOOST_PP_LIST_AT(list, index) BOOST_PP_LIST_AT_I(list, index)
|
||||
# define BOOST_PP_LIST_AT_I(list, index) BOOST_PP_LIST_FIRST(BOOST_PP_LIST_REST_N(index, list))
|
||||
# endif
|
||||
#
|
||||
# /* BOOST_PP_LIST_AT_D */
|
||||
#
|
||||
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
|
||||
# define BOOST_PP_LIST_AT_D(d, list, index) BOOST_PP_LIST_FIRST(BOOST_PP_LIST_REST_N_D(d, index, list))
|
||||
# else
|
||||
# define BOOST_PP_LIST_AT_D(d, list, index) BOOST_PP_LIST_AT_D_I(d, list, index)
|
||||
# define BOOST_PP_LIST_AT_D_I(d, list, index) BOOST_PP_LIST_FIRST(BOOST_PP_LIST_REST_N_D(d, index, list))
|
||||
# endif
|
||||
#
|
||||
# endif
|
||||
@@ -0,0 +1,36 @@
|
||||
// Boost string_algo library constants.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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 updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_CONSTANTS_HPP
|
||||
#define BOOST_STRING_CONSTANTS_HPP
|
||||
|
||||
namespace boost {
|
||||
namespace algorithm {
|
||||
|
||||
//! Token compression mode
|
||||
/*!
|
||||
Specifies token compression mode for the token_finder.
|
||||
*/
|
||||
enum token_compress_mode_type
|
||||
{
|
||||
token_compress_on, //!< Compress adjacent tokens
|
||||
token_compress_off //!< Do not compress adjacent tokens
|
||||
};
|
||||
|
||||
} // namespace algorithm
|
||||
|
||||
// pull the names to the boost namespace
|
||||
using algorithm::token_compress_on;
|
||||
using algorithm::token_compress_off;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_STRING_CONSTANTS_HPP
|
||||
|
||||
@@ -0,0 +1,360 @@
|
||||
// Copyright Neil Groves 2009. 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_ALGORITHM_SEARCH_N_HPP_INCLUDED
|
||||
#define BOOST_RANGE_ALGORITHM_SEARCH_N_HPP_INCLUDED
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/concepts.hpp>
|
||||
#include <boost/range/detail/range_return.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace range_detail
|
||||
{
|
||||
// Rationale: search_n is implemented rather than delegate to
|
||||
// the standard library implementation because some standard
|
||||
// library implementations are broken eg. MSVC.
|
||||
|
||||
// search_n forward iterator version
|
||||
template<typename ForwardIterator, typename Integer, typename Value>
|
||||
inline ForwardIterator
|
||||
search_n_impl(ForwardIterator first, ForwardIterator last, Integer count,
|
||||
const Value& value, std::forward_iterator_tag)
|
||||
{
|
||||
first = std::find(first, last, value);
|
||||
while (first != last)
|
||||
{
|
||||
typename std::iterator_traits<ForwardIterator>::difference_type n = count;
|
||||
ForwardIterator i = first;
|
||||
++i;
|
||||
while (i != last && n != 1 && *i==value)
|
||||
{
|
||||
++i;
|
||||
--n;
|
||||
}
|
||||
if (n == 1)
|
||||
return first;
|
||||
if (i == last)
|
||||
return last;
|
||||
first = std::find(++i, last, value);
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
// search_n random-access iterator version
|
||||
template<typename RandomAccessIterator, typename Integer, typename Value>
|
||||
inline RandomAccessIterator
|
||||
search_n_impl(RandomAccessIterator first, RandomAccessIterator last,
|
||||
Integer count, const Value& value,
|
||||
std::random_access_iterator_tag)
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_t;
|
||||
|
||||
difference_t tail_size = last - first;
|
||||
const difference_t pattern_size = count;
|
||||
|
||||
if (tail_size < pattern_size)
|
||||
return last;
|
||||
|
||||
const difference_t skip_offset = pattern_size - 1;
|
||||
RandomAccessIterator look_ahead = first + skip_offset;
|
||||
tail_size -= pattern_size;
|
||||
|
||||
while (1)
|
||||
{
|
||||
// look_ahead here is pointing to the last element of the
|
||||
// next possible match
|
||||
while (!(*look_ahead == value)) // skip loop...
|
||||
{
|
||||
if (tail_size < pattern_size)
|
||||
return last; // no match
|
||||
look_ahead += pattern_size;
|
||||
tail_size -= pattern_size;
|
||||
}
|
||||
difference_t remainder = skip_offset;
|
||||
for (RandomAccessIterator back_track = look_ahead - 1;
|
||||
*back_track == value; --back_track)
|
||||
{
|
||||
if (--remainder == 0)
|
||||
{
|
||||
return look_ahead - skip_offset; // matched
|
||||
}
|
||||
}
|
||||
if (remainder > tail_size)
|
||||
return last; // no match
|
||||
look_ahead += remainder;
|
||||
tail_size -= remainder;
|
||||
}
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
// search_n for forward iterators using a binary predicate
|
||||
// to determine a match
|
||||
template<typename ForwardIterator, typename Integer, typename Value,
|
||||
typename BinaryPredicate>
|
||||
inline ForwardIterator
|
||||
search_n_pred_impl(ForwardIterator first, ForwardIterator last,
|
||||
Integer count, const Value& value,
|
||||
BinaryPredicate pred, std::forward_iterator_tag)
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIterator>::difference_type difference_t;
|
||||
|
||||
while (first != last && !static_cast<bool>(pred(*first, value)))
|
||||
++first;
|
||||
|
||||
while (first != last)
|
||||
{
|
||||
difference_t n = count;
|
||||
ForwardIterator i = first;
|
||||
++i;
|
||||
while (i != last && n != 1 && static_cast<bool>(pred(*i, value)))
|
||||
{
|
||||
++i;
|
||||
--n;
|
||||
}
|
||||
if (n == 1)
|
||||
return first;
|
||||
if (i == last)
|
||||
return last;
|
||||
first = ++i;
|
||||
while (first != last && !static_cast<bool>(pred(*first, value)))
|
||||
++first;
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
// search_n for random-access iterators using a binary predicate
|
||||
// to determine a match
|
||||
template<typename RandomAccessIterator, typename Integer,
|
||||
typename Value, typename BinaryPredicate>
|
||||
inline RandomAccessIterator
|
||||
search_n_pred_impl(RandomAccessIterator first, RandomAccessIterator last,
|
||||
Integer count, const Value& value,
|
||||
BinaryPredicate pred, std::random_access_iterator_tag)
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_t;
|
||||
|
||||
difference_t tail_size = last - first;
|
||||
const difference_t pattern_size = count;
|
||||
|
||||
if (tail_size < pattern_size)
|
||||
return last;
|
||||
|
||||
const difference_t skip_offset = pattern_size - 1;
|
||||
RandomAccessIterator look_ahead = first + skip_offset;
|
||||
tail_size -= pattern_size;
|
||||
|
||||
while (1)
|
||||
{
|
||||
// look_ahead points to the last element of the next
|
||||
// possible match
|
||||
while (!static_cast<bool>(pred(*look_ahead, value))) // skip loop
|
||||
{
|
||||
if (tail_size < pattern_size)
|
||||
return last; // no match
|
||||
look_ahead += pattern_size;
|
||||
tail_size -= pattern_size;
|
||||
}
|
||||
difference_t remainder = skip_offset;
|
||||
for (RandomAccessIterator back_track = look_ahead - 1;
|
||||
pred(*back_track, value); --back_track)
|
||||
{
|
||||
if (--remainder == 0)
|
||||
return look_ahead -= skip_offset; // success
|
||||
}
|
||||
if (remainder > tail_size)
|
||||
{
|
||||
return last; // no match
|
||||
}
|
||||
look_ahead += remainder;
|
||||
tail_size -= remainder;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ForwardIterator, typename Integer, typename Value>
|
||||
inline ForwardIterator
|
||||
search_n_impl(ForwardIterator first, ForwardIterator last,
|
||||
Integer count, const Value& value)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardIteratorConcept<ForwardIterator>));
|
||||
BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept<Value>));
|
||||
BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept<typename std::iterator_traits<ForwardIterator>::value_type>));
|
||||
//BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept2<typename std::iterator_traits<ForwardIterator>::value_type, Value>));
|
||||
|
||||
typedef typename std::iterator_traits<ForwardIterator>::iterator_category cat_t;
|
||||
|
||||
if (count <= 0)
|
||||
return first;
|
||||
if (count == 1)
|
||||
return std::find(first, last, value);
|
||||
return range_detail::search_n_impl(first, last, count, value, cat_t());
|
||||
}
|
||||
|
||||
template<typename ForwardIterator, typename Integer, typename Value,
|
||||
typename BinaryPredicate>
|
||||
inline ForwardIterator
|
||||
search_n_pred_impl(ForwardIterator first, ForwardIterator last,
|
||||
Integer count, const Value& value,
|
||||
BinaryPredicate pred)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardIteratorConcept<ForwardIterator>));
|
||||
BOOST_RANGE_CONCEPT_ASSERT((
|
||||
BinaryPredicateConcept<
|
||||
BinaryPredicate,
|
||||
typename std::iterator_traits<ForwardIterator>::value_type,
|
||||
Value>
|
||||
));
|
||||
|
||||
typedef typename std::iterator_traits<ForwardIterator>::iterator_category cat_t;
|
||||
|
||||
if (count <= 0)
|
||||
return first;
|
||||
if (count == 1)
|
||||
{
|
||||
while (first != last && !static_cast<bool>(pred(*first, value)))
|
||||
++first;
|
||||
return first;
|
||||
}
|
||||
return range_detail::search_n_pred_impl(first, last, count,
|
||||
value, pred, cat_t());
|
||||
}
|
||||
} // namespace range_detail
|
||||
|
||||
namespace range {
|
||||
|
||||
/// \brief template function search
|
||||
///
|
||||
/// range-based version of the search std algorithm
|
||||
///
|
||||
/// \pre ForwardRange is a model of the ForwardRangeConcept
|
||||
/// \pre Integer is an integral type
|
||||
/// \pre Value is a model of the EqualityComparableConcept
|
||||
/// \pre ForwardRange's value type is a model of the EqualityComparableConcept
|
||||
/// \pre Object's of ForwardRange's value type can be compared for equality with Objects of type Value
|
||||
template< class ForwardRange, class Integer, class Value >
|
||||
inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
||||
search_n(ForwardRange& rng, Integer count, const Value& value)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||
return range_detail::search_n_impl(boost::begin(rng),boost::end(rng), count, value);
|
||||
}
|
||||
|
||||
/// \overload
|
||||
template< class ForwardRange, class Integer, class Value >
|
||||
inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
|
||||
search_n(const ForwardRange& rng, Integer count, const Value& value)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
|
||||
return range_detail::search_n_impl(boost::begin(rng), boost::end(rng), count, value);
|
||||
}
|
||||
|
||||
/// \overload
|
||||
template< class ForwardRange, class Integer, class Value,
|
||||
class BinaryPredicate >
|
||||
inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
|
||||
search_n(ForwardRange& rng, Integer count, const Value& value,
|
||||
BinaryPredicate binary_pred)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
|
||||
BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type, const Value&>));
|
||||
return range_detail::search_n_pred_impl(boost::begin(rng), boost::end(rng),
|
||||
count, value, binary_pred);
|
||||
}
|
||||
|
||||
/// \overload
|
||||
template< class ForwardRange, class Integer, class Value,
|
||||
class BinaryPredicate >
|
||||
inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
|
||||
search_n(const ForwardRange& rng, Integer count, const Value& value,
|
||||
BinaryPredicate binary_pred)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
|
||||
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
|
||||
BOOST_DEDUCED_TYPENAME range_value<const ForwardRange>::type, const Value&>));
|
||||
return range_detail::search_n_pred_impl(boost::begin(rng), boost::end(rng),
|
||||
count, value, binary_pred);
|
||||
}
|
||||
|
||||
// range_return overloads
|
||||
|
||||
/// \overload
|
||||
template< range_return_value re, class ForwardRange, class Integer,
|
||||
class Value >
|
||||
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
|
||||
search_n(ForwardRange& rng, Integer count, const Value& value)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||
return range_return<ForwardRange,re>::
|
||||
pack(range_detail::search_n_impl(boost::begin(rng),boost::end(rng),
|
||||
count, value),
|
||||
rng);
|
||||
}
|
||||
|
||||
/// \overload
|
||||
template< range_return_value re, class ForwardRange, class Integer,
|
||||
class Value >
|
||||
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
|
||||
search_n(const ForwardRange& rng, Integer count, const Value& value)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
|
||||
return range_return<const ForwardRange,re>::
|
||||
pack(range_detail::search_n_impl(boost::begin(rng), boost::end(rng),
|
||||
count, value),
|
||||
rng);
|
||||
}
|
||||
|
||||
/// \overload
|
||||
template< range_return_value re, class ForwardRange, class Integer,
|
||||
class Value, class BinaryPredicate >
|
||||
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
|
||||
search_n(ForwardRange& rng, Integer count, const Value& value,
|
||||
BinaryPredicate pred)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
|
||||
BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type,
|
||||
const Value&>));
|
||||
return range_return<ForwardRange,re>::
|
||||
pack(range_detail::search_n_pred_impl(boost::begin(rng),
|
||||
boost::end(rng),
|
||||
count, value, pred),
|
||||
rng);
|
||||
}
|
||||
|
||||
/// \overload
|
||||
template< range_return_value re, class ForwardRange, class Integer,
|
||||
class Value, class BinaryPredicate >
|
||||
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
|
||||
search_n(const ForwardRange& rng, Integer count, const Value& value,
|
||||
BinaryPredicate pred)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
|
||||
BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
|
||||
BOOST_DEDUCED_TYPENAME range_value<const ForwardRange>::type,
|
||||
const Value&>));
|
||||
return range_return<const ForwardRange,re>::
|
||||
pack(range_detail::search_n_pred_impl(boost::begin(rng),
|
||||
boost::end(rng),
|
||||
count, value, pred),
|
||||
rng);
|
||||
}
|
||||
|
||||
} // namespace range
|
||||
using range::search_n;
|
||||
} // namespace boost
|
||||
|
||||
#endif // include guard
|
||||
@@ -0,0 +1,239 @@
|
||||
program ldpcsim174
|
||||
! End to end test of the (174,75)/crc12 encoder and decoder.
|
||||
use crc
|
||||
use packjt
|
||||
|
||||
parameter(NRECENT=10)
|
||||
character*12 recent_calls(NRECENT)
|
||||
character*22 msg,msgsent,msgreceived
|
||||
character*8 arg
|
||||
integer*1, allocatable :: codeword(:), decoded(:), message(:)
|
||||
integer*1, target:: i1Msg8BitBytes(11)
|
||||
integer*1 msgbits(87)
|
||||
integer*1 apmask(174), cw(174)
|
||||
integer*2 checksum
|
||||
integer*4 i4Msg6BitWords(13)
|
||||
integer colorder(174)
|
||||
integer nerrtot(174),nerrdec(174),nmpcbad(87)
|
||||
logical checksumok,fsk,bpsk
|
||||
real*8, allocatable :: rxdata(:)
|
||||
real, allocatable :: llr(:)
|
||||
|
||||
data colorder/ &
|
||||
0, 1, 2, 3, 30, 4, 5, 6, 7, 8, 9, 10, 11, 32, 12, 40, 13, 14, 15, 16,&
|
||||
17, 18, 37, 45, 29, 19, 20, 21, 41, 22, 42, 31, 33, 34, 44, 35, 47, 51, 50, 43,&
|
||||
36, 52, 63, 46, 25, 55, 27, 24, 23, 53, 39, 49, 59, 38, 48, 61, 60, 57, 28, 62,&
|
||||
56, 58, 65, 66, 26, 70, 64, 69, 68, 67, 74, 71, 54, 76, 72, 75, 78, 77, 80, 79,&
|
||||
73, 83, 84, 81, 82, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,&
|
||||
100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,&
|
||||
120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,&
|
||||
140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,&
|
||||
160,161,162,163,164,165,166,167,168,169,170,171,172,173/
|
||||
|
||||
do i=1,NRECENT
|
||||
recent_calls(i)=' '
|
||||
enddo
|
||||
nerrtot=0
|
||||
nerrdec=0
|
||||
nmpcbad=0 ! Used to collect the number of errors in the message+crc part of the codeword
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.ne.4) then
|
||||
print*,'Usage: ldpcsim niter norder #trials s '
|
||||
print*,'eg: ldpcsim 10 2 1000 0.84'
|
||||
print*,'belief propagation iterations: niter, ordered-statistics order: norder'
|
||||
print*,'If s is negative, then value is ignored and sigma is calculated from SNR.'
|
||||
return
|
||||
endif
|
||||
call getarg(1,arg)
|
||||
read(arg,*) max_iterations
|
||||
call getarg(2,arg)
|
||||
read(arg,*) norder
|
||||
call getarg(3,arg)
|
||||
read(arg,*) ntrials
|
||||
call getarg(4,arg)
|
||||
read(arg,*) s
|
||||
|
||||
fsk=.false.
|
||||
bpsk=.true.
|
||||
|
||||
! don't count crc bits as data bits
|
||||
N=174
|
||||
K=87
|
||||
! scale Eb/No for a (174,87) code
|
||||
rate=real(87)/real(N)
|
||||
|
||||
write(*,*) "rate: ",rate
|
||||
write(*,*) "niter= ",max_iterations," s= ",s
|
||||
|
||||
allocate ( codeword(N), decoded(K), message(K) )
|
||||
allocate ( rxdata(N), llr(N) )
|
||||
|
||||
msg="K1JT K9AN EN50"
|
||||
! msg="G4WJS K9AN EN50"
|
||||
call packmsg(msg,i4Msg6BitWords,itype) !Pack into 12 6-bit bytes
|
||||
call unpackmsg(i4Msg6BitWords,msgsent) !Unpack to get msgsent
|
||||
write(*,*) "message sent ",msgsent
|
||||
|
||||
i4=0
|
||||
ik=0
|
||||
im=0
|
||||
do i=1,12
|
||||
nn=i4Msg6BitWords(i)
|
||||
do j=1, 6
|
||||
ik=ik+1
|
||||
i4=i4+i4+iand(1,ishft(nn,j-6))
|
||||
i4=iand(i4,255)
|
||||
if(ik.eq.8) then
|
||||
im=im+1
|
||||
! if(i4.gt.127) i4=i4-256
|
||||
i1Msg8BitBytes(im)=i4
|
||||
ik=0
|
||||
endif
|
||||
enddo
|
||||
enddo
|
||||
|
||||
i1Msg8BitBytes(10:11)=0
|
||||
checksum = crc12 (c_loc (i1Msg8BitBytes), 11)
|
||||
! For reference, the next 3 lines show how to check the CRC
|
||||
i1Msg8BitBytes(10)=checksum/256
|
||||
i1Msg8BitBytes(11)=iand (checksum,255)
|
||||
checksumok = crc12_check(c_loc (i1Msg8BitBytes), 11)
|
||||
if( checksumok ) write(*,*) 'Good checksum'
|
||||
|
||||
! K=87, For now:
|
||||
! msgbits(1:72) JT message bits
|
||||
! msgbits(73:75) 3 free message bits (set to 0)
|
||||
! msgbits(76:87) CRC12
|
||||
mbit=0
|
||||
do i=1, 9
|
||||
i1=i1Msg8BitBytes(i)
|
||||
do ibit=1,8
|
||||
mbit=mbit+1
|
||||
msgbits(mbit)=iand(1,ishft(i1,ibit-8))
|
||||
enddo
|
||||
enddo
|
||||
msgbits(73:75)=0 ! the three extra message bits go here
|
||||
i1=i1Msg8BitBytes(10) ! First 4 bits of crc12 are LSB of this byte
|
||||
do ibit=1,4
|
||||
msgbits(75+ibit)=iand(1,ishft(i1,ibit-4))
|
||||
enddo
|
||||
i1=i1Msg8BitBytes(11) ! Now shift in last 8 bits of the CRC
|
||||
do ibit=1,8
|
||||
msgbits(79+ibit)=iand(1,ishft(i1,ibit-8))
|
||||
enddo
|
||||
|
||||
write(*,*) 'message'
|
||||
write(*,'(11(8i1,1x))') msgbits
|
||||
|
||||
call encode174(msgbits,codeword)
|
||||
call init_random_seed()
|
||||
call sgran()
|
||||
|
||||
write(*,*) 'codeword'
|
||||
write(*,'(22(8i1,1x))') codeword
|
||||
|
||||
write(*,*) "Es/N0 SNR2500 ngood nundetected nbadcrc sigma"
|
||||
do idb = 14,-6,-1
|
||||
db=idb/2.0-1.0
|
||||
sigma=1/sqrt( 2*(10**(db/10.0)) )
|
||||
ngood=0
|
||||
nue=0
|
||||
nbadcrc=0
|
||||
nberr=0
|
||||
do itrial=1, ntrials
|
||||
! Create a realization of a noisy received word
|
||||
do i=1,N
|
||||
if( bpsk ) then
|
||||
rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran()
|
||||
elseif( fsk ) then
|
||||
if( codeword(i) .eq. 1 ) then
|
||||
r1=(1.0 + sigma*gran())**2 + (sigma*gran())**2
|
||||
r2=(sigma*gran())**2 + (sigma*gran())**2
|
||||
elseif( codeword(i) .eq. 0 ) then
|
||||
r2=(1.0 + sigma*gran())**2 + (sigma*gran())**2
|
||||
r1=(sigma*gran())**2 + (sigma*gran())**2
|
||||
endif
|
||||
rxdata(i)=0.35*(sqrt(r1)-sqrt(r2))
|
||||
! rxdata(i)=0.35*(exp(r1)-exp(r2))
|
||||
! rxdata(i)=0.12*(log(r1)-log(r2))
|
||||
endif
|
||||
enddo
|
||||
nerr=0
|
||||
do i=1,N
|
||||
if( rxdata(i)*(2*codeword(i)-1.0) .lt. 0 ) nerr=nerr+1
|
||||
enddo
|
||||
nerrtot(nerr)=nerrtot(nerr)+1
|
||||
nberr=nberr+nerr
|
||||
|
||||
! Correct signal normalization is important for this decoder.
|
||||
! rxav=sum(rxdata)/N
|
||||
! rx2av=sum(rxdata*rxdata)/N
|
||||
! rxsig=sqrt(rx2av-rxav*rxav)
|
||||
! rxdata=rxdata/rxsig
|
||||
! To match the metric to the channel, s should be set to the noise standard deviation.
|
||||
! For now, set s to the value that optimizes decode probability near threshold.
|
||||
! The s parameter can be tuned to trade a few tenth's dB of threshold for an order of
|
||||
! magnitude in UER
|
||||
if( s .lt. 0 ) then
|
||||
ss=sigma
|
||||
else
|
||||
ss=s
|
||||
endif
|
||||
|
||||
llr=2.0*rxdata/(ss*ss)
|
||||
! nap=0 ! number of AP bits
|
||||
! llr(colorder(174-87+1:174-87+nap)+1)=5*(2.0*msgbits(1:nap)-1.0)
|
||||
apmask=0
|
||||
! apmask(colorder(174-87+1:174-87+nap)+1)=1
|
||||
|
||||
! max_iterations is max number of belief propagation iterations
|
||||
call bpdecode174(llr, apmask, max_iterations, decoded, niterations)
|
||||
ni1=niterations
|
||||
if( norder .ge. 0 .and. niterations .lt. 0 ) call osd174(llr, norder, decoded, niterations, cw)
|
||||
ni2=niterations
|
||||
! If the decoder finds a valid codeword, niterations will be .ge. 0.
|
||||
if( niterations .ge. 0 ) then
|
||||
call extractmessage174(decoded,msgreceived,ncrcflag,recent_calls,nrecent)
|
||||
if( ncrcflag .ne. 1 ) then
|
||||
nbadcrc=nbadcrc+1
|
||||
endif
|
||||
|
||||
nueflag=0
|
||||
nerrmpc=0
|
||||
do i=1,K ! find number of errors in message+crc part of codeword
|
||||
if( msgbits(i) .ne. decoded(i) ) then
|
||||
nueflag=1
|
||||
nerrmpc=nerrmpc+1
|
||||
endif
|
||||
enddo
|
||||
nmpcbad(nerrmpc)=nmpcbad(nerrmpc)+1
|
||||
|
||||
if( ncrcflag .eq. 1 ) then
|
||||
if( nueflag .eq. 0 ) then
|
||||
ngood=ngood+1
|
||||
nerrdec(nerr)=nerrdec(nerr)+1
|
||||
else if( nueflag .eq. 1 ) then
|
||||
nue=nue+1;
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
enddo
|
||||
snr2500=db+10*log10(6.08/2500.0)
|
||||
pberr=real(nberr)/(real(ntrials*N))
|
||||
write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,1x,i8,8x,f5.2,8x,e10.3)") db,snr2500,ngood,nue,nbadcrc,ss,pberr
|
||||
|
||||
enddo
|
||||
|
||||
open(unit=23,file='nerrhisto.dat',status='unknown')
|
||||
do i=1,174
|
||||
write(23,'(i4,2x,i10,i10,f10.2)') i,nerrdec(i),nerrtot(i),real(nerrdec(i))/real(nerrtot(i)+1e-10)
|
||||
enddo
|
||||
close(23)
|
||||
open(unit=25,file='nmpcbad.dat',status='unknown')
|
||||
do i=1,87
|
||||
write(25,'(i4,2x,i10)') i,nmpcbad(i)
|
||||
enddo
|
||||
close(25)
|
||||
|
||||
end program ldpcsim174
|
||||
Reference in New Issue
Block a user