Initial Commit

This commit is contained in:
Jordan Sherer
2018-02-08 21:28:33 -05:00
commit 678c1d3966
14352 changed files with 3176737 additions and 0 deletions
@@ -0,0 +1,8 @@
// Copyright (C) 2005 Arkadiy Vertleyb
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt)
#if defined(_MSC_VER) && defined BOOST_TYPEOF_MESSAGES
# pragma message(BOOST_TYPEOF_TEXT)
#endif
#undef BOOST_TYPEOF_TEXT
@@ -0,0 +1,66 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2005-2006 Dan Marsden
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_FUSION_AT_IMPL_20061029_1946)
#define BOOST_FUSION_AT_IMPL_20061029_1946
#include <boost/fusion/support/config.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/fusion/view/transform_view/detail/apply_transform_result.hpp>
#include <boost/fusion/sequence/intrinsic/at.hpp>
namespace boost { namespace fusion {
struct transform_view_tag;
struct transform_view2_tag;
namespace extension
{
template<typename Tag>
struct at_impl;
template<>
struct at_impl<transform_view_tag>
{
template<typename Seq, typename N>
struct apply
{
typedef typename Seq::transform_type F;
typedef detail::apply_transform_result<F> transform_type;
typedef typename boost::fusion::result_of::at<typename Seq::sequence_type, N>::type value_type;
typedef typename mpl::apply<transform_type, value_type>::type type;
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
static type call(Seq& seq)
{
return seq.f(boost::fusion::at<N>(seq.seq));
}
};
};
template<>
struct at_impl<transform_view2_tag>
{
template<typename Seq, typename N>
struct apply
{
typedef typename Seq::transform_type F;
typedef detail::apply_transform_result<F> transform_type;
typedef typename boost::fusion::result_of::at<typename Seq::sequence1_type, N>::type value1_type;
typedef typename boost::fusion::result_of::at<typename Seq::sequence2_type, N>::type value2_type;
typedef typename mpl::apply<transform_type, value1_type, value2_type>::type type;
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
static type call(Seq& seq)
{
return seq.f(boost::fusion::at<N>(seq.seq1), boost::fusion::at<N>(seq.seq2));
}
};
};
}
}}
#endif
@@ -0,0 +1,77 @@
//---------------------------------------------------------------------------//
// 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_DETAIL_READ_WRITE_SINGLE_VALUE_HPP
#define BOOST_COMPUTE_DETAIL_READ_WRITE_SINGLE_VALUE_HPP
#include <boost/throw_exception.hpp>
#include <boost/compute/buffer.hpp>
#include <boost/compute/exception.hpp>
#include <boost/compute/command_queue.hpp>
namespace boost {
namespace compute {
namespace detail {
// reads and returns a single value at index in the buffer
template<class T>
inline T read_single_value(const buffer &buffer,
size_t index,
command_queue &queue)
{
BOOST_ASSERT(index < buffer.size() / sizeof(T));
BOOST_ASSERT(buffer.get_context() == queue.get_context());
T value;
queue.enqueue_read_buffer(buffer,
sizeof(T) * index,
sizeof(T),
&value);
return value;
}
// reads and returns a the first value in the buffer
template<class T>
inline T read_single_value(const buffer &buffer, command_queue &queue)
{
return read_single_value<T>(buffer, 0, queue);
}
// writes a single value at index to the buffer
template<class T>
inline void write_single_value(const T &value,
const buffer &buffer,
size_t index,
command_queue &queue)
{
BOOST_ASSERT(index < buffer.size() / sizeof(T));
BOOST_ASSERT(buffer.get_context() == queue.get_context());
queue.enqueue_write_buffer(buffer,
index * sizeof(T),
sizeof(T),
&value);
}
// writes value to the first location in buffer
template<class T>
inline void write_single_value(const T &value,
const buffer &buffer,
command_queue &queue)
{
write_single_value<T>(value, buffer, 0, queue);
}
} // end detail namespace
} // end compute namespace
} // end boost namespace
#endif // BOOST_COMPUTE_DETAIL_READ_WRITE_SINGLE_VALUE_HPP
@@ -0,0 +1,20 @@
/*
(c) 2014-2015 Glen Joseph Fernandes
<glenjofe -at- gmail.com>
Distributed under the Boost Software
License, Version 1.0.
http://boost.org/LICENSE_1_0.txt
*/
#ifndef BOOST_ALIGN_ALIGN_HPP
#define BOOST_ALIGN_ALIGN_HPP
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_STD_ALIGN)
#include <boost/align/detail/align_cxx11.hpp>
#else
#include <boost/align/detail/align.hpp>
#endif
#endif
@@ -0,0 +1,45 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(FUSION_POP_FRONT_09172005_1115)
#define FUSION_POP_FRONT_09172005_1115
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/view/iterator_range/iterator_range.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/end.hpp>
#include <boost/fusion/iterator/next.hpp>
namespace boost { namespace fusion
{
namespace result_of
{
template <typename Sequence>
struct pop_front
{
typedef
iterator_range<
typename next<
typename begin<Sequence>::type
>::type
, typename end<Sequence>::type
>
type;
};
}
template <typename Sequence>
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
inline typename result_of::pop_front<Sequence const>::type
pop_front(Sequence const& seq)
{
typedef typename result_of::pop_front<Sequence const>::type result;
return result(fusion::next(fusion::begin(seq)), fusion::end(seq));
}
}}
#endif
@@ -0,0 +1,18 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
This is an auto-generated file. Do not edit!
==============================================================================*/
namespace boost { namespace fusion
{
struct void_;
struct set_tag;
struct set_iterator_tag;
template <
typename T0 = void_ , typename T1 = void_ , typename T2 = void_ , typename T3 = void_ , typename T4 = void_ , typename T5 = void_ , typename T6 = void_ , typename T7 = void_ , typename T8 = void_ , typename T9 = void_ , typename T10 = void_ , typename T11 = void_ , typename T12 = void_ , typename T13 = void_ , typename T14 = void_ , typename T15 = void_ , typename T16 = void_ , typename T17 = void_ , typename T18 = void_ , typename T19 = void_
>
struct set;
}}
@@ -0,0 +1,125 @@
program ft8sim
! Generate simulated data for a 15-second HF/6m mode using 8-FSK.
! Output is saved to a *.wav file.
use wavhdr
include 'ft8_params.f90' !Set various constants
type(hdr) h !Header for .wav file
character arg*12,fname*17,sorm*1
character msg*22,msgsent*22
character*6 mygrid6
logical bcontest
complex c0(0:NMAX-1)
complex c(0:NMAX-1)
integer itone(NN)
integer*1 msgbits(KK)
integer*2 iwave(NMAX) !Generated full-length waveform
data mygrid6/'EM48 '/
! Get command-line argument(s)
nargs=iargc()
if(nargs.ne.8) then
print*,'Usage: ft8sim "message" s|m f0 DT fdop del nfiles snr'
print*,'Example: ft8sim "K1ABC W9XYZ EN37" m 1500.0 0.0 0.1 1.0 10 -18'
print*,'s|m: "s" for single signal at 1500 Hz, "m" for 25 signals'
print*,'f0 is ignored when sorm = m'
print*,'Make nfiles negative to invoke 72-bit contest mode.'
go to 999
endif
call getarg(1,msg) !Message to be transmitted
call getarg(2,sorm) !s for single signal, m for multiple sigs
if(sorm.eq."s") then
print*,"Generating single signal at 1500 Hz."
nsig=1
elseif( sorm.eq."m") then
print*,"Generating 25 signals per file."
nsig=25
else
print*,"sorm parameter must be s (single) or m (multiple)."
goto 999
endif
call getarg(3,arg)
read(arg,*) f0 !Frequency (only used for single-signal)
call getarg(4,arg)
read(arg,*) xdt !Time offset from nominal (s)
call getarg(5,arg)
read(arg,*) fspread !Watterson frequency spread (Hz)
call getarg(6,arg)
read(arg,*) delay !Watterson delay (ms)
call getarg(7,arg)
read(arg,*) nfiles !Number of files
call getarg(8,arg)
read(arg,*) snrdb !SNR_2500
bcontest=nfiles.lt.0
nfiles=abs(nfiles)
twopi=8.0*atan(1.0)
fs=12000.0 !Sample rate (Hz)
dt=1.0/fs !Sample interval (s)
tt=NSPS*dt !Duration of symbols (s)
baud=1.0/tt !Keying rate (baud)
bw=8*baud !Occupied bandwidth (Hz)
txt=NZ*dt !Transmission length (s)
bandwidth_ratio=2500.0/(fs/2.0)
sig=sqrt(2*bandwidth_ratio) * 10.0**(0.05*snrdb)
if(snrdb.gt.90.0) sig=1.0
txt=NN*NSPS/12000.0
! Source-encode, then get itone()
call genft8(msg,mygrid6,bcontest,msgsent,msgbits,itone)
write(*,1000) f0,xdt,txt,snrdb,bw,msgsent
1000 format('f0:',f9.3,' DT:',f6.2,' TxT:',f6.1,' SNR:',f6.1, &
' BW:',f4.1,2x,a22)
write(*,'(28i1,1x,28i1)') msgbits(1:56)
write(*,'(16i1)') msgbits(57:72)
write(*,'(3i1)') msgbits(73:75)
write(*,'(12i1)') msgbits(76:87)
! call sgran()
do ifile=1,nfiles
c=0.
do isig=1,nsig
c0=0.
if(nsig.eq.25) then
f0=(isig+2)*100.0
endif
k=-1 + nint((xdt+0.5+0.01*gran())/dt)
! k=-1 + nint((xdt+0.5)/dt)
phi=0.0
do j=1,NN !Generate complex waveform
dphi=twopi*(f0+itone(j)*baud)*dt
do i=1,NSPS
k=k+1
phi=mod(phi+dphi,twopi)
if(k.ge.0 .and. k.lt.NMAX) c0(k)=cmplx(cos(phi),sin(phi))
enddo
enddo
if(fspread.ne.0.0 .or. delay.ne.0.0) call watterson(c0,NMAX,fs,delay,fspread)
c=c+sig*c0
enddo
if(snrdb.lt.90) then
do i=0,NMAX-1 !Add gaussian noise at specified SNR
xnoise=gran()
ynoise=gran()
c(i)=c(i) + cmplx(xnoise,ynoise)
enddo
endif
fac=32767.0
rms=100.0
if(snrdb.ge.90.0) iwave(1:NMAX)=nint(fac*real(c))
if(snrdb.lt.90.0) iwave(1:NMAX)=nint(rms*real(c))
h=default_header(12000,NMAX)
write(fname,1102) ifile
1102 format('000000_',i6.6,'.wav')
open(10,file=fname,status='unknown',access='stream')
write(10) h,iwave !Save to *.wav file
close(10)
write(*,1110) ifile,xdt,f0,snrdb,fname
1110 format(i4,f7.2,f8.2,f7.1,2x,a17)
enddo
999 end program ft8sim
@@ -0,0 +1,20 @@
// These instructions are up-to-date for WSJT-X v1.8
*OS X 10.9* and later: Download the file {osx} to your desktop,
double-click on it and consult its `ReadMe` file for important
installation notes.
If you have already installed a previous version, you can retain it by
changing its name in the *Applications* folder (say, from _WSJT-X_ to
_WSJT-X_1.7_). You can then proceed to the installation phase.
Take note also of the following:
* Use the Mac's *Audio MIDI Setup* utility to configure your sound
card for 48000 Hz, two-channel, 16-bit format.
* Use *System Preferences* to select an external time source to keep
your system clock synchronized to UTC.
* To uninstall simply drag the _WSJT-X_ application from *Applications*
to the *Trash Can*.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,290 @@
// Copyright David Abrahams 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MAKE_CONSTRUCTOR_DWA20011221_HPP
# define MAKE_CONSTRUCTOR_DWA20011221_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/python/default_call_policies.hpp>
# include <boost/python/args.hpp>
# include <boost/python/object_fwd.hpp>
# include <boost/python/object/function_object.hpp>
# include <boost/python/object/make_holder.hpp>
# include <boost/python/object/pointer_holder.hpp>
# include <boost/python/converter/context_result_converter.hpp>
# include <boost/python/detail/caller.hpp>
# include <boost/python/detail/none.hpp>
# include <boost/mpl/size.hpp>
# include <boost/mpl/int.hpp>
# include <boost/mpl/push_front.hpp>
# include <boost/mpl/pop_front.hpp>
# include <boost/mpl/assert.hpp>
namespace boost { namespace python {
namespace detail
{
template <class T>
struct install_holder : converter::context_result_converter
{
install_holder(PyObject* args_)
: m_self(PyTuple_GetItem(args_, 0)) {}
PyObject* operator()(T x) const
{
dispatch(x, is_pointer<T>());
return none();
}
private:
template <class U>
void dispatch(U* x, mpl::true_) const
{
#if __cplusplus < 201103L
std::auto_ptr<U> owner(x);
dispatch(owner, mpl::false_());
#else
std::unique_ptr<U> owner(x);
dispatch(std::move(owner), mpl::false_());
#endif
}
template <class Ptr>
void dispatch(Ptr x, mpl::false_) const
{
typedef typename pointee<Ptr>::type value_type;
typedef objects::pointer_holder<Ptr,value_type> holder;
typedef objects::instance<holder> instance_t;
void* memory = holder::allocate(this->m_self, offsetof(instance_t, storage), sizeof(holder));
try {
#if __cplusplus < 201103L
(new (memory) holder(x))->install(this->m_self);
#else
(new (memory) holder(std::move(x)))->install(this->m_self);
#endif
}
catch(...) {
holder::deallocate(this->m_self, memory);
throw;
}
}
PyObject* m_self;
};
struct constructor_result_converter
{
template <class T>
struct apply
{
typedef install_holder<T> type;
};
};
template <class BaseArgs, class Offset>
struct offset_args
{
offset_args(BaseArgs base_) : base(base_) {}
BaseArgs base;
};
template <int N, class BaseArgs, class Offset>
inline PyObject* get(mpl::int_<N>, offset_args<BaseArgs,Offset> const& args_)
{
return get(mpl::int_<(N+Offset::value)>(), args_.base);
}
template <class BaseArgs, class Offset>
inline unsigned arity(offset_args<BaseArgs,Offset> const& args_)
{
return arity(args_.base) - Offset::value;
}
template <class BasePolicy_ = default_call_policies>
struct constructor_policy : BasePolicy_
{
constructor_policy(BasePolicy_ base) : BasePolicy_(base) {}
// If the BasePolicy_ supplied a result converter it would be
// ignored; issue an error if it's not the default.
BOOST_MPL_ASSERT_MSG(
(is_same<
typename BasePolicy_::result_converter
, default_result_converter
>::value)
, MAKE_CONSTRUCTOR_SUPPLIES_ITS_OWN_RESULT_CONVERTER_THAT_WOULD_OVERRIDE_YOURS
, (typename BasePolicy_::result_converter)
);
typedef constructor_result_converter result_converter;
typedef offset_args<typename BasePolicy_::argument_package, mpl::int_<1> > argument_package;
};
template <class InnerSignature>
struct outer_constructor_signature
{
typedef typename mpl::pop_front<InnerSignature>::type inner_args;
typedef typename mpl::push_front<inner_args,object>::type outer_args;
typedef typename mpl::push_front<outer_args,void>::type type;
};
// ETI workaround
template <>
struct outer_constructor_signature<int>
{
typedef int type;
};
//
// These helper functions for make_constructor (below) do the raw work
// of constructing a Python object from some invokable entity. See
// <boost/python/detail/caller.hpp> for more information about how
// the Sig arguments is used.
//
// @group make_constructor_aux {
template <class F, class CallPolicies, class Sig>
object make_constructor_aux(
F f // An object that can be invoked by detail::invoke()
, CallPolicies const& p // CallPolicies to use in the invocation
, Sig const& // An MPL sequence of argument types expected by F
)
{
typedef typename outer_constructor_signature<Sig>::type outer_signature;
typedef constructor_policy<CallPolicies> inner_policy;
return objects::function_object(
objects::py_function(
detail::caller<F,inner_policy,Sig>(f, inner_policy(p))
, outer_signature()
)
);
}
// As above, except that it accepts argument keywords. NumKeywords
// is used only for a compile-time assertion to make sure the user
// doesn't pass more keywords than the function can accept. To
// disable all checking, pass mpl::int_<0> for NumKeywords.
template <class F, class CallPolicies, class Sig, class NumKeywords>
object make_constructor_aux(
F f
, CallPolicies const& p
, Sig const&
, detail::keyword_range const& kw // a [begin,end) pair of iterators over keyword names
, NumKeywords // An MPL integral type wrapper: the size of kw
)
{
enum { arity = mpl::size<Sig>::value - 1 };
typedef typename detail::error::more_keywords_than_function_arguments<
NumKeywords::value, arity
>::too_many_keywords assertion BOOST_ATTRIBUTE_UNUSED;
typedef typename outer_constructor_signature<Sig>::type outer_signature;
typedef constructor_policy<CallPolicies> inner_policy;
return objects::function_object(
objects::py_function(
detail::caller<F,inner_policy,Sig>(f, inner_policy(p))
, outer_signature()
)
, kw
);
}
// }
//
// These dispatch functions are used to discriminate between the
// cases when the 3rd argument is keywords or when it is a
// signature.
//
// @group Helpers for make_constructor when called with 3 arguments. {
//
template <class F, class CallPolicies, class Keywords>
object make_constructor_dispatch(F f, CallPolicies const& policies, Keywords const& kw, mpl::true_)
{
return detail::make_constructor_aux(
f
, policies
, detail::get_signature(f)
, kw.range()
, mpl::int_<Keywords::size>()
);
}
template <class F, class CallPolicies, class Signature>
object make_constructor_dispatch(F f, CallPolicies const& policies, Signature const& sig, mpl::false_)
{
return detail::make_constructor_aux(
f
, policies
, sig
);
}
// }
}
// These overloaded functions wrap a function or member function
// pointer as a Python object, using optional CallPolicies,
// Keywords, and/or Signature. @group {
//
template <class F>
object make_constructor(F f)
{
return detail::make_constructor_aux(
f,default_call_policies(), detail::get_signature(f));
}
template <class F, class CallPolicies>
object make_constructor(F f, CallPolicies const& policies)
{
return detail::make_constructor_aux(
f, policies, detail::get_signature(f));
}
template <class F, class CallPolicies, class KeywordsOrSignature>
object make_constructor(
F f
, CallPolicies const& policies
, KeywordsOrSignature const& keywords_or_signature)
{
typedef typename
detail::is_reference_to_keywords<KeywordsOrSignature&>::type
is_kw;
return detail::make_constructor_dispatch(
f
, policies
, keywords_or_signature
, is_kw()
);
}
template <class F, class CallPolicies, class Keywords, class Signature>
object make_constructor(
F f
, CallPolicies const& policies
, Keywords const& kw
, Signature const& sig
)
{
return detail::make_constructor_aux(
f
, policies
, sig
, kw.range()
, mpl::int_<Keywords::size>()
);
}
// }
}}
#endif // MAKE_CONSTRUCTOR_DWA20011221_HPP
File diff suppressed because one or more lines are too long
@@ -0,0 +1,112 @@
// (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
// Unrolled polynomial evaluation using second order Horners rule
#ifndef BOOST_MATH_TOOLS_POLY_EVAL_8_HPP
#define BOOST_MATH_TOOLS_POLY_EVAL_8_HPP
namespace boost{ namespace math{ namespace tools{ namespace detail{
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T*, const V&, const mpl::int_<0>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(0);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V&, const mpl::int_<1>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<2>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(a[1] * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<3>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<4>*) BOOST_MATH_NOEXCEPT(V)
{
return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<5>*) BOOST_MATH_NOEXCEPT(V)
{
V x2 = x * x;
V t[2];
t[0] = static_cast<V>(a[4] * x2 + a[2]);
t[1] = static_cast<V>(a[3] * x2 + a[1]);
t[0] *= x2;
t[0] += static_cast<V>(a[0]);
t[1] *= x;
return t[0] + t[1];
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<6>*) BOOST_MATH_NOEXCEPT(V)
{
V x2 = x * x;
V t[2];
t[0] = a[5] * x2 + a[3];
t[1] = a[4] * x2 + a[2];
t[0] *= x2;
t[1] *= x2;
t[0] += static_cast<V>(a[1]);
t[1] += static_cast<V>(a[0]);
t[0] *= x;
return t[0] + t[1];
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<7>*) BOOST_MATH_NOEXCEPT(V)
{
V x2 = x * x;
V t[2];
t[0] = static_cast<V>(a[6] * x2 + a[4]);
t[1] = static_cast<V>(a[5] * x2 + a[3]);
t[0] *= x2;
t[1] *= x2;
t[0] += static_cast<V>(a[2]);
t[1] += static_cast<V>(a[1]);
t[0] *= x2;
t[0] += static_cast<V>(a[0]);
t[1] *= x;
return t[0] + t[1];
}
template <class T, class V>
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<8>*) BOOST_MATH_NOEXCEPT(V)
{
V x2 = x * x;
V t[2];
t[0] = a[7] * x2 + a[5];
t[1] = a[6] * x2 + a[4];
t[0] *= x2;
t[1] *= x2;
t[0] += static_cast<V>(a[3]);
t[1] += static_cast<V>(a[2]);
t[0] *= x2;
t[1] *= x2;
t[0] += static_cast<V>(a[1]);
t[1] += static_cast<V>(a[0]);
t[0] *= x;
return t[0] + t[1];
}
}}}} // namespaces
#endif // include guard
@@ -0,0 +1,218 @@
/*
* 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)
*
* Copyright (c) 2009 Helge Bahmann
* Copyright (c) 2012 Tim Blechmann
* Copyright (c) 2014 Andrey Semashev
*/
/*!
* \file atomic/detail/ops_windows.hpp
*
* This header contains implementation of the \c operations template.
*
* This implementation is the most basic version for Windows. It should
* work for any non-MSVC-like compilers as long as there are Interlocked WinAPI
* functions available. This version is also used for WinCE.
*
* Notably, this implementation is not as efficient as other
* versions based on compiler intrinsics.
*/
#ifndef BOOST_ATOMIC_DETAIL_OPS_WINDOWS_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_OPS_WINDOWS_HPP_INCLUDED_
#include <boost/memory_order.hpp>
#include <boost/type_traits/make_signed.hpp>
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/interlocked.hpp>
#include <boost/atomic/detail/storage_type.hpp>
#include <boost/atomic/detail/operations_fwd.hpp>
#include <boost/atomic/capabilities.hpp>
#include <boost/atomic/detail/ops_msvc_common.hpp>
#include <boost/atomic/detail/ops_extending_cas_based.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace atomics {
namespace detail {
struct windows_operations_base
{
static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT
{
long tmp;
BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&tmp, 0);
}
static BOOST_FORCEINLINE void fence_before(memory_order) BOOST_NOEXCEPT
{
BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
}
static BOOST_FORCEINLINE void fence_after(memory_order) BOOST_NOEXCEPT
{
BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
}
};
template< typename T, typename Derived >
struct windows_operations :
public windows_operations_base
{
typedef T storage_type;
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
Derived::exchange(storage, v, order);
}
static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
{
return Derived::fetch_add(const_cast< storage_type volatile& >(storage), (storage_type)0, order);
}
static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
typedef typename make_signed< storage_type >::type signed_storage_type;
return Derived::fetch_add(storage, static_cast< storage_type >(-static_cast< signed_storage_type >(v)), order);
}
static BOOST_FORCEINLINE bool compare_exchange_weak(
storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
{
return Derived::compare_exchange_strong(storage, expected, desired, success_order, failure_order);
}
static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
return !!Derived::exchange(storage, (storage_type)1, order);
}
static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
{
store(storage, (storage_type)0, order);
}
static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT
{
return true;
}
};
template< bool Signed >
struct operations< 4u, Signed > :
public windows_operations< typename make_storage_type< 4u, Signed >::type, operations< 4u, Signed > >
{
typedef windows_operations< typename make_storage_type< 4u, Signed >::type, operations< 4u, Signed > > base_type;
typedef typename base_type::storage_type storage_type;
typedef typename make_storage_type< 4u, Signed >::aligned aligned_storage_type;
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
base_type::fence_before(order);
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&storage, v));
base_type::fence_after(order);
return v;
}
static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
base_type::fence_before(order);
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&storage, v));
base_type::fence_after(order);
return v;
}
static BOOST_FORCEINLINE bool compare_exchange_strong(
storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
{
storage_type previous = expected;
base_type::fence_before(success_order);
storage_type old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&storage, desired, previous));
expected = old_val;
// The success and failure fences are the same anyway
base_type::fence_after(success_order);
return (previous == old_val);
}
static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
#if defined(BOOST_ATOMIC_INTERLOCKED_AND)
base_type::fence_before(order);
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND(&storage, v));
base_type::fence_after(order);
return v;
#else
storage_type res = storage;
while (!compare_exchange_strong(storage, res, res & v, order, memory_order_relaxed)) {}
return res;
#endif
}
static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
#if defined(BOOST_ATOMIC_INTERLOCKED_OR)
base_type::fence_before(order);
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR(&storage, v));
base_type::fence_after(order);
return v;
#else
storage_type res = storage;
while (!compare_exchange_strong(storage, res, res | v, order, memory_order_relaxed)) {}
return res;
#endif
}
static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
{
#if defined(BOOST_ATOMIC_INTERLOCKED_XOR)
base_type::fence_before(order);
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR(&storage, v));
base_type::fence_after(order);
return v;
#else
storage_type res = storage;
while (!compare_exchange_strong(storage, res, res ^ v, order, memory_order_relaxed)) {}
return res;
#endif
}
};
template< bool Signed >
struct operations< 1u, Signed > :
public extending_cas_based_operations< operations< 4u, Signed >, 1u, Signed >
{
};
template< bool Signed >
struct operations< 2u, Signed > :
public extending_cas_based_operations< operations< 4u, Signed >, 2u, Signed >
{
};
BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
{
BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
if (order == memory_order_seq_cst)
windows_operations_base::hardware_full_fence();
BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
}
BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
{
if (order != memory_order_relaxed)
BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
}
} // namespace detail
} // namespace atomics
} // namespace boost
#endif // BOOST_ATOMIC_DETAIL_OPS_WINDOWS_HPP_INCLUDED_
@@ -0,0 +1,289 @@
/*=============================================================================
Copyright (c) 1998-2003 Joel de Guzman
Copyright (c) 2001-2003 Hartmut Kaiser
http://spirit.sourceforge.net/
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_SPIRIT_NUMERICS_HPP
#define BOOST_SPIRIT_NUMERICS_HPP
#include <boost/config.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/core/composite/directives.hpp>
#include <boost/spirit/home/classic/core/primitives/numerics_fwd.hpp>
#include <boost/spirit/home/classic/core/primitives/impl/numerics.ipp>
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////
//
// uint_parser class
//
///////////////////////////////////////////////////////////////////////////
template <
typename T,
int Radix,
unsigned MinDigits,
int MaxDigits
>
struct uint_parser : parser<uint_parser<T, Radix, MinDigits, MaxDigits> >
{
typedef uint_parser<T, Radix, MinDigits, MaxDigits> self_t;
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, T>::type type;
};
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
typedef impl::uint_parser_impl<T, Radix, MinDigits, MaxDigits> impl_t;
typedef typename parser_result<impl_t, ScannerT>::type result_t;
return impl::contiguous_parser_parse<result_t>(impl_t(), scan, scan);
}
};
///////////////////////////////////////////////////////////////////////////
//
// int_parser class
//
///////////////////////////////////////////////////////////////////////////
template <
typename T,
int Radix,
unsigned MinDigits,
int MaxDigits
>
struct int_parser : parser<int_parser<T, Radix, MinDigits, MaxDigits> >
{
typedef int_parser<T, Radix, MinDigits, MaxDigits> self_t;
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, T>::type type;
};
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
typedef impl::int_parser_impl<T, Radix, MinDigits, MaxDigits> impl_t;
typedef typename parser_result<impl_t, ScannerT>::type result_t;
return impl::contiguous_parser_parse<result_t>(impl_t(), scan, scan);
}
};
///////////////////////////////////////////////////////////////////////////
//
// uint_parser/int_parser instantiations
//
///////////////////////////////////////////////////////////////////////////
int_parser<int> const
int_p = int_parser<int>();
uint_parser<unsigned> const
uint_p = uint_parser<unsigned>();
uint_parser<unsigned, 2> const
bin_p = uint_parser<unsigned, 2>();
uint_parser<unsigned, 8> const
oct_p = uint_parser<unsigned, 8>();
uint_parser<unsigned, 16> const
hex_p = uint_parser<unsigned, 16>();
///////////////////////////////////////////////////////////////////////////
//
// sign_parser class
//
///////////////////////////////////////////////////////////////////////////
namespace impl
{
// Utility to extract the prefix sign ('-' | '+')
template <typename ScannerT>
bool extract_sign(ScannerT const& scan, std::size_t& count);
}
struct sign_parser : public parser<sign_parser>
{
typedef sign_parser self_t;
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, bool>::type type;
};
sign_parser() {}
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
if (!scan.at_end())
{
std::size_t length;
typename ScannerT::iterator_t save(scan.first);
bool neg = impl::extract_sign(scan, length);
if (length)
return scan.create_match(1, neg, save, scan.first);
}
return scan.no_match();
}
};
sign_parser const sign_p = sign_parser();
///////////////////////////////////////////////////////////////////////////
//
// default real number policies
//
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct ureal_parser_policies
{
// trailing dot policy suggested suggested by Gustavo Guerra
BOOST_STATIC_CONSTANT(bool, allow_leading_dot = true);
BOOST_STATIC_CONSTANT(bool, allow_trailing_dot = true);
BOOST_STATIC_CONSTANT(bool, expect_dot = false);
typedef uint_parser<T, 10, 1, -1> uint_parser_t;
typedef int_parser<T, 10, 1, -1> int_parser_t;
template <typename ScannerT>
static typename match_result<ScannerT, nil_t>::type
parse_sign(ScannerT& scan)
{
return scan.no_match();
}
template <typename ScannerT>
static typename parser_result<uint_parser_t, ScannerT>::type
parse_n(ScannerT& scan)
{
return uint_parser_t().parse(scan);
}
template <typename ScannerT>
static typename parser_result<chlit<>, ScannerT>::type
parse_dot(ScannerT& scan)
{
return ch_p('.').parse(scan);
}
template <typename ScannerT>
static typename parser_result<uint_parser_t, ScannerT>::type
parse_frac_n(ScannerT& scan)
{
return uint_parser_t().parse(scan);
}
template <typename ScannerT>
static typename parser_result<chlit<>, ScannerT>::type
parse_exp(ScannerT& scan)
{
return as_lower_d['e'].parse(scan);
}
template <typename ScannerT>
static typename parser_result<int_parser_t, ScannerT>::type
parse_exp_n(ScannerT& scan)
{
return int_parser_t().parse(scan);
}
};
template <typename T>
struct real_parser_policies : public ureal_parser_policies<T>
{
template <typename ScannerT>
static typename parser_result<sign_parser, ScannerT>::type
parse_sign(ScannerT& scan)
{
return sign_p.parse(scan);
}
};
///////////////////////////////////////////////////////////////////////////
//
// real_parser class
//
///////////////////////////////////////////////////////////////////////////
template <
typename T,
typename RealPoliciesT
>
struct real_parser
: public parser<real_parser<T, RealPoliciesT> >
{
typedef real_parser<T, RealPoliciesT> self_t;
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, T>::type type;
};
real_parser() {}
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
typedef typename parser_result<self_t, ScannerT>::type result_t;
return impl::real_parser_impl<result_t, T, RealPoliciesT>::parse(scan);
}
};
///////////////////////////////////////////////////////////////////////////
//
// real_parser instantiations
//
///////////////////////////////////////////////////////////////////////////
real_parser<double, ureal_parser_policies<double> > const
ureal_p = real_parser<double, ureal_parser_policies<double> >();
real_parser<double, real_parser_policies<double> > const
real_p = real_parser<double, real_parser_policies<double> >();
///////////////////////////////////////////////////////////////////////////
//
// strict reals (do not allow plain integers (no decimal point))
//
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct strict_ureal_parser_policies : public ureal_parser_policies<T>
{
BOOST_STATIC_CONSTANT(bool, expect_dot = true);
};
template <typename T>
struct strict_real_parser_policies : public real_parser_policies<T>
{
BOOST_STATIC_CONSTANT(bool, expect_dot = true);
};
real_parser<double, strict_ureal_parser_policies<double> > const
strict_ureal_p
= real_parser<double, strict_ureal_parser_policies<double> >();
real_parser<double, strict_real_parser_policies<double> > const
strict_real_p
= real_parser<double, strict_real_parser_policies<double> >();
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif
@@ -0,0 +1,60 @@
#ifndef SAMPLE_DOWNLOADER_DIRECTORY_HPP__
#define SAMPLE_DOWNLOADER_DIRECTORY_HPP__
#include <QObject>
#include <QString>
#include <QTreeWidget>
#include <QIcon>
#include <QSize>
#include <QDir>
#include <QUrl>
#include "DirectoryDelegate.hpp"
#include "RemoteFile.hpp"
class Configuration;
class QNetworkAccessManager;
class QTreeWidgetItem;
class QNetworkReply;
class QAuthenticator;
class QJsonArray;
class Directory final
: public QTreeWidget
, protected RemoteFile::ListenerInterface
{
Q_OBJECT
public:
explicit Directory (Configuration const * configuration
, QNetworkAccessManager * network_manager
, QWidget * parent = nullptr);
QSize sizeHint () const override {return {400, 500};}
bool url_root (QUrl);
bool refresh (bool http_only);
void abort ();
void update (QTreeWidgetItem * item);
protected:
void error (QString const& title, QString const& message) override;
bool redirect_request (QUrl const&) override {return true;} // allow
void download_finished (bool success) override;
private:
Q_SLOT void authentication (QNetworkReply *, QAuthenticator *);
void parse_entries (QJsonArray const& entries, QDir const& dir, QTreeWidgetItem * parent);
Configuration const * configuration_;
QNetworkAccessManager * network_manager_;
bool http_only_;
QDir root_dir_;
QUrl url_root_;
RemoteFile contents_;
DirectoryDelegate item_delegate_;
QIcon dir_icon_;
QIcon file_icon_;
};
#endif
@@ -0,0 +1,49 @@
#ifndef BOOST_MPL_AUX_LAMBDA_SPEC_HPP_INCLUDED
#define BOOST_MPL_AUX_LAMBDA_SPEC_HPP_INCLUDED
// Copyright Aleksey Gurtovoy 2001-2007
//
// 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/void.hpp>
#include <boost/mpl/lambda_fwd.hpp>
#include <boost/mpl/int_fwd.hpp>
#include <boost/mpl/aux_/preprocessor/params.hpp>
#include <boost/mpl/aux_/lambda_arity_param.hpp>
#include <boost/mpl/aux_/config/lambda.hpp>
#if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT)
# define BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(i, name) \
template< \
BOOST_MPL_PP_PARAMS(i, typename T) \
, typename Tag \
> \
struct lambda< \
name< BOOST_MPL_PP_PARAMS(i, T) > \
, Tag \
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(int_<i>) \
> \
{ \
typedef false_ is_le; \
typedef name< BOOST_MPL_PP_PARAMS(i, T) > result_; \
typedef result_ type; \
}; \
/**/
#else
# define BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(i, name) /**/
#endif
#endif // BOOST_MPL_AUX_LAMBDA_SPEC_HPP_INCLUDED
@@ -0,0 +1,94 @@
// 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/less_equal.hpp" header
// -- DO NOT modify by hand!
namespace boost { namespace mpl {
template<
typename Tag1
, typename Tag2
>
struct less_equal_impl
: if_c<
( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1)
> BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2)
)
, aux::cast2nd_impl< less_equal_impl< Tag1,Tag1 >,Tag1, Tag2 >
, aux::cast1st_impl< less_equal_impl< Tag2,Tag2 >,Tag1, Tag2 >
>::type
{
};
/// for Digital Mars C++/compilers with no CTPS/TTP support
template<> struct less_equal_impl< na,na >
{
template< typename U1, typename U2 > struct apply
{
typedef apply type;
BOOST_STATIC_CONSTANT(int, value = 0);
};
};
template< typename Tag > struct less_equal_impl< na,Tag >
{
template< typename U1, typename U2 > struct apply
{
typedef apply type;
BOOST_STATIC_CONSTANT(int, value = 0);
};
};
template< typename Tag > struct less_equal_impl< Tag,na >
{
template< typename U1, typename U2 > struct apply
{
typedef apply type;
BOOST_STATIC_CONSTANT(int, value = 0);
};
};
template< typename T > struct less_equal_tag
{
typedef typename T::tag type;
};
template<
typename BOOST_MPL_AUX_NA_PARAM(N1)
, typename BOOST_MPL_AUX_NA_PARAM(N2)
>
struct less_equal
: less_equal_impl<
typename less_equal_tag<N1>::type
, typename less_equal_tag<N2>::type
>::template apply< N1,N2 >::type
{
BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less_equal, (N1, N2))
};
BOOST_MPL_AUX_NA_SPEC2(2, 2, less_equal)
}}
namespace boost { namespace mpl {
template<>
struct less_equal_impl< integral_c_tag,integral_c_tag >
{
template< typename N1, typename N2 > struct apply
: bool_< ( BOOST_MPL_AUX_VALUE_WKND(N1)::value <= BOOST_MPL_AUX_VALUE_WKND(N2)::value ) >
{
};
};
}}
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

@@ -0,0 +1,28 @@
# /* **************************************************************************
# * *
# * (C) Copyright Edward Diener 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 for most recent version. */
#
# ifndef BOOST_PREPROCESSOR_VARIADIC_DETAIL_IS_SINGLE_RETURN_HPP
# define BOOST_PREPROCESSOR_VARIADIC_DETAIL_IS_SINGLE_RETURN_HPP
#
# include <boost/preprocessor/config/config.hpp>
#
# /* BOOST_PP_VARIADIC_IS_SINGLE_RETURN */
#
# if BOOST_PP_VARIADICS && BOOST_PP_VARIADICS_MSVC
# include <boost/preprocessor/control/iif.hpp>
# include <boost/preprocessor/facilities/is_1.hpp>
# include <boost/preprocessor/variadic/size.hpp>
# define BOOST_PP_VARIADIC_IS_SINGLE_RETURN(sr,nsr,...) \
BOOST_PP_IIF(BOOST_PP_IS_1(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__)),sr,nsr) \
/**/
# endif /* BOOST_PP_VARIADICS && BOOST_PP_VARIADICS_MSVC */
#
# endif /* BOOST_PREPROCESSOR_VARIADIC_DETAIL_IS_SINGLE_RETURN_HPP */
@@ -0,0 +1,3 @@
2
3 4
.8 .2
@@ -0,0 +1,336 @@
[[PROTOCOL_OVERVIEW]]
=== Overview
All QSO modes except ISCAT use structured messages that compress
user-readable information into fixed-length packets of 72 bits. Each
message consists of two 28-bit fields normally used for callsigns and
a 15-bit field for a grid locator, report, acknowledgment, or 73. An
additional bit flags a message containing arbitrary alphanumeric text,
up to 13 characters. Special cases allow other information such as
add-on callsign prefixes (e.g., ZA/K1ABC) or suffixes (e.g., K1ABC/P)
to be encoded. The basic aim is to compress the most common messages
used for minimally valid QSOs into a fixed 72-bit length. Information
payloads in FT8 include 3 additional bits (75 bits total), with
definitions yet to be defined.
A standard amateur callsign consists of a one- or two-character
prefix, at least one of which must be a letter, followed by a digit
and a suffix of one to three letters. Within these rules, the number
of possible callsigns is equal to 37×36×10×27×27×27, or somewhat over
262 million. (The numbers 27 and 37 arise because in the first and
last three positions a character may be absent, or a letter, or
perhaps a digit.) Since 2^28^ is more than 268 million, 28 bits are
enough to encode any standard callsign uniquely. Similarly, the number
of 4-digit Maidenhead grid locators on earth is 180×180 = 32,400,
which is less than 2^15^ = 32,768; so a grid locator requires 15 bits.
Some 6 million of the possible 28-bit values are not needed for
callsigns. A few of these slots have been assigned to special message
components such as `CQ`, `DE`, and `QRZ`. `CQ` may be followed by three
digits to indicate a desired callback frequency. (If K1ABC transmits
on a standard calling frequency, say 50.280, and sends `CQ 290 K1ABC
FN42`, it means that s/he will listen on 50.290 and respond there to
any replies.) A numerical signal report of the form `nn` or
`Rnn` can be sent in place of a grid locator. (As originally
defined, numerical signal reports `nn` were required to fall between -01
and -30 dB. Recent program versions accommodate reports between
-50 and +49 dB.) A country prefix or portable suffix may be
attached to one of the callsigns. When this feature is used the
additional information is sent in place of the grid locator or by
encoding additional information into some of the 6 million available
slots mentioned above.
Finally, the message compression algorithm supports messages starting
with `CQ AA` through `CQ ZZ`. Such messages are encoded by
sending `E9AA` through `E9ZZ` in place of the first callsign of a
standard message. Upon reception these calls are converted back to
the form `CQ AA` through `CQ ZZ`.
To be useful on channels with low signal-to-noise ratio, this kind of
lossless message compression requires use of a strong forward error
correcting (FEC) code. Different codes are used for each mode.
Accurate synchronization of time and frequency is required between
transmitting and receiving stations. As an aid to the decoders, each
protocol includes a "`sync vector`" of known symbols interspersed with
the information-carrying symbols. Generated waveforms for all of the
_WSJT-X_ modes have continuous phase and constant envelope.
[[SLOW_MODES]]
=== Slow Modes
[[FT8PRO]]
==== FT8
Forward error correction (FEC) in FT8 uses a low-density parity check
(LDPC) code with 75 information bits, a 12-bit cyclic redundancy check
(CRC), and 87 parity bits making a 174-bit codeword. It is thus
called an LDPC (174,87) code. Synchronization uses 7×7 Costas arrays
at the beginning, middle, and end of each transmission. Modulation is
8-tone frequency-shift keying (8-FSK) at 12000/1920 = 6.25 baud. Each
transmitted symbol carries three bits, so the total number of channel
symbols is 174/3 + 21 = 79. The total occupied bandwidth is 8 × 6.25
= 50 Hz.
[[JT4PRO]]
==== JT4
FEC in JT4 uses a strong convolutional code with constraint length
K=32, rate r=1/2, and a zero tail. This choice leads to an encoded
message length of (72+31) x 2 = 206 information-carrying bits.
Modulation is 4-tone frequency-shift keying (4-FSK) at 11025 / 2520 =
4.375 baud. Each symbol carries one information bit (the most
significant bit) and one synchronizing bit. The two 32-bit
polynomials used for convolutional encoding have hexadecimal values
0xf2d05351 and 0xe4613c47, and the ordering of encoded bits is
scrambled by an interleaver. The pseudo-random sync vector is the
following sequence (60 bits per line):
000011000110110010100000001100000000000010110110101111101000
100100111110001010001111011001000110101010101111101010110101
011100101101111000011011000111011101110010001101100100011111
10011000011000101101111010
[[JT9PRO]]
==== JT9
FEC in JT9 uses the same strong convolutional code as JT4: constraint
length K=32, rate r=1/2, and a zero tail, leading to an encoded
message length of (72+31) × 2 = 206 information-carrying
bits. Modulation is nine-tone frequency-shift keying, 9-FSK at
12000.0/6912 = 1.736 baud. Eight tones are used for data, one for
synchronization. Eight data tones means that three data bits are
conveyed by each transmitted information symbol. Sixteen symbol
intervals are devoted to synchronization, so a transmission requires a
total of 206 / 3 + 16 = 85 (rounded up) channel symbols. The sync
symbols are those numbered 1, 2, 5, 10, 16, 23, 33, 35, 51, 52, 55,
60, 66, 73, 83, and 85 in the transmitted sequence. Tone spacing of
the 9-FSK modulation for JT9A is equal to the keying rate, 1.736 Hz.
The total occupied bandwidth is 9 × 1.736 = 15.6 Hz.
[[JT65PRO]]
==== JT65
A detailed description of the JT65 protocol was published in
{jt65protocol} for September-October, 2005. A Reed Solomon (63,12)
error-control code converts 72-bit user messages into sequences of 63
six-bit information-carrying symbols. These are interleaved with
another 63 symbols of synchronizing information according to the
following pseudo-random sequence:
100110001111110101000101100100011100111101101111000110101011001
101010100100000011000000011010010110101010011001001000011111111
The synchronizing tone is normally sent in each interval having a
"`1`" in the sequence. Modulation is 65-FSK at 11025/4096 = 2.692
baud. Frequency spacing between tones is equal to the keying rate for
JT65A, and 2 and 4 times larger for JT65B and JT65C. For EME QSOs the
signal report OOO is sometimes used instead of numerical signal
reports. It is conveyed by reversing sync and data positions in the
transmitted sequence. Shorthand messages for RO, RRR, and 73 dispense
with the sync vector entirely and use time intervals of 16384/11025 =
1.486 s for pairs of alternating tones. The lower frequency is the
same as that of the sync tone used in long messages, and the frequency
separation is 110250/4096 = 26.92 Hz multiplied by n for JT65A, with n
= 2, 3, 4 used to convey the messages RO, RRR, and 73.
[[QRA64_PROTOCOL]]
==== QRA64
QRA64 is an experimental mode intended for EME and other extreme
weak-signal applications. Its internal code was designed by IV3NWV.
The protocol uses a (63,12) **Q**-ary **R**epeat **A**ccumulate code
that is inherently better than the Reed Solomon (63,12) code used in
JT65, yielding a 1.3 dB advantage. A new synchronizing scheme is based
on three 7 x 7 Costas arrays. This change yields another 1.9 dB
advantage.
In most respects the current implementation of QRA64 is operationally
similar to JT65. QRA64 does not use two-tone shorthand messages, and
it makes no use of a callsign database. Rather, additional
sensitivity is gained by making use of already known information as a
QSO progresses -- for example, when reports are being exchanged and
you have already decoded both callsigns in a previous transmission.
QRA64 presently offers no message averaging capability, though that
feature may be added. In early tests, many EME QSOs were made using
submodes QRA64A-E on bands from 144 MHz to 24 GHz.
[[SLOW_SUMMARY]]
==== Summary
Table 2 provides a brief summary parameters for the slow modes in
_WSJT-X_. Parameters K and r specify the constraint length and rate
of the convolutional codes; n and k specify the sizes of the
(equivalent) block codes; Q is the alphabet size for the
information-carrying channel symbols; Sync Energy is the fraction of
transmitted energy devoted to synchronizing symbols; and S/N Threshold
is the signal-to-noise ratio (in a 2500 Hz reference bandwidth) above
which the probability of decoding is 50% or higher.
[[SLOW_TAB]]
.Parameters of Slow Modes
[width="90%",cols="3h,^3,^2,^1,^2,^2,^2,^2,^2,^2",frame=topbot,options="header"]
|===============================================================================
|Mode |FEC Type |(n,k) | Q|Modulation type|Keying rate (Baud)|Bandwidth (Hz)
|Sync Energy|Tx Duration (s)|S/N Threshold (dB)
|FT8 |LDPC, r=1/2|(174,87)| 8| 8-FSK| 6.25 | 50.0 | 0.27| 12.6 | -21
|JT4A |K=32, r=1/2|(206,72)| 2| 4-FSK| 4.375| 17.5 | 0.50| 47.1 | -23
|JT9A |K=32, r=1/2|(206,72)| 8| 9-FSK| 1.736| 15.6 | 0.19| 49.0 | -27
|JT65A |Reed Solomon|(63,12) |64|65-FSK| 2.692| 177.6 | 0.50| 46.8 | -25
|QRA64A|Q-ary Repeat Accumulate|(63,12) |64|64-FSK|1.736|111.1|0.25|48.4| -26
| WSPR |K=32, r=1/2|(162,50)| 2| 4-FSK| 1.465| 5.9 | 0.50|110.6 | -28
|===============================================================================
Submodes of JT4, JT9, JT65, and QRA64 offer wider tone spacings for
circumstances that may require them, such significant Doppler spread.
Table 3 summarizes the tone spacings, bandwidths, and approximate
threshold sensitivities of the various submodes when spreading is
comparable to tone spacing.
[[SLOW_SUBMODES]]
.Parameters of Slow Submodes
[width="50%",cols="h,3*^",frame=topbot,options="header"]
|=====================================
|Mode |Tone Spacing |BW (Hz)|S/N (dB)
|FT8 |6.25 | 50.0 |-21
|JT4A |4.375| 17.5 |-23
|JT4B |8.75 | 30.6 |-22
|JT4C |17.5 | 56.9 |-21
|JT4D |39.375| 122.5 |-20
|JT4E |78.75| 240.6 |-19
|JT4F |157.5| 476.9 |-18
|JT4G |315.0| 949.4 |-17
|JT9A |1.736| 15.6 |-27
|JT9B |3.472| 29.5 |-26
|JT9C |6.944| 57.3 |-25
|JT9D |13.889| 112.8 |-24
|JT9E |27.778| 224.0 |-23
|JT9F |55.556| 446.2 |-22
|JT9G |111.111|890.6 |-21
|JT9H |222.222|1779.5|-20
|JT65A |2.692| 177.6 |-25
|JT65B |5.383| 352.6 |-25
|JT65C |10.767| 702.5 |-25
|QRA64A|1.736| 111.1 |-26
|QRA64B|3.472| 220.5 |-25
|QRA64C|6.944| 439.2 |-24
|QRA64D|13.889| 876.7 |-23
|QRA64E|27.778|1751.7 |-22
|=====================================
[[FAST_MODES]]
=== Fast Modes
==== ISCAT
ISCAT messages are free-form, up to 28 characters in length.
Modulation is 42-tone frequency-shift keying at 11025 / 512 = 21.533
baud (ISCAT-A), or 11025 / 256 = 43.066 baud (ISCAT-B). Tone
frequencies are spaced by an amount in Hz equal to the baud rate. The
available character set is:
----
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ /.?@-
----
Transmissions consist of sequences of 24 symbols: a synchronizing
pattern of four symbols at tone numbers 0, 1, 3, and 2, followed by
two symbols with tone number corresponding to (message length) and
(message length + 5), and finally 18 symbols conveying the user's
message, sent repeatedly character by character. The message always
starts with `@`, the beginning-of-message symbol, which is not
displayed to the user. The sync pattern and message-length indicator
have a fixed repetition period, recurring every 24 symbols. Message
information occurs periodically within the 18 symbol positions set
aside for its use, repeating at its own natural length.
For example, consider the user message `CQ WA9XYZ`. Including the
beginning-of-message symbol `@`, the message is 10 characters long.
Using the character sequence displayed above to indicate tone numbers,
the transmitted message will therefore start out as shown in the first
line below:
----
0132AF@CQ WA9XYZ@CQ WA9X0132AFYZ@CQ WA9XYZ@CQ W0132AFA9X ...
sync## sync## sync##
----
Note that the first six symbols (four for sync, two for message
length) repeat every 24 symbols. Within the 18 information-carrying
symbols in each 24, the user message `@CQ WA9XYZ` repeats at its own
natural length, 10 characters. The resulting sequence is extended as
many times as will fit into a Tx sequence.
==== JT9
The JT9 slow modes all use keying rate 12000/6912 = 1.736 baud. By contrast, with
the *Fast* setting submodes JT9E-H adjust the keying rate to match the
increased tone spacings. Message durations are therefore much
shorter, and they are sent repeatedly throughout each Tx sequence.
For details see Table 4, below.
==== MSK144
Standard MSK144 messages are structured in the same way as those in
the slow modes, with 72 bits of user information. Forward error
correction is implemented by first augmenting the 72 message bits with
an 8-bit cyclic redundancy check (CRC) calculated from the message
bits. The CRC is used to detect and eliminate most false decodes at
the receiver. The resulting 80-bit augmented message is mapped to a
128-bit codeword using a (128,80) binary low-density-parity-check
(LDPC) code designed by K9AN specifically for this purpose. Two 8-bit
synchronizing sequences are added to make a message frame 144 bits
long. Modulation is Offset Quadrature Phase-Shift Keying (OQPSK) at
2000 baud. Even-numbered bits are conveyed over the in-phase channel,
odd-numbered bits on the quadrature channel. Individual symbols are
shaped with half-sine profiles, thereby ensuring a generated waveform
with constant envelope, equivalent to a Minimum Shift Keying (MSK)
waveform. Frame duration is 72 ms, so the effective character
transmission rate for standard messages is up to 250 cps.
Contest Mode in MSK144 conveys an additional acknowledgment bit (the
"`R`" in a message of the form `W9XYZ K1ABC R FN42`) by using the fact
that meteor scatter and other propagation modes usable with MSK144 are
generally effective only out to distances of order 2500 km. To convey
the message fragment `R FN42`, WSJT-X encodes the locator as that of
its antipodes. The receiving program recognizes a locator with
distance greater than 10,000 km, does the reverse transformation, and
inserts the implied "`R`".
MSK144 also supports short-form messages that can be used after QSO
partners have exchanged both callsigns. Short messages consist of 4
bits encoding R+report, RRR, or 73, together with a 12-bit hash code
based on the ordered pair of "`to`" and "`from`" callsigns. Another
specially designed LDPC (32,16) code provides error correction, and an
8-bit synchronizing vector is appended to make up a 40-bit frame.
Short-message duration is thus 20 ms, and short messages can be
decoded from very short meteor pings.
The 72 ms or 20 ms frames of MSK144 messages are repeated without gaps
for the full duration of a transmission cycle. For most purposes, a
cycle duration of 15 s is suitable and recommended for MSK144.
The modulated MSK144 signal occupies the full bandwidth of a SSB
transmitter, so transmissions are always centered at audio frequency
1500 Hz. For best results, transmitter and receiver filters should be
adjusted to provide the flattest possible response over the range
300Hz to 2700Hz. The maximum permissible frequency offset between you
and your QSO partner ± 200 Hz.
==== Summary
.Parameters of Fast Modes
[width="90%",cols="3h,^3,^2,^1,^2,^2,^2,^2,^2",frame="topbot",options="header"]
|=====================================================================
|Mode |FEC Type |(n,k) | Q|Modulation Type|Keying rate (Baud)
|Bandwidth (Hz)|Sync Energy|Tx Duration (s)
|ISCAT-A | - | - |42|42-FSK| 21.5 | 905 | 0.17| 1.176
|ISCAT-B | - | - |42|42-FSK| 43.1 | 1809 | 0.17| 0.588
|JT9E |K=32, r=1/2|(206,72)| 8| 9-FSK| 25.0 | 225 | 0.19| 3.400
|JT9F |K=32, r=1/2|(206,72)| 8| 9-FSK| 50.0 | 450 | 0.19| 1.700
|JT9G |K=32, r=1/2|(206,72)| 8| 9-FSK|100.0 | 900 | 0.19| 0.850
|JT9H |K=32, r=1/2|(206,72)| 8| 9-FSK|200.0 | 1800 | 0.19| 0.425
|MSK144 |LDPC |(128,80)| 2| OQPSK| 2000 | 2400 | 0.11| 0.072
|MSK144 Sh|LDPC |(32,16) | 2| OQPSK| 2000 | 2400 | 0.20| 0.020
|=====================================================================
@@ -0,0 +1,102 @@
// 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/greater_equal.hpp" header
// -- DO NOT modify by hand!
namespace boost { namespace mpl {
template<
typename Tag1
, typename Tag2
, BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value
, BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value
>
struct greater_equal_impl
: if_c<
( tag1_ > tag2_ )
, aux::cast2nd_impl< greater_equal_impl< Tag1,Tag1 >,Tag1, Tag2 >
, aux::cast1st_impl< greater_equal_impl< Tag2,Tag2 >,Tag1, Tag2 >
>::type
{
};
/// for Digital Mars C++/compilers with no CTPS/TTP support
template<> struct greater_equal_impl< na,na >
{
template< typename U1, typename U2 > struct apply
{
typedef apply type;
BOOST_STATIC_CONSTANT(int, value = 0);
};
};
template<> struct greater_equal_impl< na,integral_c_tag >
{
template< typename U1, typename U2 > struct apply
{
typedef apply type;
BOOST_STATIC_CONSTANT(int, value = 0);
};
};
template<> struct greater_equal_impl< integral_c_tag,na >
{
template< typename U1, typename U2 > struct apply
{
typedef apply type;
BOOST_STATIC_CONSTANT(int, value = 0);
};
};
template< typename T > struct greater_equal_tag
: tag< T,na >
{
};
template<
typename BOOST_MPL_AUX_NA_PARAM(N1)
, typename BOOST_MPL_AUX_NA_PARAM(N2)
>
struct greater_equal
: aux::msvc_eti_base< typename apply_wrap2<
greater_equal_impl<
typename greater_equal_tag<N1>::type
, typename greater_equal_tag<N2>::type
>
, N1
, N2
>::type >::type
{
BOOST_MPL_AUX_LAMBDA_SUPPORT(2, greater_equal, (N1, N2))
};
BOOST_MPL_AUX_NA_SPEC2(2, 2, greater_equal)
}}
namespace boost { namespace mpl {
template<>
struct greater_equal_impl< integral_c_tag,integral_c_tag >
{
template< typename N1, typename N2 > struct apply
{
BOOST_STATIC_CONSTANT(bool, value =
( BOOST_MPL_AUX_VALUE_WKND(N1)::value >=
BOOST_MPL_AUX_VALUE_WKND(N2)::value )
);
typedef bool_<value> type;
};
};
}}
@@ -0,0 +1,30 @@
///////////////////////////////////////////////////////////////////////////////
/// \file core.hpp
/// Includes the core of Proto. Not included are the contexts, transforms and
/// debugging utilities.
//
// Copyright 2008 Eric Niebler. 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_PROTO_CORE_HPP_EAN_04_01_2005
#define BOOST_PROTO_CORE_HPP_EAN_04_01_2005
#include <boost/proto/proto_fwd.hpp>
#include <boost/proto/args.hpp>
#include <boost/proto/tags.hpp>
#include <boost/proto/eval.hpp>
#include <boost/proto/expr.hpp>
#include <boost/proto/repeat.hpp>
#include <boost/proto/traits.hpp>
#include <boost/proto/domain.hpp>
#include <boost/proto/fusion.hpp>
#include <boost/proto/matches.hpp>
#include <boost/proto/extends.hpp>
#include <boost/proto/literal.hpp>
#include <boost/proto/generate.hpp>
#include <boost/proto/operators.hpp>
#include <boost/proto/deep_copy.hpp>
#include <boost/proto/make_expr.hpp>
#endif
@@ -0,0 +1,166 @@
// 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/apply.hpp" header
// -- DO NOT modify by hand!
namespace boost { namespace mpl {
template<
typename F
>
struct apply0
{
typedef typename apply_wrap0<
typename lambda<F>::type
>::type type;
BOOST_MPL_AUX_LAMBDA_SUPPORT(
1
, apply0
, (F )
)
};
/// workaround for ETI bug
template<>
struct apply0<int>
{
typedef int type;
};
template<
typename F, typename T1
>
struct apply1
{
typedef typename apply_wrap1<
typename lambda<F>::type
, T1
>::type type;
BOOST_MPL_AUX_LAMBDA_SUPPORT(
2
, apply1
, (F, T1)
)
};
/// workaround for ETI bug
template<>
struct apply1< int,int >
{
typedef int type;
};
template<
typename F, typename T1, typename T2
>
struct apply2
{
typedef typename apply_wrap2<
typename lambda<F>::type
, T1, T2
>::type type;
BOOST_MPL_AUX_LAMBDA_SUPPORT(
3
, apply2
, (F, T1, T2)
)
};
/// workaround for ETI bug
template<>
struct apply2< int,int,int >
{
typedef int type;
};
template<
typename F, typename T1, typename T2, typename T3
>
struct apply3
{
typedef typename apply_wrap3<
typename lambda<F>::type
, T1, T2, T3
>::type type;
BOOST_MPL_AUX_LAMBDA_SUPPORT(
4
, apply3
, (F, T1, T2, T3)
)
};
/// workaround for ETI bug
template<>
struct apply3< int,int,int,int >
{
typedef int type;
};
template<
typename F, typename T1, typename T2, typename T3, typename T4
>
struct apply4
{
typedef typename apply_wrap4<
typename lambda<F>::type
, T1, T2, T3, T4
>::type type;
BOOST_MPL_AUX_LAMBDA_SUPPORT(
5
, apply4
, (F, T1, T2, T3, T4)
)
};
/// workaround for ETI bug
template<>
struct apply4< int,int,int,int,int >
{
typedef int type;
};
template<
typename F, typename T1, typename T2, typename T3, typename T4
, typename T5
>
struct apply5
{
typedef typename apply_wrap5<
typename lambda<F>::type
, T1, T2, T3, T4, T5
>::type type;
BOOST_MPL_AUX_LAMBDA_SUPPORT(
6
, apply5
, (F, T1, T2, T3, T4, T5)
)
};
/// workaround for ETI bug
template<>
struct apply5< int,int,int,int,int,int >
{
typedef int type;
};
}}
@@ -0,0 +1,56 @@
#ifndef BOOST_MPL_VECTOR_AUX_FRONT_HPP_INCLUDED
#define BOOST_MPL_VECTOR_AUX_FRONT_HPP_INCLUDED
// Copyright Aleksey Gurtovoy 2000-2008
//
// 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/front_fwd.hpp>
#include <boost/mpl/vector/aux_/at.hpp>
#include <boost/mpl/vector/aux_/tag.hpp>
#include <boost/mpl/aux_/nttp_decl.hpp>
#include <boost/mpl/aux_/config/typeof.hpp>
#include <boost/mpl/aux_/config/ctps.hpp>
namespace boost { namespace mpl {
#if defined(BOOST_MPL_CFG_TYPEOF_BASED_SEQUENCES)
template<>
struct front_impl< aux::vector_tag >
{
template< typename Vector > struct apply
: v_at<Vector,0>
{
};
};
#else
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template< BOOST_MPL_AUX_NTTP_DECL(long, n_) >
struct front_impl< aux::vector_tag<n_> >
{
template< typename Vector > struct apply
{
typedef typename Vector::item0 type;
};
};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#endif // BOOST_MPL_CFG_TYPEOF_BASED_SEQUENCES
}}
#endif // BOOST_MPL_VECTOR_AUX_FRONT_HPP_INCLUDED
@@ -0,0 +1,377 @@
subroutine osd174(llr,apmask,ndeep,decoded,cw,nhardmin,dmin)
!
! An ordered-statistics decoder for the (174,87) code.
!
include "ldpc_174_87_params.f90"
integer*1 apmask(N),apmaskr(N)
integer*1 gen(K,N)
integer*1 genmrb(K,N),g2(N,K)
integer*1 temp(K),m0(K),me(K),mi(K),misub(K),e2sub(N-K),e2(N-K),ui(N-K)
integer*1 r2pat(N-K)
integer indices(N),nxor(N)
integer*1 cw(N),ce(N),c0(N),hdec(N)
integer*1 decoded(K)
integer indx(N)
real llr(N),rx(N),absrx(N)
logical first,reset
data first/.true./
save first,gen
if( first ) then ! fill the generator matrix
gen=0
do i=1,M
do j=1,22
read(g(i)(j:j),"(Z1)") istr
do jj=1, 4
irow=(j-1)*4+jj
if( btest(istr,4-jj) ) gen(irow,i)=1
enddo
enddo
enddo
do irow=1,K
gen(irow,M+irow)=1
enddo
first=.false.
endif
! Re-order received vector to place systematic msg bits at the end.
rx=llr(colorder+1)
apmaskr=apmask(colorder+1)
! Hard decisions on the received word.
hdec=0
where(rx .ge. 0) hdec=1
! Use magnitude of received symbols as a measure of reliability.
absrx=abs(rx)
call indexx(absrx,N,indx)
! Re-order the columns of the generator matrix in order of decreasing reliability.
do i=1,N
genmrb(1:K,i)=gen(1:K,indx(N+1-i))
indices(i)=indx(N+1-i)
enddo
! Do gaussian elimination to create a generator matrix with the most reliable
! received bits in positions 1:K in order of decreasing reliability (more or less).
do id=1,K ! diagonal element indices
do icol=id,K+20 ! The 20 is ad hoc - beware
iflag=0
if( genmrb(id,icol) .eq. 1 ) then
iflag=1
if( icol .ne. id ) then ! reorder column
temp(1:K)=genmrb(1:K,id)
genmrb(1:K,id)=genmrb(1:K,icol)
genmrb(1:K,icol)=temp(1:K)
itmp=indices(id)
indices(id)=indices(icol)
indices(icol)=itmp
endif
do ii=1,K
if( ii .ne. id .and. genmrb(ii,id) .eq. 1 ) then
genmrb(ii,1:N)=ieor(genmrb(ii,1:N),genmrb(id,1:N))
endif
enddo
exit
endif
enddo
enddo
g2=transpose(genmrb)
! The hard decisions for the K MRB bits define the order 0 message, m0.
! Encode m0 using the modified generator matrix to find the "order 0" codeword.
! Flip various combinations of bits in m0 and re-encode to generate a list of
! codewords. Return the member of the list that has the smallest Euclidean
! distance to the received word.
hdec=hdec(indices) ! hard decisions from received symbols
m0=hdec(1:K) ! zero'th order message
absrx=absrx(indices)
rx=rx(indices)
apmaskr=apmaskr(indices)
call mrbencode(m0,c0,g2,N,K)
nxor=ieor(c0,hdec)
nhardmin=sum(nxor)
dmin=sum(nxor*absrx)
cw=c0
ntotal=0
nrejected=0
if(ndeep.eq.0) goto 998 ! norder=0
if(ndeep.gt.5) ndeep=5
if( ndeep.eq. 1) then
nord=1
npre1=0
npre2=0
nt=40
ntheta=12
elseif(ndeep.eq.2) then
nord=1
npre1=1
npre2=0
nt=40
ntheta=12
elseif(ndeep.eq.3) then
nord=1
npre1=1
npre2=1
nt=40
ntheta=12
ntau=14
elseif(ndeep.eq.4) then
nord=2
npre1=1
npre2=0
nt=40
ntheta=12
ntau=19
elseif(ndeep.eq.5) then
nord=2
npre1=1
npre2=1
nt=40
ntheta=12
ntau=19
endif
do iorder=1,nord
if( iorder.eq. 1 ) then
misub(1:K-1)=0
misub(K)=1
iflag=K
elseif( iorder.eq. 2 ) then
misub(1:K-2)=0
misub(K-1:K)=1
iflag=K-1
endif
do while(iflag .ge.0)
if(iorder.eq.nord .and. npre1.eq.0) then
iend=iflag
else
iend=1
endif
do n1=iflag,iend,-1
mi=misub
mi(n1)=1
if(any(iand(apmaskr(1:K),mi).eq.1)) cycle
ntotal=ntotal+1
me=ieor(m0,mi)
if(n1.eq.iflag) then
call mrbencode(me,ce,g2,N,K)
e2sub=ieor(ce(K+1:N),hdec(K+1:N))
e2=e2sub
nd1Kpt=sum(e2sub(1:nt))+1
d1=sum(ieor(me(1:K),hdec(1:K))*absrx(1:K))
else
e2=ieor(e2sub,g2(K+1:N,n1))
nd1Kpt=sum(e2(1:nt))+2
endif
if(nd1Kpt .le. ntheta) then
call mrbencode(me,ce,g2,N,K)
nxor=ieor(ce,hdec)
if(n1.eq.iflag) then
dd=d1+sum(e2sub*absrx(K+1:N))
else
dd=d1+ieor(ce(n1),hdec(n1))*absrx(n1)+sum(e2*absrx(K+1:N))
endif
if( dd .lt. dmin ) then
dmin=dd
cw=ce
nhardmin=sum(nxor)
nd1Kptbest=nd1Kpt
endif
else
nrejected=nrejected+1
endif
enddo
! Get the next test error pattern, iflag will go negative
! when the last pattern with weight iorder has been generated.
call nextpat(misub,k,iorder,iflag)
enddo
enddo
if(npre2.eq.1) then
reset=.true.
ntotal=0
do i1=K,1,-1
do i2=i1-1,1,-1
ntotal=ntotal+1
mi(1:ntau)=ieor(g2(K+1:K+ntau,i1),g2(K+1:K+ntau,i2))
call boxit(reset,mi(1:ntau),ntau,ntotal,i1,i2)
enddo
enddo
ncount2=0
ntotal2=0
reset=.true.
! Now run through again and do the second pre-processing rule
if(nord.eq.1) then
misub(1:K-1)=0
misub(K)=1
iflag=K
elseif(nord.eq.2) then
misub(1:K-1)=0
misub(K-1:K)=1
iflag=K-1
endif
do while(iflag .ge.0)
me=ieor(m0,misub)
call mrbencode(me,ce,g2,N,K)
e2sub=ieor(ce(K+1:N),hdec(K+1:N))
do i2=0,ntau
ntotal2=ntotal2+1
ui=0
if(i2.gt.0) ui(i2)=1
r2pat=ieor(e2sub,ui)
778 continue
call fetchit(reset,r2pat(1:ntau),ntau,in1,in2)
if(in1.gt.0.and.in2.gt.0) then
ncount2=ncount2+1
mi=misub
mi(in1)=1
mi(in2)=1
if(sum(mi).lt.nord+npre1+npre2.or.any(iand(apmaskr(1:K),mi).eq.1)) cycle
me=ieor(m0,mi)
call mrbencode(me,ce,g2,N,K)
nxor=ieor(ce,hdec)
dd=sum(nxor*absrx)
if( dd .lt. dmin ) then
dmin=dd
cw=ce
nhardmin=sum(nxor)
endif
goto 778
endif
enddo
call nextpat(misub,K,nord,iflag)
enddo
endif
998 continue
! Re-order the codeword to place message bits at the end.
cw(indices)=cw
hdec(indices)=hdec
decoded=cw(K+1:N)
cw(colorder+1)=cw ! put the codeword back into received-word order
return
end subroutine osd174
subroutine mrbencode(me,codeword,g2,N,K)
integer*1 me(K),codeword(N),g2(N,K)
! fast encoding for low-weight test patterns
codeword=0
do i=1,K
if( me(i) .eq. 1 ) then
codeword=ieor(codeword,g2(1:N,i))
endif
enddo
return
end subroutine mrbencode
subroutine nextpat(mi,k,iorder,iflag)
integer*1 mi(k),ms(k)
! generate the next test error pattern
ind=-1
do i=1,k-1
if( mi(i).eq.0 .and. mi(i+1).eq.1) ind=i
enddo
if( ind .lt. 0 ) then ! no more patterns of this order
iflag=ind
return
endif
ms=0
ms(1:ind-1)=mi(1:ind-1)
ms(ind)=1
ms(ind+1)=0
if( ind+1 .lt. k ) then
nz=iorder-sum(ms)
ms(k-nz+1:k)=1
endif
mi=ms
do i=1,k ! iflag will point to the lowest-index 1 in mi
if(mi(i).eq.1) then
iflag=i
exit
endif
enddo
return
end subroutine nextpat
subroutine boxit(reset,e2,ntau,npindex,i1,i2)
integer*1 e2(1:ntau)
integer indexes(4000,2),fp(0:525000),np(4000)
logical reset
common/boxes/indexes,fp,np
if(reset) then
patterns=-1
fp=-1
np=-1
sc=-1
indexes=-1
reset=.false.
endif
indexes(npindex,1)=i1
indexes(npindex,2)=i2
ipat=0
do i=1,ntau
if(e2(i).eq.1) then
ipat=ipat+ishft(1,ntau-i)
endif
enddo
ip=fp(ipat) ! see what's currently stored in fp(ipat)
if(ip.eq.-1) then
fp(ipat)=npindex
else
do while (np(ip).ne.-1)
ip=np(ip)
enddo
np(ip)=npindex
endif
return
end subroutine boxit
subroutine fetchit(reset,e2,ntau,i1,i2)
integer indexes(4000,2),fp(0:525000),np(4000)
integer lastpat
integer*1 e2(ntau)
logical reset
common/boxes/indexes,fp,np
save lastpat,inext
if(reset) then
lastpat=-1
reset=.false.
endif
ipat=0
do i=1,ntau
if(e2(i).eq.1) then
ipat=ipat+ishft(1,ntau-i)
endif
enddo
index=fp(ipat)
if(lastpat.ne.ipat .and. index.gt.0) then ! return first set of indices
i1=indexes(index,1)
i2=indexes(index,2)
inext=np(index)
elseif(lastpat.eq.ipat .and. inext.gt.0) then
i1=indexes(inext,1)
i2=indexes(inext,2)
inext=np(inext)
else
i1=-1
i2=-1
inext=-1
endif
lastpat=ipat
return
end subroutine fetchit
@@ -0,0 +1,16 @@
/* User include file for the Reed-Solomon codec
* Copyright 2002, Phil Karn KA9Q
* May be used under the terms of the GNU General Public License (GPL)
*/
/* General purpose RS codec, integer symbols */
void encode_rs_int(void *rs,int *data,int *parity);
int decode_rs_int(void *rs,int *data,int *eras_pos,int no_eras, int calc_syn);
void *init_rs_int(int symsize,int gfpoly,int fcr,
int prim,int nroots,int pad);
void free_rs_int(void *rs);
/* Tables to map from conventional->dual (Taltab) and
* dual->conventional (Tal1tab) bases
*/
extern unsigned char Taltab[],Tal1tab[];
@@ -0,0 +1,54 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2005-2006 Dan Marsden
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(FUSION_CONVERT_IMPL_09232005_1340)
#define FUSION_CONVERT_IMPL_09232005_1340
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/container/map/detail/cpp03/as_map.hpp>
#include <boost/fusion/container/map/detail/cpp03/map.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/sequence/intrinsic/size.hpp>
namespace boost { namespace fusion
{
struct map_tag;
namespace extension
{
template <typename T>
struct convert_impl;
template <>
struct convert_impl<map_tag>
{
template <typename Sequence>
struct apply
{
typedef typename
detail::as_map<
result_of::size<Sequence>::value
, is_base_of<
associative_tag
, typename traits::category_of<Sequence>::type>::value
>
gen;
typedef typename gen::
template apply<typename result_of::begin<Sequence>::type>::type
type;
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
static type call(Sequence& seq)
{
return gen::call(fusion::begin(seq));
}
};
};
}
}}
#endif
@@ -0,0 +1,44 @@
// 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)
// (C) Copyright 2014 Vicente J. Botet Escriba
#ifndef BOOST_THREAD_EXCEPTIONAL_PTR_HPP
#define BOOST_THREAD_EXCEPTIONAL_PTR_HPP
#include <boost/thread/detail/move.hpp>
#include <boost/exception_ptr.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
struct exceptional_ptr {
exception_ptr ptr_;
exceptional_ptr() : ptr_() {}
explicit exceptional_ptr(exception_ptr ex) : ptr_(ex) {}
template <class E>
explicit exceptional_ptr(BOOST_FWD_REF(E) ex) : ptr_(boost::copy_exception(boost::forward<E>(ex))) {}
};
template <class E>
inline exceptional_ptr make_exceptional(BOOST_FWD_REF(E) ex) {
return exceptional_ptr(boost::forward<E>(ex));
}
inline exceptional_ptr make_exceptional(exception_ptr ex)
{
return exceptional_ptr(ex);
}
inline exceptional_ptr make_exceptional()
{
return exceptional_ptr();
}
} // namespace boost
#include <boost/config/abi_suffix.hpp>
#endif
@@ -0,0 +1,907 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Pablo Halpern 2009. 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)
//
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-2013. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/scoped_allocator_fwd.hpp>
#include <boost/container/detail/dispatch_uses_allocator.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/pair.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/move/adl_move_swap.hpp>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
#include <boost/move/utility_core.hpp>
#include <boost/core/no_exceptions_support.hpp>
namespace boost { namespace container {
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace container_detail {
template <typename Allocator>
struct is_scoped_allocator_imp
{
typedef char yes_type;
struct no_type{ char dummy[2]; };
template <typename T>
static yes_type test(typename T::outer_allocator_type*);
template <typename T>
static int test(...);
static const bool value = (sizeof(yes_type) == sizeof(test<Allocator>(0)));
};
template<class MaybeScopedAlloc, bool = is_scoped_allocator_imp<MaybeScopedAlloc>::value >
struct outermost_allocator_type_impl
{
typedef typename MaybeScopedAlloc::outer_allocator_type outer_type;
typedef typename outermost_allocator_type_impl<outer_type>::type type;
};
template<class MaybeScopedAlloc>
struct outermost_allocator_type_impl<MaybeScopedAlloc, false>
{
typedef MaybeScopedAlloc type;
};
template<class MaybeScopedAlloc, bool = is_scoped_allocator_imp<MaybeScopedAlloc>::value >
struct outermost_allocator_imp
{
typedef MaybeScopedAlloc type;
static type &get(MaybeScopedAlloc &a)
{ return a; }
static const type &get(const MaybeScopedAlloc &a)
{ return a; }
};
template<class MaybeScopedAlloc>
struct outermost_allocator_imp<MaybeScopedAlloc, true>
{
typedef typename MaybeScopedAlloc::outer_allocator_type outer_type;
typedef typename outermost_allocator_type_impl<outer_type>::type type;
static type &get(MaybeScopedAlloc &a)
{ return outermost_allocator_imp<outer_type>::get(a.outer_allocator()); }
static const type &get(const MaybeScopedAlloc &a)
{ return outermost_allocator_imp<outer_type>::get(a.outer_allocator()); }
};
} //namespace container_detail {
template <typename Allocator>
struct is_scoped_allocator
: container_detail::is_scoped_allocator_imp<Allocator>
{};
template <typename Allocator>
struct outermost_allocator
: container_detail::outermost_allocator_imp<Allocator>
{};
template <typename Allocator>
typename outermost_allocator<Allocator>::type &
get_outermost_allocator(Allocator &a)
{ return outermost_allocator<Allocator>::get(a); }
template <typename Allocator>
const typename outermost_allocator<Allocator>::type &
get_outermost_allocator(const Allocator &a)
{ return outermost_allocator<Allocator>::get(a); }
namespace container_detail {
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename OuterAlloc, class ...InnerAllocs>
class scoped_allocator_adaptor_base
: public OuterAlloc
{
typedef allocator_traits<OuterAlloc> outer_traits_type;
BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)
public:
template <class OuterA2>
struct rebind_base
{
typedef scoped_allocator_adaptor_base<OuterA2, InnerAllocs...> other;
};
typedef OuterAlloc outer_allocator_type;
typedef scoped_allocator_adaptor<InnerAllocs...> inner_allocator_type;
typedef allocator_traits<inner_allocator_type> inner_traits_type;
typedef scoped_allocator_adaptor
<OuterAlloc, InnerAllocs...> scoped_allocator_type;
typedef container_detail::bool_<
outer_traits_type::propagate_on_container_copy_assignment::value ||
inner_allocator_type::propagate_on_container_copy_assignment::value
> propagate_on_container_copy_assignment;
typedef container_detail::bool_<
outer_traits_type::propagate_on_container_move_assignment::value ||
inner_allocator_type::propagate_on_container_move_assignment::value
> propagate_on_container_move_assignment;
typedef container_detail::bool_<
outer_traits_type::propagate_on_container_swap::value ||
inner_allocator_type::propagate_on_container_swap::value
> propagate_on_container_swap;
typedef container_detail::bool_<
outer_traits_type::is_always_equal::value &&
inner_allocator_type::is_always_equal::value
> is_always_equal;
scoped_allocator_adaptor_base()
{}
template <class OuterA2>
scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs &...args)
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
, m_inner(args...)
{}
scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)
: outer_allocator_type(other.outer_allocator())
, m_inner(other.inner_allocator())
{}
scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
: outer_allocator_type(::boost::move(other.outer_allocator()))
, m_inner(::boost::move(other.inner_allocator()))
{}
template <class OuterA2>
scoped_allocator_adaptor_base
(const scoped_allocator_adaptor_base<OuterA2, InnerAllocs...>& other)
: outer_allocator_type(other.outer_allocator())
, m_inner(other.inner_allocator())
{}
template <class OuterA2>
scoped_allocator_adaptor_base
(BOOST_RV_REF_BEG scoped_allocator_adaptor_base
<OuterA2, InnerAllocs...> BOOST_RV_REF_END other)
: outer_allocator_type(other.outer_allocator())
, m_inner(other.inner_allocator())
{}
public:
struct internal_type_t{};
template <class OuterA2>
scoped_allocator_adaptor_base
( internal_type_t
, BOOST_FWD_REF(OuterA2) outerAlloc
, const inner_allocator_type &inner)
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
, m_inner(inner)
{}
public:
scoped_allocator_adaptor_base &operator=
(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
{
outer_allocator_type::operator=(other.outer_allocator());
m_inner = other.inner_allocator();
return *this;
}
scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
{
outer_allocator_type::operator=(boost::move(other.outer_allocator()));
m_inner = ::boost::move(other.inner_allocator());
return *this;
}
void swap(scoped_allocator_adaptor_base &r)
{
boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());
boost::adl_move_swap(this->m_inner, r.inner_allocator());
}
friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
{ l.swap(r); }
inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return m_inner; }
inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_inner; }
outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return static_cast<outer_allocator_type&>(*this); }
const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return static_cast<const outer_allocator_type&>(*this); }
scoped_allocator_type select_on_container_copy_construction() const
{
return scoped_allocator_type
(internal_type_t()
,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
);
}
private:
inner_allocator_type m_inner;
};
#else //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
//Let's add a dummy first template parameter to allow creating
//specializations up to maximum InnerAlloc count
template <typename OuterAlloc, bool Dummy, BOOST_MOVE_CLASSDFLT9>
class scoped_allocator_adaptor_base;
//Specializations for the adaptor with InnerAlloc allocators
#define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE(N)\
template <typename OuterAlloc BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
class scoped_allocator_adaptor_base<OuterAlloc, true, BOOST_MOVE_TARG##N>\
: public OuterAlloc\
{\
typedef allocator_traits<OuterAlloc> outer_traits_type;\
BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)\
\
public:\
template <class OuterA2>\
struct rebind_base\
{\
typedef scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N> other;\
};\
\
typedef OuterAlloc outer_allocator_type;\
typedef scoped_allocator_adaptor<BOOST_MOVE_TARG##N> inner_allocator_type;\
typedef scoped_allocator_adaptor<OuterAlloc, BOOST_MOVE_TARG##N> scoped_allocator_type;\
typedef allocator_traits<inner_allocator_type> inner_traits_type;\
typedef container_detail::bool_<\
outer_traits_type::propagate_on_container_copy_assignment::value ||\
inner_allocator_type::propagate_on_container_copy_assignment::value\
> propagate_on_container_copy_assignment;\
typedef container_detail::bool_<\
outer_traits_type::propagate_on_container_move_assignment::value ||\
inner_allocator_type::propagate_on_container_move_assignment::value\
> propagate_on_container_move_assignment;\
typedef container_detail::bool_<\
outer_traits_type::propagate_on_container_swap::value ||\
inner_allocator_type::propagate_on_container_swap::value\
> propagate_on_container_swap;\
\
typedef container_detail::bool_<\
outer_traits_type::is_always_equal::value &&\
inner_allocator_type::is_always_equal::value\
> is_always_equal;\
\
scoped_allocator_adaptor_base(){}\
\
template <class OuterA2>\
scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, BOOST_MOVE_CREF##N)\
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))\
, m_inner(BOOST_MOVE_ARG##N)\
{}\
\
scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)\
: outer_allocator_type(other.outer_allocator())\
, m_inner(other.inner_allocator())\
{}\
\
scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\
: outer_allocator_type(::boost::move(other.outer_allocator()))\
, m_inner(::boost::move(other.inner_allocator()))\
{}\
\
template <class OuterA2>\
scoped_allocator_adaptor_base\
(const scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N>& other)\
: outer_allocator_type(other.outer_allocator())\
, m_inner(other.inner_allocator())\
{}\
\
template <class OuterA2>\
scoped_allocator_adaptor_base\
(BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N> BOOST_RV_REF_END other)\
: outer_allocator_type(other.outer_allocator())\
, m_inner(other.inner_allocator())\
{}\
\
public:\
struct internal_type_t{};\
\
template <class OuterA2>\
scoped_allocator_adaptor_base\
( internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &inner)\
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))\
, m_inner(inner)\
{}\
\
public:\
scoped_allocator_adaptor_base &operator=\
(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)\
{\
outer_allocator_type::operator=(other.outer_allocator());\
m_inner = other.inner_allocator();\
return *this;\
}\
\
scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\
{\
outer_allocator_type::operator=(boost::move(other.outer_allocator()));\
m_inner = ::boost::move(other.inner_allocator());\
return *this;\
}\
\
void swap(scoped_allocator_adaptor_base &r)\
{\
boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());\
boost::adl_move_swap(this->m_inner, r.inner_allocator());\
}\
\
friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)\
{ l.swap(r); }\
\
inner_allocator_type& inner_allocator()\
{ return m_inner; }\
\
inner_allocator_type const& inner_allocator() const\
{ return m_inner; }\
\
outer_allocator_type & outer_allocator()\
{ return static_cast<outer_allocator_type&>(*this); }\
\
const outer_allocator_type &outer_allocator() const\
{ return static_cast<const outer_allocator_type&>(*this); }\
\
scoped_allocator_type select_on_container_copy_construction() const\
{\
return scoped_allocator_type\
(internal_type_t()\
,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())\
,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())\
);\
}\
private:\
inner_allocator_type m_inner;\
};\
//!
BOOST_MOVE_ITERATE_1TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE)
#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE
#endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE ,true
#define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER BOOST_MOVE_TARG9
#define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS BOOST_MOVE_CLASS9
#else
#define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE
#define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER InnerAllocs...
#define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS typename... InnerAllocs
#endif
//Specialization for adaptor without any InnerAlloc
template <typename OuterAlloc>
class scoped_allocator_adaptor_base< OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE>
: public OuterAlloc
{
BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)
public:
template <class U>
struct rebind_base
{
typedef scoped_allocator_adaptor_base
<typename allocator_traits<OuterAlloc>::template portable_rebind_alloc<U>::type
BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE > other;
};
typedef OuterAlloc outer_allocator_type;
typedef allocator_traits<OuterAlloc> outer_traits_type;
typedef scoped_allocator_adaptor<OuterAlloc> inner_allocator_type;
typedef inner_allocator_type scoped_allocator_type;
typedef allocator_traits<inner_allocator_type> inner_traits_type;
typedef typename outer_traits_type::
propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
typedef typename outer_traits_type::
propagate_on_container_move_assignment propagate_on_container_move_assignment;
typedef typename outer_traits_type::
propagate_on_container_swap propagate_on_container_swap;
typedef typename outer_traits_type::
is_always_equal is_always_equal;
scoped_allocator_adaptor_base()
{}
template <class OuterA2>
scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc)
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
{}
scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)
: outer_allocator_type(other.outer_allocator())
{}
scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
: outer_allocator_type(::boost::move(other.outer_allocator()))
{}
template <class OuterA2>
scoped_allocator_adaptor_base
(const scoped_allocator_adaptor_base<OuterA2 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE>& other)
: outer_allocator_type(other.outer_allocator())
{}
template <class OuterA2>
scoped_allocator_adaptor_base
(BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE> BOOST_RV_REF_END other)
: outer_allocator_type(other.outer_allocator())
{}
public:
struct internal_type_t{};
template <class OuterA2>
scoped_allocator_adaptor_base(internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &)
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
{}
public:
scoped_allocator_adaptor_base &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
{
outer_allocator_type::operator=(other.outer_allocator());
return *this;
}
scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
{
outer_allocator_type::operator=(boost::move(other.outer_allocator()));
return *this;
}
void swap(scoped_allocator_adaptor_base &r)
{
boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());
}
friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
{ l.swap(r); }
inner_allocator_type& inner_allocator()
{ return static_cast<inner_allocator_type&>(*this); }
inner_allocator_type const& inner_allocator() const
{ return static_cast<const inner_allocator_type&>(*this); }
outer_allocator_type & outer_allocator()
{ return static_cast<outer_allocator_type&>(*this); }
const outer_allocator_type &outer_allocator() const
{ return static_cast<const outer_allocator_type&>(*this); }
scoped_allocator_type select_on_container_copy_construction() const
{
return scoped_allocator_type
(internal_type_t()
,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
//Don't use inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
//as inner_allocator() is equal to *this and that would trigger an infinite loop
, this->inner_allocator()
);
}
};
} //namespace container_detail {
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//Scoped allocator
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
//! This class is a C++03-compatible implementation of std::scoped_allocator_adaptor.
//! The class template scoped_allocator_adaptor is an allocator template that specifies
//! the memory resource (the outer allocator) to be used by a container (as any other
//! allocator does) and also specifies an inner allocator resource to be passed to
//! the constructor of every element within the container.
//!
//! This adaptor is
//! instantiated with one outer and zero or more inner allocator types. If
//! instantiated with only one allocator type, the inner allocator becomes the
//! scoped_allocator_adaptor itself, thus using the same allocator resource for the
//! container and every element within the container and, if the elements themselves
//! are containers, each of their elements recursively. If instantiated with more than
//! one allocator, the first allocator is the outer allocator for use by the container,
//! the second allocator is passed to the constructors of the container's elements,
//! and, if the elements themselves are containers, the third allocator is passed to
//! the elements' elements, and so on. If containers are nested to a depth greater
//! than the number of allocators, the last allocator is used repeatedly, as in the
//! single-allocator case, for any remaining recursions.
//!
//! [<b>Note</b>: The
//! scoped_allocator_adaptor is derived from the outer allocator type so it can be
//! substituted for the outer allocator type in most expressions. -end note]
//!
//! In the construct member functions, <code>OUTERMOST(x)</code> is x if x does not have
//! an <code>outer_allocator()</code> member function and
//! <code>OUTERMOST(x.outer_allocator())</code> otherwise; <code>OUTERMOST_ALLOC_TRAITS(x)</code> is
//! <code>allocator_traits<decltype(OUTERMOST(x))></code>.
//!
//! [<b>Note</b>: <code>OUTERMOST(x)</code> and
//! <code>OUTERMOST_ALLOC_TRAITS(x)</code> are recursive operations. It is incumbent upon
//! the definition of <code>outer_allocator()</code> to ensure that the recursion terminates.
//! It will terminate for all instantiations of scoped_allocator_adaptor. -end note]
template <typename OuterAlloc, typename ...InnerAllocs>
class scoped_allocator_adaptor
#else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
template <typename OuterAlloc, typename ...InnerAllocs>
class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>
#endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template <typename OuterAlloc, BOOST_MOVE_CLASS9>
class scoped_allocator_adaptor
#endif
: public container_detail::scoped_allocator_adaptor_base
<OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>
{
BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor)
public:
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
typedef container_detail::scoped_allocator_adaptor_base
<OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> base_type;
typedef typename base_type::internal_type_t internal_type_t;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
typedef OuterAlloc outer_allocator_type;
//! Type: For exposition only
//!
typedef allocator_traits<OuterAlloc> outer_traits_type;
//! Type: <code>scoped_allocator_adaptor<OuterAlloc></code> if <code>sizeof...(InnerAllocs)</code> is zero; otherwise,
//! <code>scoped_allocator_adaptor<InnerAllocs...></code>.
typedef typename base_type::inner_allocator_type inner_allocator_type;
typedef allocator_traits<inner_allocator_type> inner_traits_type;
typedef typename outer_traits_type::value_type value_type;
typedef typename outer_traits_type::size_type size_type;
typedef typename outer_traits_type::difference_type difference_type;
typedef typename outer_traits_type::pointer pointer;
typedef typename outer_traits_type::const_pointer const_pointer;
typedef typename outer_traits_type::void_pointer void_pointer;
typedef typename outer_traits_type::const_void_pointer const_void_pointer;
//! Type: A type with a constant boolean <code>value</code> == true if
//!`allocator_traits<Allocator>:: propagate_on_container_copy_assignment::value` is
//! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
typedef typename base_type::
propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
//! Type: A type with a constant boolean <code>value</code> == true if
//!`allocator_traits<Allocator>:: propagate_on_container_move_assignment::value` is
//! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
typedef typename base_type::
propagate_on_container_move_assignment propagate_on_container_move_assignment;
//! Type: A type with a constant boolean <code>value</code> == true if
//! `allocator_traits<Allocator>:: propagate_on_container_swap::value` is
//! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
typedef typename base_type::
propagate_on_container_swap propagate_on_container_swap;
//! Type: A type with a constant boolean <code>value</code> == true if
//!`allocator_traits<Allocator>:: is_always_equal::value` is
//! true for all <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
typedef typename base_type::
is_always_equal is_always_equal;
//! Type: Rebinds scoped allocator to
//! <code>typedef scoped_allocator_adaptor
//! < typename outer_traits_type::template portable_rebind_alloc<U>::type
//! , InnerAllocs... ></code>
template <class U>
struct rebind
{
typedef scoped_allocator_adaptor
< typename outer_traits_type::template portable_rebind_alloc<U>::type
, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> other;
};
//! <b>Effects</b>: value-initializes the OuterAlloc base class
//! and the inner allocator object.
scoped_allocator_adaptor()
{}
~scoped_allocator_adaptor()
{}
//! <b>Effects</b>: initializes each allocator within the adaptor with
//! the corresponding allocator from other.
scoped_allocator_adaptor(const scoped_allocator_adaptor& other)
: base_type(other.base())
{}
//! <b>Effects</b>: move constructs each allocator within the adaptor with
//! the corresponding allocator from other.
scoped_allocator_adaptor(BOOST_RV_REF(scoped_allocator_adaptor) other)
: base_type(::boost::move(other.base()))
{}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Requires</b>: OuterAlloc shall be constructible from OuterA2.
//!
//! <b>Effects</b>: initializes the OuterAlloc base class with boost::forward<OuterA2>(outerAlloc) and inner
//! with innerAllocs...(hence recursively initializing each allocator within the adaptor with the
//! corresponding allocator from the argument list).
template <class OuterA2>
scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs & ...innerAllocs)
: base_type(::boost::forward<OuterA2>(outerAlloc), innerAllocs...)
{}
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE(N)\
template <class OuterA2>\
scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc BOOST_MOVE_I##N BOOST_MOVE_CREF##N)\
: base_type(::boost::forward<OuterA2>(outerAlloc) BOOST_MOVE_I##N BOOST_MOVE_ARG##N)\
{}\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE)
#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Requires</b>: OuterAlloc shall be constructible from OuterA2.
//!
//! <b>Effects</b>: initializes each allocator within the adaptor with the corresponding allocator from other.
template <class OuterA2>
scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> &other)
: base_type(other.base())
{}
//! <b>Requires</b>: OuterAlloc shall be constructible from OuterA2.
//!
//! <b>Effects</b>: initializes each allocator within the adaptor with the corresponding allocator
//! rvalue from other.
template <class OuterA2>
scoped_allocator_adaptor(BOOST_RV_REF_BEG scoped_allocator_adaptor
<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> BOOST_RV_REF_END other)
: base_type(::boost::move(other.base()))
{}
scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other)
{ return static_cast<scoped_allocator_adaptor&>(base_type::operator=(static_cast<const base_type &>(other))); }
scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other)
{ return static_cast<scoped_allocator_adaptor&>(base_type::operator=(boost::move(other.base()))); }
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
//! <b>Effects</b>: swaps *this with r.
//!
void swap(scoped_allocator_adaptor &r);
//! <b>Effects</b>: swaps *this with r.
//!
friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r);
//! <b>Returns</b>:
//! <code>static_cast<OuterAlloc&>(*this)</code>.
outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Returns</b>:
//! <code>static_cast<const OuterAlloc&>(*this)</code>.
const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Returns</b>:
//! *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Returns</b>:
//! *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
//! <b>Returns</b>:
//! <code>allocator_traits<OuterAlloc>:: max_size(outer_allocator())</code>.
size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return outer_traits_type::max_size(this->outer_allocator()); }
//! <b>Effects</b>:
//! calls <code>OUTERMOST_ALLOC_TRAITS(*this):: destroy(OUTERMOST(*this), p)</code>.
template <class T>
void destroy(T* p) BOOST_NOEXCEPT_OR_NOTHROW
{
allocator_traits<typename outermost_allocator<OuterAlloc>::type>
::destroy(get_outermost_allocator(this->outer_allocator()), p);
}
//! <b>Returns</b>:
//! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)</code>.
pointer allocate(size_type n)
{ return outer_traits_type::allocate(this->outer_allocator(), n); }
//! <b>Returns</b>:
//! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)</code>.
pointer allocate(size_type n, const_void_pointer hint)
{ return outer_traits_type::allocate(this->outer_allocator(), n, hint); }
//! <b>Effects</b>:
//! <code>allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n)</code>.
void deallocate(pointer p, size_type n)
{ outer_traits_type::deallocate(this->outer_allocator(), p, n); }
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
//! <b>Returns</b>: A new scoped_allocator_adaptor object where each allocator
//! Allocator in the adaptor is initialized from the result of calling
//! <code>allocator_traits<Allocator>::select_on_container_copy_construction()</code> on
//! the corresponding allocator in *this.
scoped_allocator_adaptor select_on_container_copy_construction() const;
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
base_type &base() { return *this; }
const base_type &base() const { return *this; }
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>:
//! 1) If <code>uses_allocator<T, inner_allocator_type>::value</code> is false calls
//! <code>OUTERMOST_ALLOC_TRAITS(*this)::
//! construct(OUTERMOST(*this), p, std::forward<Args>(args)...)</code>.
//!
//! 2) Otherwise, if <code>uses_allocator<T, inner_allocator_type>::value</code> is true and
//! <code>is_constructible<T, allocator_arg_t, inner_allocator_type, Args...>:: value</code> is true, calls
//! <code>OUTERMOST_ALLOC_TRAITS(*this):: construct(OUTERMOST(*this), p, allocator_arg,
//! inner_allocator(), std::forward<Args>(args)...)</code>.
//!
//! [<b>Note</b>: In compilers without advanced decltype SFINAE support, <code>is_constructible</code> can't
//! be implemented so that condition will be replaced by
//! constructible_with_allocator_prefix<T>::value. -end note]
//!
//! 3) Otherwise, if uses_allocator<T, inner_allocator_type>::value is true and
//! <code>is_constructible<T, Args..., inner_allocator_type>:: value</code> is true, calls
//! <code>OUTERMOST_ALLOC_TRAITS(*this):: construct(OUTERMOST(*this), p,
//! std::forward<Args>(args)..., inner_allocator())</code>.
//!
//! [<b>Note</b>: In compilers without advanced decltype SFINAE support, <code>is_constructible</code> can't be
//! implemented so that condition will be replaced by
//! <code>constructible_with_allocator_suffix<T>:: value</code>. -end note]
//!
//! 4) Otherwise, the program is ill-formed.
//!
//! [<b>Note</b>: An error will result if <code>uses_allocator</code> evaluates
//! to true but the specific constructor does not take an allocator. This definition prevents a silent
//! failure to pass an inner allocator to a contained element. -end note]
template < typename T, class ...Args>
void construct(T* p, BOOST_FWD_REF(Args)...args)
{
container_detail::dispatch_uses_allocator
( (get_outermost_allocator)(this->outer_allocator())
, this->inner_allocator(), p, ::boost::forward<Args>(args)...);
}
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//Disable this overload if the first argument is pair as some compilers have
//overload selection problems when the first parameter is a pair.
#define BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE(N) \
template < typename T BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\
void construct(T* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\
{\
container_detail::dispatch_uses_allocator\
( (get_outermost_allocator)(this->outer_allocator())\
, this->inner_allocator(), p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\
}\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE)
#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
//Internal function
template <class OuterA2>
scoped_allocator_adaptor(internal_type_t, BOOST_FWD_REF(OuterA2) outer, const inner_allocator_type& inner)
: base_type(internal_type_t(), ::boost::forward<OuterA2>(outer), inner)
{}
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
/// @cond
template<bool ZeroInner>
struct scoped_allocator_operator_equal
{
//Optimize equal outer allocator types with
//allocator_traits::equal which uses is_always_equal
template<class IA>
static bool equal_outer(const IA &l, const IA &r)
{ return allocator_traits<IA>::equal(l, r); }
//Otherwise compare it normally
template<class IA1, class IA2>
static bool equal_outer(const IA1 &l, const IA2 &r)
{ return l == r; }
//Otherwise compare it normally
template<class IA>
static bool equal_inner(const IA &l, const IA &r)
{ return allocator_traits<IA>::equal(l, r); }
};
template<>
struct scoped_allocator_operator_equal<true>
: scoped_allocator_operator_equal<false>
{
//when inner allocator count is zero,
//inner_allocator_type is the same as outer_allocator_type
//so both types can be different in operator==
template<class IA1, class IA2>
static bool equal_inner(const IA1 &, const IA2 &)
{ return true; }
};
/// @endcond
template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS>
inline bool operator==(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a
,const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& b)
{
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
const bool has_zero_inner = sizeof...(InnerAllocs) == 0u;
#else
const bool has_zero_inner = boost::container::container_detail::is_same<P0, void>::value;
#endif
typedef scoped_allocator_operator_equal<has_zero_inner> equal_t;
return equal_t::equal_outer(a.outer_allocator(), b.outer_allocator()) &&
equal_t::equal_inner(a.inner_allocator(), b.inner_allocator());
}
template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS>
inline bool operator!=(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a
,const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& b)
{ return !(a == b); }
}} // namespace boost { namespace container {
#include <boost/container/detail/config_end.hpp>
#endif // BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
@@ -0,0 +1,212 @@
//---------------------------------------------------------------------------//
// 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_DETAIL_FIND_IF_WITH_ATOMICS_HPP
#define BOOST_COMPUTE_ALGORITHM_DETAIL_FIND_IF_WITH_ATOMICS_HPP
#include <iterator>
#include <boost/compute/types.hpp>
#include <boost/compute/functional.hpp>
#include <boost/compute/command_queue.hpp>
#include <boost/compute/container/detail/scalar.hpp>
#include <boost/compute/iterator/buffer_iterator.hpp>
#include <boost/compute/type_traits/type_name.hpp>
#include <boost/compute/detail/meta_kernel.hpp>
#include <boost/compute/detail/iterator_range_size.hpp>
#include <boost/compute/detail/parameter_cache.hpp>
namespace boost {
namespace compute {
namespace detail {
template<class InputIterator, class UnaryPredicate>
inline InputIterator find_if_with_atomics_one_vpt(InputIterator first,
InputIterator last,
UnaryPredicate predicate,
const size_t count,
command_queue &queue)
{
typedef typename std::iterator_traits<InputIterator>::value_type value_type;
typedef typename std::iterator_traits<InputIterator>::difference_type difference_type;
const context &context = queue.get_context();
detail::meta_kernel k("find_if");
size_t index_arg = k.add_arg<int *>(memory_object::global_memory, "index");
atomic_min<uint_> atomic_min_uint;
k << k.decl<const uint_>("i") << " = get_global_id(0);\n"
<< k.decl<const value_type>("value") << "="
<< first[k.var<const uint_>("i")] << ";\n"
<< "if(" << predicate(k.var<const value_type>("value")) << "){\n"
<< " " << atomic_min_uint(k.var<uint_ *>("index"), k.var<uint_>("i")) << ";\n"
<< "}\n";
kernel kernel = k.compile(context);
scalar<uint_> index(context);
kernel.set_arg(index_arg, index.get_buffer());
// initialize index to the last iterator's index
index.write(static_cast<uint_>(count), queue);
queue.enqueue_1d_range_kernel(kernel, 0, count, 0);
// read index and return iterator
return first + static_cast<difference_type>(index.read(queue));
}
template<class InputIterator, class UnaryPredicate>
inline InputIterator find_if_with_atomics_multiple_vpt(InputIterator first,
InputIterator last,
UnaryPredicate predicate,
const size_t count,
const size_t vpt,
command_queue &queue)
{
typedef typename std::iterator_traits<InputIterator>::value_type value_type;
typedef typename std::iterator_traits<InputIterator>::difference_type difference_type;
const context &context = queue.get_context();
const device &device = queue.get_device();
detail::meta_kernel k("find_if");
size_t index_arg = k.add_arg<uint_ *>(memory_object::global_memory, "index");
size_t count_arg = k.add_arg<const uint_>("count");
size_t vpt_arg = k.add_arg<const uint_>("vpt");
atomic_min<uint_> atomic_min_uint;
// for GPUs reads from global memory are coalesced
if(device.type() & device::gpu) {
k <<
k.decl<const uint_>("lsize") << " = get_local_size(0);\n" <<
k.decl<uint_>("id") << " = get_local_id(0) + get_group_id(0) * lsize * vpt;\n" <<
k.decl<const uint_>("end") << " = min(" <<
"id + (lsize *" << k.var<uint_>("vpt") << ")," <<
"count" <<
");\n" <<
// checking if the index is already found
"__local uint local_index;\n" <<
"if(get_local_id(0) == 0){\n" <<
" local_index = *index;\n " <<
"};\n" <<
"barrier(CLK_LOCAL_MEM_FENCE);\n" <<
"if(local_index < id){\n" <<
" return;\n" <<
"}\n" <<
"while(id < end){\n" <<
" " << k.decl<const value_type>("value") << " = " <<
first[k.var<const uint_>("id")] << ";\n"
" if(" << predicate(k.var<const value_type>("value")) << "){\n" <<
" " << atomic_min_uint(k.var<uint_ *>("index"),
k.var<uint_>("id")) << ";\n" <<
" return;\n"
" }\n" <<
" id+=lsize;\n" <<
"}\n";
// for CPUs (and other devices) reads are ordered so the big cache is
// efficiently used.
} else {
k <<
k.decl<uint_>("id") << " = get_global_id(0) * " << k.var<uint_>("vpt") << ";\n" <<
k.decl<const uint_>("end") << " = min(" <<
"id + " << k.var<uint_>("vpt") << "," <<
"count" <<
");\n" <<
"while(id < end && (*index) > id){\n" <<
" " << k.decl<const value_type>("value") << " = " <<
first[k.var<const uint_>("id")] << ";\n"
" if(" << predicate(k.var<const value_type>("value")) << "){\n" <<
" " << atomic_min_uint(k.var<uint_ *>("index"),
k.var<uint_>("id")) << ";\n" <<
" return;\n" <<
" }\n" <<
" id++;\n" <<
"}\n";
}
kernel kernel = k.compile(context);
scalar<uint_> index(context);
kernel.set_arg(index_arg, index.get_buffer());
kernel.set_arg(count_arg, static_cast<uint_>(count));
kernel.set_arg(vpt_arg, static_cast<uint_>(vpt));
// initialize index to the last iterator's index
index.write(static_cast<uint_>(count), queue);
const size_t global_wg_size = static_cast<size_t>(
std::ceil(float(count) / vpt)
);
queue.enqueue_1d_range_kernel(kernel, 0, global_wg_size, 0);
// read index and return iterator
return first + static_cast<difference_type>(index.read(queue));
}
template<class InputIterator, class UnaryPredicate>
inline InputIterator find_if_with_atomics(InputIterator first,
InputIterator last,
UnaryPredicate predicate,
command_queue &queue)
{
typedef typename std::iterator_traits<InputIterator>::value_type value_type;
size_t count = detail::iterator_range_size(first, last);
if(count == 0){
return last;
}
const device &device = queue.get_device();
// load cached parameters
std::string cache_key = std::string("__boost_find_if_with_atomics_")
+ type_name<value_type>();
boost::shared_ptr<parameter_cache> parameters =
detail::parameter_cache::get_global_cache(device);
// for relatively small inputs on GPUs kernel checking one value per thread
// (work-item) is more efficient than its multiple values per thread version
if(device.type() & device::gpu){
const size_t one_vpt_threshold =
parameters->get(cache_key, "one_vpt_threshold", 1048576);
if(count <= one_vpt_threshold){
return find_if_with_atomics_one_vpt(
first, last, predicate, count, queue
);
}
}
// values per thread
size_t vpt;
if(device.type() & device::gpu){
// get vpt parameter
vpt = parameters->get(cache_key, "vpt", 32);
} else {
// for CPUs work is split equally between compute units
const size_t max_compute_units =
device.get_info<CL_DEVICE_MAX_COMPUTE_UNITS>();
vpt = static_cast<size_t>(
std::ceil(float(count) / max_compute_units)
);
}
return find_if_with_atomics_multiple_vpt(
first, last, predicate, count, vpt, queue
);
}
} // end detail namespace
} // end compute namespace
} // end boost namespace
#endif // BOOST_COMPUTE_ALGORITHM_DETAIL_FIND_IF_WITH_ATOMICS_HPP
@@ -0,0 +1,25 @@
#ifndef BOOST_MPL_KEY_TYPE_FWD_HPP_INCLUDED
#define BOOST_MPL_KEY_TYPE_FWD_HPP_INCLUDED
// Copyright Aleksey Gurtovoy 2003-2004
// Copyright David Abrahams 2003-2004
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/mpl for documentation.
// $Id$
// $Date$
// $Revision$
namespace boost { namespace mpl {
template< typename Tag > struct key_type_impl;
template< typename AssociativeSequence, typename T > struct key_type;
}}
#endif // BOOST_MPL_KEY_TYPE_FWD_HPP_INCLUDED
@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="Layer_1"
space="preserve"
sodipodi:version="0.32"
viewBox="0 0 640 480"
version="1.1"
sodipodi:docname="tasto_5_architetto_franc_01.svg"
inkscape:version="0.48.4 r9939"
width="100%"
height="100%">
<defs
id="defs6110" />
<sodipodi:namedview
id="base"
bordercolor="#666666"
borderopacity="1.0"
pagecolor="#ffffff"
showgrid="false"
inkscape:zoom="1.89375"
inkscape:cx="227.06271"
inkscape:cy="240"
inkscape:window-width="1855"
inkscape:window-height="1056"
inkscape:window-x="65"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="g3" />
<g
id="g3"
transform="translate(0,342.62101)">
<radialGradient
id="XMLID_2_"
gradientUnits="userSpaceOnUse"
cy="42.188999"
cx="42.785999"
r="69.833"
gradientTransform="translate(237.98657,-269.79195)">
<stop
id="stop6"
stop-color="#D1F593"
offset="0" />
<stop
id="stop8"
stop-color="#81CE09"
offset="1" />
</radialGradient>
<path
id="path10"
d="m 294.86757,-261.31295 v 11.564 c 0,1.741 1.297,11.914 0,13.039 -1.02,0.886 -6.762,0 -8.05,0 h -18.478 c -7.957,0 -22.38,-2.722 -27.218,5.536 -3.929,6.711 -1.526,19.418 -1.526,26.711 0,8.382 -0.774,17.167 0,25.519 0,13.355 15.573,11.178 24.427,11.178 h 30.258 c 1.235,0 0.587,21.391 0.587,24.12 0,9.468 9.867,13.694 16.696,6.885 5.979,-5.956 11.956,-11.914 17.934,-17.874 12.723,-12.681 27.184,-24.79 38.705,-38.581 8.129,-8.157 -0.109,-15.919 -5.847,-21.664 -7.818,-7.824 -15.637,-15.65 -23.456,-23.475 -7.681,-7.69 -15.364,-15.38 -23.047,-23.068 -4.98,-4.985 -11.292,-11.356 -18.616,-5 -1.493,1.285 -2.366,3.107 -2.366,5.097"
inkscape:connector-curvature="0"
style="fill:url(#XMLID_2_)" />
<path
id="path12"
d="m 239.59557,-225.52895 v 25.519 c 0,7.292 -2.404,20 1.526,26.707 4.839,8.26 19.258,5.537 27.214,5.537 h 17.257 c 1.47,0 8.123,-1.016 9.274,0 1.14,1.006 0,9.882 0,11.396 v 14.252 c 0,10.854 12.136,9.904 17.771,4.287 15.045,-14.996 30.09,-29.993 45.136,-44.991 5.456,-5.438 15.865,-12.589 13.176,-21.487 -0.317,0.598 -3.726,2.826 -4.396,3.495 -3.066,3.059 -6.136,6.117 -9.201,9.174 -8.52,8.492 -17.037,16.985 -25.555,25.477 -5.672,5.654 -11.342,11.308 -17.012,16.961 -2.447,2.439 -6.51,4.557 -9.908,2.681 -4.008,-2.21 -2.962,-8.699 -2.962,-12.543 v -15.579 c 0,-2.856 -2.156,-1.731 -4.79,-1.731 h -33.59 c -8.25,0 -16.507,-0.511 -16.507,-10.853 v -32.609 c 0,-4.972 -1.083,-11.582 0.677,-16.393 -4.732,1.342 -8.114,5.758 -8.114,10.688"
inkscape:connector-curvature="0"
style="fill:#67ba06" />
<path
id="path14"
d="m 247.70757,-168.51195 c -2.771,-7.597 -0.677,-18.748 -0.677,-26.612 0,-8.349 -1.456,-18.099 0.173,-26.347 1.843,-9.349 18.409,-6.667 25.217,-6.667 h 29.23 c 0.768,0 -0.319,-21.606 0.808,-24.748 3.407,-9.491 12.963,0.134 16.668,3.857 15.269,15.341 30.538,30.681 45.805,46.022 1.224,1.231 5.246,3.916 6.019,5.379 2.872,-9.511 -10.045,-18.432 -15.802,-24.213 l -32.322,-32.461 c -5.208,-5.23 -12.42,-16.139 -21.006,-14.488 -11.102,2.133 -6.951,23.787 -6.951,31.819 -9.333,0 -18.663,-0.002 -27.996,-0.002 -9.16,-0.001 -27.276,-2.955 -27.276,11.18 -0.863,9.313 0,19.11 0,28.458 0,8.799 -3.183,25.591 8.112,28.823"
inkscape:connector-curvature="0"
style="fill:#b2ed21" />
<path
id="path16"
d="m 299.44057,-268.80395 c -9.2,3.806 -5.476,22.395 -5.476,30.261 0,1.951 -23.229,0.93 -26.087,0.93 -8.576,0 -23.012,-2.757 -27.835,6.535 -3.627,6.99 -1.35,19.146 -1.35,26.616 0,8.4 -0.709,17.143 0,25.519 0,13.884 15.395,12.081 24.75,12.081 h 30.326 c 0.616,0 -0.196,23.651 0.363,26.81 1.344,7.601 11.873,10.134 17.171,4.83 1.235,-0.97 2.304,-2.297 3.414,-3.404 6.86,-6.837 13.72,-13.676 20.579,-20.514 7.706,-7.681 15.41,-15.36 23.116,-23.042 4.011,-3.997 10.436,-8.579 12.863,-13.906 3.874,-8.509 -2.996,-14.135 -8.281,-19.426 -7.462,-7.47 -14.926,-14.941 -22.389,-22.411 -7.348,-7.353 -14.693,-14.708 -22.041,-22.061 -5.328,-5.353 -10.368,-12.444 -19.115,-8.826 m -58.942,89.86 v -25.519 c 0,-7.083 -2.537,-20.456 1.757,-26.809 4.938,-7.304 19.854,-4.536 27.283,-4.536 h 17.136 c 1.448,0 7.955,0.999 9.096,0 1.124,-0.984 0,-9.795 0,-11.286 v -14.11 c 0,-6.577 10.11,-8.923 14.281,-4.749 1.512,1.514 3.024,3.027 4.536,4.539 l 46.438,46.479 c 5.123,5.13 13.199,11.335 7.847,19.468 -3.387,5.148 -9.155,9.432 -13.47,13.732 -14.601,14.553 -29.201,29.107 -43.802,43.659 -2.575,2.568 -5.353,4.298 -9.308,3.666 -6.041,-0.967 -6.522,-6.041 -6.522,-10.962 0,-3.029 1.173,-23.3 -1.004,-23.3 h -29.582 c -8.374,-0.01 -24.69,2.6 -24.69,-10.282"
inkscape:connector-curvature="0"
style="fill:#739b07" />
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#ff7400;fill-opacity:0.77254902;stroke:none;font-family:Purisa;-inkscape-font-specification:Sans Bold"
x="316.39532"
y="-58.000538"
id="text6112"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan6114"
x="316.39532"
y="-58.000538">Drag the icon</tspan><tspan
sodipodi:role="line"
x="316.39532"
y="-8.0005379"
id="tspan6116">onto the link</tspan><tspan
sodipodi:role="line"
x="316.39532"
y="41.999462"
id="tspan6118">to install WSJT-X</tspan></text>
</g>
<metadata
id="metadata6108">
<rdf:RDF>
<cc:Work>
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<cc:license
rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
<dc:publisher>
<cc:Agent
rdf:about="http://openclipart.org/">
<dc:title>Openclipart</dc:title>
</cc:Agent>
</dc:publisher>
<dc:title></dc:title>
<dc:date>2010-03-28T09:25:56</dc:date>
<dc:description>Drawing by Francesco 'Architetto' Rollandin. From OCAL 0.18 release.</dc:description>
<dc:source>http://openclipart.org/detail/34711/architetto----tasto-5-by-anonymous</dc:source>
<dc:creator>
<cc:Agent>
<dc:title>Anonymous</dc:title>
</cc:Agent>
</dc:creator>
<dc:subject>
<rdf:Bag>
<rdf:li>arrow</rdf:li>
<rdf:li>clip art</rdf:li>
<rdf:li>clipart</rdf:li>
<rdf:li>green</rdf:li>
<rdf:li>icon</rdf:li>
<rdf:li>right</rdf:li>
<rdf:li>sign</rdf:li>
<rdf:li>symbol</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/publicdomain/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
</svg>

After

Width:  |  Height:  |  Size: 7.6 KiB

@@ -0,0 +1,97 @@
// 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/aux_/advance_backward.hpp" header
// -- DO NOT modify by hand!
namespace boost { namespace mpl { namespace aux {
template< long N > struct advance_backward;
template<>
struct advance_backward<0>
{
template< typename Iterator > struct apply
{
typedef Iterator iter0;
typedef iter0 type;
};
};
template<>
struct advance_backward<1>
{
template< typename Iterator > struct apply
{
typedef Iterator iter0;
typedef typename prior<iter0>::type iter1;
typedef iter1 type;
};
};
template<>
struct advance_backward<2>
{
template< typename Iterator > struct apply
{
typedef Iterator iter0;
typedef typename prior<iter0>::type iter1;
typedef typename prior<iter1>::type iter2;
typedef iter2 type;
};
};
template<>
struct advance_backward<3>
{
template< typename Iterator > struct apply
{
typedef Iterator iter0;
typedef typename prior<iter0>::type iter1;
typedef typename prior<iter1>::type iter2;
typedef typename prior<iter2>::type iter3;
typedef iter3 type;
};
};
template<>
struct advance_backward<4>
{
template< typename Iterator > struct apply
{
typedef Iterator iter0;
typedef typename prior<iter0>::type iter1;
typedef typename prior<iter1>::type iter2;
typedef typename prior<iter2>::type iter3;
typedef typename prior<iter3>::type iter4;
typedef iter4 type;
};
};
template< long N >
struct advance_backward
{
template< typename Iterator > struct apply
{
typedef typename apply_wrap1<
advance_backward<4>
, Iterator
>::type chunk_result_;
typedef typename apply_wrap1<
advance_backward<(
(N - 4) < 0
? 0
: N - 4
)>
, chunk_result_
>::type type;
};
};
}}}
@@ -0,0 +1,23 @@
#ifndef BOOST_MPL_AUX_HAS_SIZE_HPP_INCLUDED
#define BOOST_MPL_AUX_HAS_SIZE_HPP_INCLUDED
// Copyright Aleksey Gurtovoy 2002-2004
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/mpl for documentation.
// $Id$
// $Date$
// $Revision$
#include <boost/mpl/has_xxx.hpp>
namespace boost { namespace mpl { namespace aux {
BOOST_MPL_HAS_XXX_TRAIT_DEF(size)
}}}
#endif // BOOST_MPL_AUX_HAS_SIZE_HPP_INCLUDED
@@ -0,0 +1,193 @@
// 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/list/list40_c.hpp" header
// -- DO NOT modify by hand!
namespace boost { namespace mpl {
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30
>
struct list31_c
: l_item<
long_<31>
, integral_c< T,C0 >
, list30_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30 >
>
{
typedef list31_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30
, T C31
>
struct list32_c
: l_item<
long_<32>
, integral_c< T,C0 >
, list31_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31 >
>
{
typedef list32_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30
, T C31, T C32
>
struct list33_c
: l_item<
long_<33>
, integral_c< T,C0 >
, list32_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32 >
>
{
typedef list33_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30
, T C31, T C32, T C33
>
struct list34_c
: l_item<
long_<34>
, integral_c< T,C0 >
, list33_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33 >
>
{
typedef list34_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30
, T C31, T C32, T C33, T C34
>
struct list35_c
: l_item<
long_<35>
, integral_c< T,C0 >
, list34_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34 >
>
{
typedef list35_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30
, T C31, T C32, T C33, T C34, T C35
>
struct list36_c
: l_item<
long_<36>
, integral_c< T,C0 >
, list35_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35 >
>
{
typedef list36_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30
, T C31, T C32, T C33, T C34, T C35, T C36
>
struct list37_c
: l_item<
long_<37>
, integral_c< T,C0 >
, list36_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36 >
>
{
typedef list37_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30
, T C31, T C32, T C33, T C34, T C35, T C36, T C37
>
struct list38_c
: l_item<
long_<38>
, integral_c< T,C0 >
, list37_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37 >
>
{
typedef list38_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30
, T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38
>
struct list39_c
: l_item<
long_<39>
, integral_c< T,C0 >
, list38_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38 >
>
{
typedef list39_c type;
typedef T value_type;
};
template<
typename T
, T C0, T C1, T C2, T C3, T C4, T C5, T C6, T C7, T C8, T C9, T C10
, T C11, T C12, T C13, T C14, T C15, T C16, T C17, T C18, T C19, T C20
, T C21, T C22, T C23, T C24, T C25, T C26, T C27, T C28, T C29, T C30
, T C31, T C32, T C33, T C34, T C35, T C36, T C37, T C38, T C39
>
struct list40_c
: l_item<
long_<40>
, integral_c< T,C0 >
, list39_c< T,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32,C33,C34,C35,C36,C37,C38,C39 >
>
{
typedef list40_c type;
typedef T value_type;
};
}}
@@ -0,0 +1,48 @@
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//
// See http://www.boost.org/libs/type_traits for most recent version including documentation.
#ifndef BOOST_TT_HAS_TRIVIAL_DESTRUCTOR_HPP_INCLUDED
#define BOOST_TT_HAS_TRIVIAL_DESTRUCTOR_HPP_INCLUDED
#include <boost/type_traits/intrinsics.hpp>
#include <boost/type_traits/integral_constant.hpp>
#ifdef BOOST_HAS_TRIVIAL_DESTRUCTOR
#if defined(BOOST_INTEL) || defined(BOOST_MSVC)
#include <boost/type_traits/is_pod.hpp>
#endif
#ifdef BOOST_HAS_SGI_TYPE_TRAITS
#include <boost/type_traits/is_same.hpp>
#endif
#if defined(__GNUC__) || defined(__clang__) || defined(__SUNPRO_CC)
#include <boost/type_traits/is_destructible.hpp>
#endif
namespace boost {
template <typename T> struct has_trivial_destructor : public integral_constant<bool, BOOST_HAS_TRIVIAL_DESTRUCTOR(T)>{};
#else
#include <boost/type_traits/is_pod.hpp>
namespace boost{
template <typename T> struct has_trivial_destructor : public integral_constant<bool, ::boost::is_pod<T>::value>{};
#endif
template <> struct has_trivial_destructor<void> : public false_type{};
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
template <> struct has_trivial_destructor<void const> : public false_type{};
template <> struct has_trivial_destructor<void const volatile> : public false_type{};
template <> struct has_trivial_destructor<void volatile> : public false_type{};
#endif
} // namespace boost
#endif // BOOST_TT_HAS_TRIVIAL_DESTRUCTOR_HPP_INCLUDED
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,159 @@
// 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/vector/vector20.hpp" header
// -- DO NOT modify by hand!
namespace boost { namespace mpl {
template<
typename T0, typename T1, typename T2, typename T3, typename T4
, typename T5, typename T6, typename T7, typename T8, typename T9
, typename T10
>
struct vector11
: v_item<
T10
, vector10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >
>
{
typedef vector11 type;
};
template<
typename T0, typename T1, typename T2, typename T3, typename T4
, typename T5, typename T6, typename T7, typename T8, typename T9
, typename T10, typename T11
>
struct vector12
: v_item<
T11
, vector11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >
>
{
typedef vector12 type;
};
template<
typename T0, typename T1, typename T2, typename T3, typename T4
, typename T5, typename T6, typename T7, typename T8, typename T9
, typename T10, typename T11, typename T12
>
struct vector13
: v_item<
T12
, vector12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >
>
{
typedef vector13 type;
};
template<
typename T0, typename T1, typename T2, typename T3, typename T4
, typename T5, typename T6, typename T7, typename T8, typename T9
, typename T10, typename T11, typename T12, typename T13
>
struct vector14
: v_item<
T13
, vector13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >
>
{
typedef vector14 type;
};
template<
typename T0, typename T1, typename T2, typename T3, typename T4
, typename T5, typename T6, typename T7, typename T8, typename T9
, typename T10, typename T11, typename T12, typename T13, typename T14
>
struct vector15
: v_item<
T14
, vector14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >
>
{
typedef vector15 type;
};
template<
typename T0, typename T1, typename T2, typename T3, typename T4
, typename T5, typename T6, typename T7, typename T8, typename T9
, typename T10, typename T11, typename T12, typename T13, typename T14
, typename T15
>
struct vector16
: v_item<
T15
, vector15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >
>
{
typedef vector16 type;
};
template<
typename T0, typename T1, typename T2, typename T3, typename T4
, typename T5, typename T6, typename T7, typename T8, typename T9
, typename T10, typename T11, typename T12, typename T13, typename T14
, typename T15, typename T16
>
struct vector17
: v_item<
T16
, vector16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >
>
{
typedef vector17 type;
};
template<
typename T0, typename T1, typename T2, typename T3, typename T4
, typename T5, typename T6, typename T7, typename T8, typename T9
, typename T10, typename T11, typename T12, typename T13, typename T14
, typename T15, typename T16, typename T17
>
struct vector18
: v_item<
T17
, vector17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >
>
{
typedef vector18 type;
};
template<
typename T0, typename T1, typename T2, typename T3, typename T4
, typename T5, typename T6, typename T7, typename T8, typename T9
, typename T10, typename T11, typename T12, typename T13, typename T14
, typename T15, typename T16, typename T17, typename T18
>
struct vector19
: v_item<
T18
, vector18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >
>
{
typedef vector19 type;
};
template<
typename T0, typename T1, typename T2, typename T3, typename T4
, typename T5, typename T6, typename T7, typename T8, typename T9
, typename T10, typename T11, typename T12, typename T13, typename T14
, typename T15, typename T16, typename T17, typename T18, typename T19
>
struct vector20
: v_item<
T19
, vector19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >
>
{
typedef vector20 type;
};
}}
@@ -0,0 +1,304 @@
subroutine syncmsk(cdat,npts,jpk,ipk,idf,rmax,snr,metric,decoded)
! Attempt synchronization, and if successful decode using Viterbi algorithm.
use iso_c_binding, only: c_loc,c_size_t
use packjt
use hashing
use timer_module, only: timer
parameter (NSPM=1404,NSAVE=2000)
complex cdat(npts) !Analytic signal
complex cb(66) !Complex waveform for Barker-11 code
complex cd(0:11,0:3)
complex c(0:NSPM-1) !Complex data for one message length
complex c2(0:NSPM-1)
complex cb3(1:NSPM,3)
real r(12000)
real rdat(12000)
real ss1(12000)
real symbol(234)
real rdata(198)
real rd2(198)
real rsave(NSAVE)
real xp(29)
complex z,z0,z1,z2,z3,cfac
integer*1 e1(198)
integer*1, target :: d8(13)
integer*1 i1hash(4)
integer*1 i1
integer*4 i4Msg6BitWords(12) !72-bit message as 6-bit words
integer mettab(0:255,0:1) !Metric table for BPSK modulation
integer ipksave(NSAVE)
integer jpksave(NSAVE)
integer indx(NSAVE)
integer b11(11) !Barker-11 code
character*22 decoded
character*72 c72
logical first
equivalence (i1,i4)
equivalence (ihash,i1hash)
data xp/0.500000, 0.401241, 0.309897, 0.231832, 0.168095, &
0.119704, 0.083523, 0.057387, 0.039215, 0.026890, &
0.018084, 0.012184, 0.008196, 0.005475, 0.003808, &
0.002481, 0.001710, 0.001052, 0.000789, 0.000469, &
0.000329, 0.000225, 0.000187, 0.000086, 0.000063, &
0.000017, 0.000091, 0.000032, 0.000045/
data first/.true./
data b11/1,1,1,0,0,0,1,0,0,1,0/
save first,cb,cd,twopi,dt,f0,f1,mettab
phi=0.
if(first) then
! Get the metric table
bias=0.0
scale=20.0
xln2=log(2.0)
mettab=0
do i=128,156
x0=log(max(0.001,2.0*xp(i-127)))/xln2
x1=log(max(0.001,2.0*(1.0-xp(i-127))))/xln2
mettab(i,0)=nint(scale*(x0-bias))
mettab(i,1)=nint(scale*(x1-bias))
mettab(256-i,0)=mettab(i,1)
mettab(256-i,1)=mettab(i,0)
enddo
do i=157,255
mettab(i,0)=mettab(156,0)
mettab(i,1)=mettab(156,1)
mettab(256-i,0)=mettab(i,1)
mettab(256-i,1)=mettab(i,0)
enddo
j=0
twopi=8.0*atan(1.0)
dt=1.0/12000.0
f0=1000.0
f1=2000.0
dphi=0
do i=1,11
if(b11(i).eq.0) dphi=twopi*f0*dt
if(b11(i).eq.1) dphi=twopi*f1*dt
do n=1,6
j=j+1
phi=phi+dphi
cb(j)=cmplx(cos(phi),sin(phi))
enddo
enddo
cb3=0.
cb3(1:66,1)=cb
cb3(283:348,1)=cb
cb3(769:834,1)=cb
cb3(1:66,2)=cb
cb3(487:552,2)=cb
cb3(1123:1188,2)=cb
cb3(1:66,3)=cb
cb3(637:702,3)=cb
cb3(919:984,3)=cb
phi=0.
do n=0,3
k=-1
dphi=twopi*f0*dt
if(n.ge.2) dphi=twopi*f1*dt
do i=0,5
k=k+1
phi=phi+dphi
if(phi.gt.twopi) phi=phi-twopi
cd(k,n)=cmplx(cos(phi),sin(phi))
enddo
dphi=twopi*f0*dt
if(mod(n,2).eq.1) dphi=twopi*f1*dt
do i=6,11
k=k+1
phi=phi+dphi
if(phi.gt.twopi) phi=phi-twopi
cd(k,n)=cmplx(cos(phi),sin(phi))
enddo
enddo
first=.false.
endif
nfft=NSPM
jz=npts-nfft
decoded=" "
ipk=0
jpk=0
metric=-9999
r=0.
call timer('sync1 ',0)
do j=1,jz !Find the Barker-11 sync vectors
z=0.
ss=0.
do i=1,66
ss=ss + real(cdat(j+i-1))**2 + aimag(cdat(j+i-1))**2
z=z + cdat(j+i-1)*conjg(cb(i)) !Signal matching Barker 11
enddo
ss=sqrt(ss/66.0)*66.0
r(j)=abs(z)/(0.908*ss) !Goodness-of-fit to Barker 11
ss1(j)=ss
enddo
call timer('sync1 ',1)
call timer('sync2 ',0)
jz=npts-nfft
rmax=0.
! n1=35, n2=69, n3=94
k=0
do j=1,jz !Find best full-message sync
if(ss1(j).lt.85.0) cycle
r1=r(j) + r(j+282) + r(j+768) ! 6*(12+n1) 6*(24+n1+n2)
r2=r(j) + r(j+486) + r(j+1122) ! 6*(12+n2) 6*(24+n2+n3)
r3=r(j) + r(j+636) + r(j+918) ! 6*(12+n3) 6*(24+n3+n1)
if(r1.gt.rmax) then
rmax=r1
jpk=j
ipk=1
endif
if(r2.gt.rmax) then
rmax=r2
jpk=j
ipk=2
endif
if(r3.gt.rmax) then
rmax=r3
jpk=j
ipk=3
endif
rrmax=max(r1,r2,r3)
if(rrmax.gt.1.9) then
k=min(k+1,NSAVE)
if(r1.eq.rrmax) ipksave(k)=1
if(r2.eq.rrmax) ipksave(k)=2
if(r3.eq.rrmax) ipksave(k)=3
jpksave(k)=j
rsave(k)=rrmax
endif
enddo
call timer('sync2 ',1)
kmax=k
call indexx(rsave,kmax,indx)
call timer('sync3 ',0)
do kk=1,kmax
k=indx(kmax+1-kk)
ipk=ipksave(k)
jpk=jpksave(k)
rmax=rsave(k)
c=conjg(cb3(1:NSPM,ipk))*cdat(jpk:jpk+nfft-1)
smax=0.
dfx=0.
idfbest=0
do itry=1,25
idf=itry/2
if(mod(itry,2).eq.0) idf=-idf
idf=4*idf
twk=idf
call tweak1(c,NSPM,-twk,c2)
z=sum(c2)
if(abs(z).gt.smax) then
dfx=twk
smax=abs(z)
phi=atan2(aimag(z),real(z)) !Carrier phase offset
idfbest=idf
endif
enddo
idf=idfbest
call tweak1(cdat,npts,-dfx,cdat)
cfac=cmplx(cos(phi),-sin(phi))
cdat=cfac*cdat
sig=0.
ref=0.
rdat(1:npts)=cdat
iz=11
do k=1,234 !Compute soft symbols
j=jpk+6*(k-1)
z0=2.0*dot_product(cdat(j:j+iz),cd(0:iz,0))
z1=2.0*dot_product(cdat(j:j+iz),cd(0:iz,1))
z2=2.0*dot_product(cdat(j:j+iz),cd(0:iz,2))
z3=2.0*dot_product(cdat(j:j+iz),cd(0:iz,3))
!### Maybe these should be weighted by yellow() ?
if(j+1404+iz.lt.npts) then
z0=z0 + dot_product(cdat(j+1404:j+1404+iz),cd(0:iz,0))
z1=z1 + dot_product(cdat(j+1404:j+1404+iz),cd(0:iz,1))
z2=z2 + dot_product(cdat(j+1404:j+1404+iz),cd(0:iz,2))
z3=z3 + dot_product(cdat(j+1404:j+1404+iz),cd(0:iz,3))
endif
if(j-1404.ge.1) then
z0=z0 + dot_product(cdat(j-1404:j-1404+iz),cd(0:iz,0))
z1=z1 + dot_product(cdat(j-1404:j-1404+iz),cd(0:iz,1))
z2=z2 + dot_product(cdat(j-1404:j-1404+iz),cd(0:iz,2))
z3=z3 + dot_product(cdat(j-1404:j-1404+iz),cd(0:iz,3))
endif
sym=max(abs(real(z2)),abs(real(z3))) - max(abs(real(z0)),abs(real(z1)))
if(sym.lt.0.0) then
phi=atan2(aimag(z0),real(z0))
sig=sig + real(z0)**2
ref=ref + aimag(z0)**2
else
phi=atan2(aimag(z1),real(z1))
sig=sig + real(z1)**2
ref=ref + aimag(z1)**2
endif
n=k
if(ipk.eq.2) n=k+47
if(ipk.eq.3) n=k+128
if(n.gt.234) n=n-234
ibit=0
if(sym.ge.0) ibit=1
symbol(n)=sym
enddo
snr=db(sig/ref-1.0)
rdata(1:35)=symbol(12:46)
rdata(36:104)=symbol(59:127)
rdata(105:198)=symbol(140:233)
! Re-order the symbols and make them i*1
j=0
do i=1,99
i4=128+rdata(i) !### Should be nint() ??? ###
if(i4.gt.255) i4=255
if(i4.lt.0) i4=0
j=j+1
e1(j)=i1
rd2(j)=rdata(i)
i4=128+rdata(i+99)
if(i4.gt.255) i4=255
if(i4.lt.0) i4=0
j=j+1
e1(j)=i1
rd2(j)=rdata(i+99)
enddo
! Decode the message
nb1=87
call vit213(e1,nb1,mettab,d8,metric)
ihash=nhash(c_loc(d8),int(9,c_size_t),146)
ihash=2*iand(ihash,32767)
decoded=' '
if(d8(10).eq.i1hash(2) .and. d8(11).eq.i1hash(1)) then
write(c72,1012) d8(1:9)
1012 format(9b8.8)
read(c72,1014) i4Msg6BitWords
1014 format(12b6.6)
call unpackmsg(i4Msg6BitWords,decoded,.false.,' ') !Unpack to get msgsent
endif
if(decoded.ne.' ') exit
enddo
call timer('sync3 ',1)
return
end subroutine syncmsk