Initial Commit
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
For this step and the next, you may want to pretend you are K1JT
|
||||
by entering that callsign temporarily as *My Call* on the
|
||||
*Settings | General* tab. Your results should then be identical to
|
||||
those shown in the screen shot below.
|
||||
|
||||
.Open a Wave File:
|
||||
|
||||
- Select *File | Open* and select the file
|
||||
+...\save\samples\JT9\130418_1742.wav+. When the file opens you should
|
||||
see something similar to the following screen shot:
|
||||
|
||||
[[X12]]
|
||||
image::main-ui.png[align="center",alt="Main UI and Wide Graph"]
|
||||
|
||||
.Decoding Overview
|
||||
|
||||
Decoding takes place at the end of a receive sequence and proceeds in
|
||||
two steps. The first decode is done at the selected Rx frequency,
|
||||
indicated by the U-shaped green marker on the waterfall frequency
|
||||
scale. Results appear in both the left (*Band Activity*) and right
|
||||
(*Rx Frequency*) text windows on the main screen. The program then
|
||||
finds and decodes all signals in the selected mode over the displayed
|
||||
frequency range. The red marker on the waterfall scale indicates your
|
||||
Tx frequency.
|
||||
|
||||
Seven JT9 signals are present in the example file, all decodable.
|
||||
When this file was recorded KF4RWA was finishing a QSO with K1JT.
|
||||
Since the green marker was placed at his audio frequency, 1224 Hz, his
|
||||
message `K1JT KF4RWA 73` is decoded first and appears in the *Rx
|
||||
Frequency* window. The *Band Activity* window shows this message plus
|
||||
all decodes at other frequencies. By default lines containing `CQ`
|
||||
are highlighted in green, and lines with *My Call* (in this case K1JT)
|
||||
in red.
|
||||
|
||||
[[X13]]
|
||||
.Decoding Controls
|
||||
|
||||
To gain some feeling for controls frequently used when making QSOs,
|
||||
try clicking with the mouse on the decoded text lines and on the
|
||||
waterfall spectral display. You should be able to confirm the
|
||||
following behavior:
|
||||
|
||||
- Double-click on either of the decoded lines highlighted in
|
||||
green. This action produces the following results:
|
||||
|
||||
** Callsign and locator of a station calling CQ are copied to the *DX
|
||||
Call* and *DX Grid* entry fields.
|
||||
|
||||
** Messages are generated for a standard minimal QSO.
|
||||
|
||||
** The *Tx even* box is checked or cleared appropriately, so that you
|
||||
will transmit in the proper (odd or even) minutes.
|
||||
|
||||
** The Rx frequency marker is moved to the frequency of the CQing
|
||||
station.
|
||||
|
||||
** The *Gen Msg* ("`generated message`") radio button at bottom right
|
||||
of the main window is selected.
|
||||
|
||||
** If you had checked *Double-click on call sets Tx Enable* on the
|
||||
*Setup* menu, *Enable Tx* would be activated and a transmission would
|
||||
start automatically at the proper time.
|
||||
|
||||
** You can modify the double-click behavior by holding down the
|
||||
*Shift* key to move only the Tx frequency or the *Ctrl* key to move
|
||||
both Rx and Tx frequencies.
|
||||
|
||||
- Double-click on the decoded message `K1JT N5KDV EM41`, highlighted
|
||||
in red. Results will be similar to those in the previous step. The Tx
|
||||
frequency (red marker) is not moved unless *Shift* or *Ctrl* is held
|
||||
down. Messages highlighted in red are usually in response to your own
|
||||
CQ or from a tail-ender, and you probably want your Tx frequency to
|
||||
stay where it was.
|
||||
|
||||
NOTE: Double-clicking on decoded messages can be defaulted to simplex
|
||||
operation by checking *Double click on call sets Tx and Rx freqs* on
|
||||
the *Settings -> General* tab.
|
||||
|
||||
NOTE: You can prevent your Tx frequency from being changed by checking the
|
||||
box *Lock Tx Freq*.
|
||||
|
||||
- Click somewhere on the waterfall to set Rx frequency (green marker
|
||||
on waterfall scale).
|
||||
|
||||
- Shift-click on the waterfall to set Tx frequency (red marker).
|
||||
|
||||
- Ctrl-click on the waterfall to set both Rx and Tx frequencies.
|
||||
|
||||
- Double-click on a signal in the waterfall to set Rx frequency and
|
||||
start a narrow-band decode there. Decoded text will appear in the
|
||||
right window only.
|
||||
|
||||
- Ctrl-double-click on a signal to set both Rx and Tx frequencies and
|
||||
decode at the new frequency.
|
||||
|
||||
- Click *Erase* to clear the right window.
|
||||
|
||||
- Double-click *Erase* to clear both text windows.
|
||||
@@ -0,0 +1,72 @@
|
||||
|
||||
#ifndef BOOST_MPL_MAP_AUX_INSERT_IMPL_HPP_INCLUDED
|
||||
#define BOOST_MPL_MAP_AUX_INSERT_IMPL_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$
|
||||
|
||||
#include <boost/mpl/insert_fwd.hpp>
|
||||
#include <boost/mpl/next_prior.hpp>
|
||||
#include <boost/mpl/map/aux_/contains_impl.hpp>
|
||||
#include <boost/mpl/map/aux_/item.hpp>
|
||||
#include <boost/mpl/map/aux_/tag.hpp>
|
||||
#include <boost/mpl/aux_/na.hpp>
|
||||
#include <boost/mpl/aux_/config/typeof.hpp>
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
namespace aux {
|
||||
template< typename Map, typename Pair >
|
||||
struct map_insert_impl
|
||||
: if_<
|
||||
contains_impl<aux::map_tag>::apply<Map,Pair>
|
||||
, Map
|
||||
#if defined(BOOST_MPL_CFG_TYPEOF_BASED_SEQUENCES)
|
||||
, m_item<
|
||||
typename Pair::first
|
||||
, typename Pair::second
|
||||
, Map
|
||||
>
|
||||
#else
|
||||
, m_item<
|
||||
Map::order::value
|
||||
, typename Pair::first
|
||||
, typename Pair::second
|
||||
, Map
|
||||
>
|
||||
#endif
|
||||
>
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
template<>
|
||||
struct insert_impl< aux::map_tag >
|
||||
{
|
||||
template<
|
||||
typename Map
|
||||
, typename PosOrKey
|
||||
, typename KeyOrNA
|
||||
>
|
||||
struct apply
|
||||
: aux::map_insert_impl<
|
||||
Map
|
||||
, typename if_na<KeyOrNA,PosOrKey>::type
|
||||
>
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_MPL_MAP_AUX_INSERT_IMPL_HPP_INCLUDED
|
||||
@@ -0,0 +1,32 @@
|
||||
/*=============================================================================
|
||||
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_SIZE_IMPL_31122005_1508)
|
||||
#define BOOST_FUSION_SIZE_IMPL_31122005_1508
|
||||
|
||||
#include <boost/fusion/support/config.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
|
||||
namespace boost { namespace fusion
|
||||
{
|
||||
struct mpl_sequence_tag;
|
||||
|
||||
namespace extension
|
||||
{
|
||||
template<typename Tag>
|
||||
struct size_impl;
|
||||
|
||||
template <>
|
||||
struct size_impl<mpl_sequence_tag>
|
||||
{
|
||||
template <typename Sequence>
|
||||
struct apply : mpl::size<Sequence> {};
|
||||
};
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,148 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef LIST_DWA2002627_HPP
|
||||
# define LIST_DWA2002627_HPP
|
||||
|
||||
# include <boost/python/detail/prefix.hpp>
|
||||
|
||||
# include <boost/python/object.hpp>
|
||||
# include <boost/python/converter/pytype_object_mgr_traits.hpp>
|
||||
# include <boost/python/ssize_t.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct BOOST_PYTHON_DECL list_base : object
|
||||
{
|
||||
void append(object_cref); // append object to end
|
||||
|
||||
ssize_t count(object_cref value) const; // return number of occurrences of value
|
||||
|
||||
void extend(object_cref sequence); // extend list by appending sequence elements
|
||||
|
||||
long index(object_cref value) const; // return index of first occurrence of value
|
||||
|
||||
void insert(ssize_t index, object_cref); // insert object before index
|
||||
void insert(object const& index, object_cref);
|
||||
|
||||
object pop(); // remove and return item at index (default last)
|
||||
object pop(ssize_t index);
|
||||
object pop(object const& index);
|
||||
|
||||
void remove(object_cref value); // remove first occurrence of value
|
||||
|
||||
void reverse(); // reverse *IN PLACE*
|
||||
|
||||
void sort(); // sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
void sort(args_proxy const &args,
|
||||
kwds_proxy const &kwds);
|
||||
#else
|
||||
void sort(object_cref cmpfunc);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
list_base(); // new list
|
||||
explicit list_base(object_cref sequence); // new list initialized from sequence's items
|
||||
|
||||
BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(list_base, object)
|
||||
private:
|
||||
static detail::new_non_null_reference call(object const&);
|
||||
};
|
||||
}
|
||||
|
||||
class list : public detail::list_base
|
||||
{
|
||||
typedef detail::list_base base;
|
||||
public:
|
||||
list() {} // new list
|
||||
|
||||
template <class T>
|
||||
explicit list(T const& sequence)
|
||||
: base(object(sequence))
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void append(T const& x)
|
||||
{
|
||||
base::append(object(x));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
long count(T const& value) const
|
||||
{
|
||||
return base::count(object(value));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void extend(T const& x)
|
||||
{
|
||||
base::extend(object(x));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
long index(T const& x) const
|
||||
{
|
||||
return base::index(object(x));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void insert(ssize_t index, T const& x) // insert object before index
|
||||
{
|
||||
base::insert(index, object(x));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void insert(object const& index, T const& x) // insert object before index
|
||||
{
|
||||
base::insert(index, object(x));
|
||||
}
|
||||
|
||||
object pop() { return base::pop(); }
|
||||
object pop(ssize_t index) { return base::pop(index); }
|
||||
|
||||
template <class T>
|
||||
object pop(T const& index)
|
||||
{
|
||||
return base::pop(object(index));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void remove(T const& value)
|
||||
{
|
||||
base::remove(object(value));
|
||||
}
|
||||
|
||||
#if PY_VERSION_HEX <= 0x03000000
|
||||
void sort() { base::sort(); }
|
||||
|
||||
template <class T>
|
||||
void sort(T const& value)
|
||||
{
|
||||
base::sort(object(value));
|
||||
}
|
||||
#endif
|
||||
|
||||
public: // implementation detail -- for internal use only
|
||||
BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(list, base)
|
||||
};
|
||||
|
||||
//
|
||||
// Converter Specializations
|
||||
//
|
||||
namespace converter
|
||||
{
|
||||
template <>
|
||||
struct object_manager_traits<list>
|
||||
: pytype_object_manager_traits<&PyList_Type,list>
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // LIST_DWA2002627_HPP
|
||||
@@ -0,0 +1,90 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_INTERSECTION_IPP)
|
||||
#define BOOST_SPIRIT_INTERSECTION_IPP
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// intersection class implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A, typename B>
|
||||
inline intersection<A, B>
|
||||
operator&(parser<A> const& a, parser<B> const& b)
|
||||
{
|
||||
return intersection<A, B>(a.derived(), b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline intersection<A, chlit<char> >
|
||||
operator&(parser<A> const& a, char b)
|
||||
{
|
||||
return intersection<A, chlit<char> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline intersection<chlit<char>, B>
|
||||
operator&(char a, parser<B> const& b)
|
||||
{
|
||||
return intersection<chlit<char>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline intersection<A, strlit<char const*> >
|
||||
operator&(parser<A> const& a, char const* b)
|
||||
{
|
||||
return intersection<A, strlit<char const*> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline intersection<strlit<char const*>, B>
|
||||
operator&(char const* a, parser<B> const& b)
|
||||
{
|
||||
return intersection<strlit<char const*>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline intersection<A, chlit<wchar_t> >
|
||||
operator&(parser<A> const& a, wchar_t b)
|
||||
{
|
||||
return intersection<A, chlit<wchar_t> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline intersection<chlit<wchar_t>, B>
|
||||
operator&(wchar_t a, parser<B> const& b)
|
||||
{
|
||||
return intersection<chlit<wchar_t>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline intersection<A, strlit<wchar_t const*> >
|
||||
operator&(parser<A> const& a, wchar_t const* b)
|
||||
{
|
||||
return intersection<A, strlit<wchar_t const*> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline intersection<strlit<wchar_t const*>, B>
|
||||
operator&(wchar_t const* a, parser<B> const& b)
|
||||
{
|
||||
return intersection<strlit<wchar_t const*>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
#ifndef BOOST_MPL_LIST_LIST40_C_HPP_INCLUDED
|
||||
#define BOOST_MPL_LIST_LIST40_C_HPP_INCLUDED
|
||||
|
||||
// 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#if !defined(BOOST_MPL_PREPROCESSING_MODE)
|
||||
# include <boost/mpl/list/list30_c.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/aux_/config/use_preprocessed.hpp>
|
||||
|
||||
#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
|
||||
&& !defined(BOOST_MPL_PREPROCESSING_MODE)
|
||||
|
||||
# define BOOST_MPL_PREPROCESSED_HEADER list40_c.hpp
|
||||
# include <boost/mpl/list/aux_/include_preprocessed.hpp>
|
||||
|
||||
#else
|
||||
|
||||
# include <boost/preprocessor/iterate.hpp>
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3,(31, 40, <boost/mpl/list/aux_/numbered_c.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
|
||||
|
||||
#endif // BOOST_MPL_LIST_LIST40_C_HPP_INCLUDED
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* -*- c++ -*-
|
||||
*
|
||||
* \file num_rows.hpp
|
||||
*
|
||||
* \brief The \c num_rows operation.
|
||||
*
|
||||
* Copyright (c) 2009-2012, Marco Guazzone
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
* \author Marco Guazzone, marco.guazzone@gmail.com
|
||||
*/
|
||||
|
||||
#ifndef BOOST_NUMERIC_UBLAS_OPERATION_NUM_ROWS_HPP
|
||||
#define BOOST_NUMERIC_UBLAS_OPERATION_NUM_ROWS_HPP
|
||||
|
||||
|
||||
#include <boost/numeric/ublas/detail/config.hpp>
|
||||
#include <boost/numeric/ublas/expression_types.hpp>
|
||||
#include <boost/numeric/ublas/traits.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace numeric { namespace ublas {
|
||||
|
||||
/**
|
||||
* \brief Return the number of rows.
|
||||
* \tparam MatrixExprT A type which models the matrix expression concept.
|
||||
* \param m A matrix expression.
|
||||
* \return The number of rows.
|
||||
*/
|
||||
template <typename MatrixExprT>
|
||||
BOOST_UBLAS_INLINE
|
||||
typename matrix_traits<MatrixExprT>::size_type num_rows(matrix_expression<MatrixExprT> const& me)
|
||||
{
|
||||
return me().size1();
|
||||
}
|
||||
|
||||
}}} // Namespace boost::numeric::ublas
|
||||
|
||||
|
||||
#endif // BOOST_NUMERIC_UBLAS_OPERATION_NUM_ROWS_HPP
|
||||
@@ -0,0 +1,412 @@
|
||||
// (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_18_HPP
|
||||
#define BOOST_MATH_TOOLS_POLY_EVAL_18_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];
|
||||
}
|
||||
|
||||
template <class T, class V>
|
||||
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<9>*) BOOST_MATH_NOEXCEPT(V)
|
||||
{
|
||||
V x2 = x * x;
|
||||
V t[2];
|
||||
t[0] = static_cast<V>(a[8] * x2 + a[6]);
|
||||
t[1] = static_cast<V>(a[7] * x2 + a[5]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[4]);
|
||||
t[1] += static_cast<V>(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_<10>*) BOOST_MATH_NOEXCEPT(V)
|
||||
{
|
||||
V x2 = x * x;
|
||||
V t[2];
|
||||
t[0] = a[9] * x2 + a[7];
|
||||
t[1] = a[8] * x2 + a[6];
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[5]);
|
||||
t[1] += static_cast<V>(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];
|
||||
}
|
||||
|
||||
template <class T, class V>
|
||||
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<11>*) BOOST_MATH_NOEXCEPT(V)
|
||||
{
|
||||
V x2 = x * x;
|
||||
V t[2];
|
||||
t[0] = static_cast<V>(a[10] * x2 + a[8]);
|
||||
t[1] = static_cast<V>(a[9] * x2 + a[7]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[6]);
|
||||
t[1] += static_cast<V>(a[5]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[4]);
|
||||
t[1] += static_cast<V>(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_<12>*) BOOST_MATH_NOEXCEPT(V)
|
||||
{
|
||||
V x2 = x * x;
|
||||
V t[2];
|
||||
t[0] = a[11] * x2 + a[9];
|
||||
t[1] = a[10] * x2 + a[8];
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[7]);
|
||||
t[1] += static_cast<V>(a[6]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[5]);
|
||||
t[1] += static_cast<V>(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];
|
||||
}
|
||||
|
||||
template <class T, class V>
|
||||
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<13>*) BOOST_MATH_NOEXCEPT(V)
|
||||
{
|
||||
V x2 = x * x;
|
||||
V t[2];
|
||||
t[0] = static_cast<V>(a[12] * x2 + a[10]);
|
||||
t[1] = static_cast<V>(a[11] * x2 + a[9]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[8]);
|
||||
t[1] += static_cast<V>(a[7]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[6]);
|
||||
t[1] += static_cast<V>(a[5]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[4]);
|
||||
t[1] += static_cast<V>(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_<14>*) BOOST_MATH_NOEXCEPT(V)
|
||||
{
|
||||
V x2 = x * x;
|
||||
V t[2];
|
||||
t[0] = a[13] * x2 + a[11];
|
||||
t[1] = a[12] * x2 + a[10];
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[9]);
|
||||
t[1] += static_cast<V>(a[8]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[7]);
|
||||
t[1] += static_cast<V>(a[6]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[5]);
|
||||
t[1] += static_cast<V>(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];
|
||||
}
|
||||
|
||||
template <class T, class V>
|
||||
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<15>*) BOOST_MATH_NOEXCEPT(V)
|
||||
{
|
||||
V x2 = x * x;
|
||||
V t[2];
|
||||
t[0] = static_cast<V>(a[14] * x2 + a[12]);
|
||||
t[1] = static_cast<V>(a[13] * x2 + a[11]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[10]);
|
||||
t[1] += static_cast<V>(a[9]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[8]);
|
||||
t[1] += static_cast<V>(a[7]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[6]);
|
||||
t[1] += static_cast<V>(a[5]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[4]);
|
||||
t[1] += static_cast<V>(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_<16>*) BOOST_MATH_NOEXCEPT(V)
|
||||
{
|
||||
V x2 = x * x;
|
||||
V t[2];
|
||||
t[0] = a[15] * x2 + a[13];
|
||||
t[1] = a[14] * x2 + a[12];
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[11]);
|
||||
t[1] += static_cast<V>(a[10]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[9]);
|
||||
t[1] += static_cast<V>(a[8]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[7]);
|
||||
t[1] += static_cast<V>(a[6]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[5]);
|
||||
t[1] += static_cast<V>(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];
|
||||
}
|
||||
|
||||
template <class T, class V>
|
||||
inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<17>*) BOOST_MATH_NOEXCEPT(V)
|
||||
{
|
||||
V x2 = x * x;
|
||||
V t[2];
|
||||
t[0] = static_cast<V>(a[16] * x2 + a[14]);
|
||||
t[1] = static_cast<V>(a[15] * x2 + a[13]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[12]);
|
||||
t[1] += static_cast<V>(a[11]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[10]);
|
||||
t[1] += static_cast<V>(a[9]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[8]);
|
||||
t[1] += static_cast<V>(a[7]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[6]);
|
||||
t[1] += static_cast<V>(a[5]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[4]);
|
||||
t[1] += static_cast<V>(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_<18>*) BOOST_MATH_NOEXCEPT(V)
|
||||
{
|
||||
V x2 = x * x;
|
||||
V t[2];
|
||||
t[0] = a[17] * x2 + a[15];
|
||||
t[1] = a[16] * x2 + a[14];
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[13]);
|
||||
t[1] += static_cast<V>(a[12]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[11]);
|
||||
t[1] += static_cast<V>(a[10]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[9]);
|
||||
t[1] += static_cast<V>(a[8]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[7]);
|
||||
t[1] += static_cast<V>(a[6]);
|
||||
t[0] *= x2;
|
||||
t[1] *= x2;
|
||||
t[0] += static_cast<V>(a[5]);
|
||||
t[1] += static_cast<V>(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,23 @@
|
||||
# /* **************************************************************************
|
||||
# * *
|
||||
# * (C) Copyright Paul Mensonides 2002-2011. *
|
||||
# * (C) Copyright Edward Diener 2011. *
|
||||
# * Distributed under the Boost Software License, Version 1.0. (See *
|
||||
# * accompanying file LICENSE_1_0.txt or copy at *
|
||||
# * http://www.boost.org/LICENSE_1_0.txt) *
|
||||
# * *
|
||||
# ************************************************************************** */
|
||||
#
|
||||
# /* See http://www.boost.org for most recent version. */
|
||||
#
|
||||
# ifndef BOOST_PREPROCESSOR_FACILITIES_HPP
|
||||
# define BOOST_PREPROCESSOR_FACILITIES_HPP
|
||||
#
|
||||
# include <boost/preprocessor/facilities/apply.hpp>
|
||||
# include <boost/preprocessor/facilities/empty.hpp>
|
||||
# include <boost/preprocessor/facilities/expand.hpp>
|
||||
# include <boost/preprocessor/facilities/identity.hpp>
|
||||
# include <boost/preprocessor/facilities/intercept.hpp>
|
||||
# include <boost/preprocessor/facilities/overload.hpp>
|
||||
#
|
||||
# endif
|
||||
@@ -0,0 +1,826 @@
|
||||
/*
|
||||
* 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_msvc_arm.hpp
|
||||
*
|
||||
* This header contains implementation of the \c operations template.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ATOMIC_DETAIL_OPS_MSVC_ARM_HPP_INCLUDED_
|
||||
#define BOOST_ATOMIC_DETAIL_OPS_MSVC_ARM_HPP_INCLUDED_
|
||||
|
||||
#include <intrin.h>
|
||||
#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>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define BOOST_ATOMIC_DETAIL_ARM_LOAD8(p) __iso_volatile_load8((const volatile __int8*)(p))
|
||||
#define BOOST_ATOMIC_DETAIL_ARM_LOAD16(p) __iso_volatile_load16((const volatile __int16*)(p))
|
||||
#define BOOST_ATOMIC_DETAIL_ARM_LOAD32(p) __iso_volatile_load32((const volatile __int32*)(p))
|
||||
#define BOOST_ATOMIC_DETAIL_ARM_LOAD64(p) __iso_volatile_load64((const volatile __int64*)(p))
|
||||
#define BOOST_ATOMIC_DETAIL_ARM_STORE8(p, v) __iso_volatile_store8((volatile __int8*)(p), (__int8)(v))
|
||||
#define BOOST_ATOMIC_DETAIL_ARM_STORE16(p, v) __iso_volatile_store16((volatile __int16*)(p), (__int16)(v))
|
||||
#define BOOST_ATOMIC_DETAIL_ARM_STORE32(p, v) __iso_volatile_store32((volatile __int32*)(p), (__int32)(v))
|
||||
#define BOOST_ATOMIC_DETAIL_ARM_STORE64(p, v) __iso_volatile_store64((volatile __int64*)(p), (__int64)(v))
|
||||
|
||||
namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
// A note about memory_order_consume. Technically, this architecture allows to avoid
|
||||
// unnecessary memory barrier after consume load since it supports data dependency ordering.
|
||||
// However, some compiler optimizations may break a seemingly valid code relying on data
|
||||
// dependency tracking by injecting bogus branches to aid out of order execution.
|
||||
// This may happen not only in Boost.Atomic code but also in user's code, which we have no
|
||||
// control of. See this thread: http://lists.boost.org/Archives/boost/2014/06/213890.php.
|
||||
// For this reason we promote memory_order_consume to memory_order_acquire.
|
||||
|
||||
struct msvc_arm_operations_base
|
||||
{
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
|
||||
|
||||
static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT
|
||||
{
|
||||
__dmb(0xB); // _ARM_BARRIER_ISH, see armintr.h from MSVC 11 and later
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
|
||||
|
||||
if ((order & memory_order_release) != 0)
|
||||
hardware_full_fence();
|
||||
|
||||
BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
|
||||
|
||||
if (order == memory_order_seq_cst)
|
||||
hardware_full_fence();
|
||||
|
||||
BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
|
||||
|
||||
if ((order & (memory_order_consume | memory_order_acquire)) != 0)
|
||||
hardware_full_fence();
|
||||
|
||||
BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE BOOST_CONSTEXPR memory_order cas_common_order(memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
|
||||
{
|
||||
// Combine order flags together and promote memory_order_consume to memory_order_acquire
|
||||
return static_cast< memory_order >(((failure_order | success_order) & ~memory_order_consume) | (((failure_order | success_order) & memory_order_consume) << 1u));
|
||||
}
|
||||
};
|
||||
|
||||
template< typename T, typename Derived >
|
||||
struct msvc_arm_operations :
|
||||
public msvc_arm_operations_base
|
||||
{
|
||||
typedef T storage_type;
|
||||
|
||||
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
|
||||
{
|
||||
Derived::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< 1u, Signed > :
|
||||
public msvc_arm_operations< typename make_storage_type< 1u, Signed >::type, operations< 1u, Signed > >
|
||||
{
|
||||
typedef msvc_arm_operations< typename make_storage_type< 1u, Signed >::type, operations< 1u, Signed > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
typedef typename make_storage_type< 1u, Signed >::aligned aligned_storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
base_type::fence_before_store(order);
|
||||
BOOST_ATOMIC_DETAIL_ARM_STORE8(&storage, v);
|
||||
base_type::fence_after_store(order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type v = BOOST_ATOMIC_DETAIL_ARM_LOAD8(&storage);
|
||||
base_type::fence_after_load(order);
|
||||
return v;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8(&storage, v));
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8(&storage, v));
|
||||
break;
|
||||
}
|
||||
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, old_val;
|
||||
|
||||
switch (cas_common_order(success_order, failure_order))
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_RELAXED(&storage, desired, previous));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_ACQUIRE(&storage, desired, previous));
|
||||
break;
|
||||
case memory_order_release:
|
||||
old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_RELEASE(&storage, desired, previous));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8(&storage, desired, previous));
|
||||
break;
|
||||
}
|
||||
expected = old_val;
|
||||
|
||||
return (previous == old_val);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8(&storage, v));
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8(&storage, v));
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8(&storage, v));
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 2u, Signed > :
|
||||
public msvc_arm_operations< typename make_storage_type< 2u, Signed >::type, operations< 2u, Signed > >
|
||||
{
|
||||
typedef msvc_arm_operations< typename make_storage_type< 2u, Signed >::type, operations< 2u, Signed > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
typedef typename make_storage_type< 2u, Signed >::aligned aligned_storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
base_type::fence_before_store(order);
|
||||
BOOST_ATOMIC_DETAIL_ARM_STORE16(&storage, v);
|
||||
base_type::fence_after_store(order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type v = BOOST_ATOMIC_DETAIL_ARM_LOAD16(&storage);
|
||||
base_type::fence_after_load(order);
|
||||
return v;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16(&storage, v));
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16(&storage, v));
|
||||
break;
|
||||
}
|
||||
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, old_val;
|
||||
|
||||
switch (cas_common_order(success_order, failure_order))
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_RELAXED(&storage, desired, previous));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_ACQUIRE(&storage, desired, previous));
|
||||
break;
|
||||
case memory_order_release:
|
||||
old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_RELEASE(&storage, desired, previous));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16(&storage, desired, previous));
|
||||
break;
|
||||
}
|
||||
expected = old_val;
|
||||
|
||||
return (previous == old_val);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16(&storage, v));
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16(&storage, v));
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16(&storage, v));
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 4u, Signed > :
|
||||
public msvc_arm_operations< typename make_storage_type< 4u, Signed >::type, operations< 4u, Signed > >
|
||||
{
|
||||
typedef msvc_arm_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 void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
base_type::fence_before_store(order);
|
||||
BOOST_ATOMIC_DETAIL_ARM_STORE32(&storage, v);
|
||||
base_type::fence_after_store(order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type v = BOOST_ATOMIC_DETAIL_ARM_LOAD32(&storage);
|
||||
base_type::fence_after_load(order);
|
||||
return v;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&storage, v));
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&storage, v));
|
||||
break;
|
||||
}
|
||||
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, old_val;
|
||||
|
||||
switch (cas_common_order(success_order, failure_order))
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_RELAXED(&storage, desired, previous));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_ACQUIRE(&storage, desired, previous));
|
||||
break;
|
||||
case memory_order_release:
|
||||
old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_RELEASE(&storage, desired, previous));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&storage, desired, previous));
|
||||
break;
|
||||
}
|
||||
expected = old_val;
|
||||
|
||||
return (previous == old_val);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND(&storage, v));
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR(&storage, v));
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR(&storage, v));
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 8u, Signed > :
|
||||
public msvc_arm_operations< typename make_storage_type< 8u, Signed >::type, operations< 8u, Signed > >
|
||||
{
|
||||
typedef msvc_arm_operations< typename make_storage_type< 8u, Signed >::type, operations< 8u, Signed > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
typedef typename make_storage_type< 8u, Signed >::aligned aligned_storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
base_type::fence_before_store(order);
|
||||
BOOST_ATOMIC_DETAIL_ARM_STORE64(&storage, v);
|
||||
base_type::fence_after_store(order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type v = BOOST_ATOMIC_DETAIL_ARM_LOAD64(&storage);
|
||||
base_type::fence_after_load(order);
|
||||
return v;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(&storage, v));
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(&storage, v));
|
||||
break;
|
||||
}
|
||||
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, old_val;
|
||||
|
||||
switch (cas_common_order(success_order, failure_order))
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_RELAXED(&storage, desired, previous));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_ACQUIRE(&storage, desired, previous));
|
||||
break;
|
||||
case memory_order_release:
|
||||
old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_RELEASE(&storage, desired, previous));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(&storage, desired, previous));
|
||||
break;
|
||||
}
|
||||
expected = old_val;
|
||||
|
||||
return (previous == old_val);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64(&storage, v));
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64(&storage, v));
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64_RELAXED(&storage, v));
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64_ACQUIRE(&storage, v));
|
||||
break;
|
||||
case memory_order_release:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64_RELEASE(&storage, v));
|
||||
break;
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
default:
|
||||
v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64(&storage, v));
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
|
||||
if (order != memory_order_relaxed)
|
||||
msvc_arm_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
|
||||
|
||||
#undef BOOST_ATOMIC_DETAIL_ARM_LOAD8
|
||||
#undef BOOST_ATOMIC_DETAIL_ARM_LOAD16
|
||||
#undef BOOST_ATOMIC_DETAIL_ARM_LOAD32
|
||||
#undef BOOST_ATOMIC_DETAIL_ARM_LOAD64
|
||||
#undef BOOST_ATOMIC_DETAIL_ARM_STORE8
|
||||
#undef BOOST_ATOMIC_DETAIL_ARM_STORE16
|
||||
#undef BOOST_ATOMIC_DETAIL_ARM_STORE32
|
||||
#undef BOOST_ATOMIC_DETAIL_ARM_STORE64
|
||||
|
||||
#endif // BOOST_ATOMIC_DETAIL_OPS_MSVC_ARM_HPP_INCLUDED_
|
||||
@@ -0,0 +1,15 @@
|
||||
/*==============================================================================
|
||||
Copyright (c) 2001-2010 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)
|
||||
==============================================================================*/
|
||||
#ifndef BOOST_PHOENIX_FUNCTION_HPP
|
||||
#define BOOST_PHOENIX_FUNCTION_HPP
|
||||
|
||||
#include <boost/phoenix/version.hpp>
|
||||
#include <boost/phoenix/function/function.hpp>
|
||||
#include <boost/phoenix/function/adapt_callable.hpp>
|
||||
#include <boost/phoenix/function/adapt_function.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright 2002 The Trustees of Indiana University.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Boost.MultiArray Library
|
||||
// Authors: Ronald Garcia
|
||||
// Jeremy Siek
|
||||
// Andrew Lumsdaine
|
||||
// See http://www.boost.org/libs/multi_array for documentation.
|
||||
|
||||
#ifndef BOOST_INDEX_GEN_RG071801_HPP
|
||||
#define BOOST_INDEX_GEN_RG071801_HPP
|
||||
|
||||
#include "boost/array.hpp"
|
||||
#include "boost/multi_array/index_range.hpp"
|
||||
#include "boost/multi_array/range_list.hpp"
|
||||
#include "boost/multi_array/types.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
namespace multi_array {
|
||||
|
||||
|
||||
template <int NumRanges, int NumDims>
|
||||
struct index_gen {
|
||||
private:
|
||||
typedef ::boost::detail::multi_array::index index;
|
||||
typedef ::boost::detail::multi_array::size_type size_type;
|
||||
typedef index_range<index,size_type> range;
|
||||
public:
|
||||
template <int Dims, int Ranges>
|
||||
struct gen_type {
|
||||
typedef index_gen<Ranges,Dims> type;
|
||||
};
|
||||
|
||||
typedef typename range_list_generator<range,NumRanges>::type range_list;
|
||||
range_list ranges_;
|
||||
|
||||
index_gen() { }
|
||||
|
||||
template <int ND>
|
||||
explicit index_gen(const index_gen<NumRanges-1,ND>& rhs,
|
||||
const range& r)
|
||||
{
|
||||
std::copy(rhs.ranges_.begin(),rhs.ranges_.end(),ranges_.begin());
|
||||
*ranges_.rbegin() = r;
|
||||
}
|
||||
|
||||
index_gen<NumRanges+1,NumDims+1>
|
||||
operator[](const range& r) const
|
||||
{
|
||||
index_gen<NumRanges+1,NumDims+1> tmp;
|
||||
std::copy(ranges_.begin(),ranges_.end(),tmp.ranges_.begin());
|
||||
*tmp.ranges_.rbegin() = r;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
index_gen<NumRanges+1,NumDims>
|
||||
operator[](index idx) const
|
||||
{
|
||||
index_gen<NumRanges+1,NumDims> tmp;
|
||||
std::copy(ranges_.begin(),ranges_.end(),tmp.ranges_.begin());
|
||||
*tmp.ranges_.rbegin() = range(idx);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static index_gen<0,0> indices() {
|
||||
return index_gen<0,0>();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace multi_array
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_INDEX_GEN_RG071801_HPP
|
||||
@@ -0,0 +1,436 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. 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/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_SHARED_MEMORY_OBJECT_HPP
|
||||
#define BOOST_INTERPROCESS_SHARED_MEMORY_OBJECT_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/interprocess/creation_tags.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/interprocess/detail/os_file_functions.hpp>
|
||||
#include <boost/interprocess/detail/shared_dir_helpers.hpp>
|
||||
#include <boost/interprocess/permissions.hpp>
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
#if defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS)
|
||||
# include <fcntl.h> //O_CREAT, O_*...
|
||||
# include <sys/mman.h> //shm_xxx
|
||||
# include <unistd.h> //ftruncate, close
|
||||
# include <sys/stat.h> //mode_t, S_IRWXG, S_IRWXO, S_IRWXU,
|
||||
# if defined(BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY)
|
||||
# if defined(__FreeBSD__)
|
||||
# include <sys/sysctl.h>
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
//
|
||||
#endif
|
||||
|
||||
//!\file
|
||||
//!Describes a shared memory object management class.
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
//!A class that wraps a shared memory mapping that can be used to
|
||||
//!create mapped regions from the mapped files
|
||||
class shared_memory_object
|
||||
{
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
//Non-copyable and non-assignable
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(shared_memory_object)
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
//!Default constructor. Represents an empty shared_memory_object.
|
||||
shared_memory_object();
|
||||
|
||||
//!Creates a shared memory object with name "name" and mode "mode", with the access mode "mode"
|
||||
//!If the file previously exists, throws an error.*/
|
||||
shared_memory_object(create_only_t, const char *name, mode_t mode, const permissions &perm = permissions())
|
||||
{ this->priv_open_or_create(ipcdetail::DoCreate, name, mode, perm); }
|
||||
|
||||
//!Tries to create a shared memory object with name "name" and mode "mode", with the
|
||||
//!access mode "mode". If the file previously exists, it tries to open it with mode "mode".
|
||||
//!Otherwise throws an error.
|
||||
shared_memory_object(open_or_create_t, const char *name, mode_t mode, const permissions &perm = permissions())
|
||||
{ this->priv_open_or_create(ipcdetail::DoOpenOrCreate, name, mode, perm); }
|
||||
|
||||
//!Tries to open a shared memory object with name "name", with the access mode "mode".
|
||||
//!If the file does not previously exist, it throws an error.
|
||||
shared_memory_object(open_only_t, const char *name, mode_t mode)
|
||||
{ this->priv_open_or_create(ipcdetail::DoOpen, name, mode, permissions()); }
|
||||
|
||||
//!Moves the ownership of "moved"'s shared memory object to *this.
|
||||
//!After the call, "moved" does not represent any shared memory object.
|
||||
//!Does not throw
|
||||
shared_memory_object(BOOST_RV_REF(shared_memory_object) moved)
|
||||
: m_handle(file_handle_t(ipcdetail::invalid_file()))
|
||||
, m_mode(read_only)
|
||||
{ this->swap(moved); }
|
||||
|
||||
//!Moves the ownership of "moved"'s shared memory to *this.
|
||||
//!After the call, "moved" does not represent any shared memory.
|
||||
//!Does not throw
|
||||
shared_memory_object &operator=(BOOST_RV_REF(shared_memory_object) moved)
|
||||
{
|
||||
shared_memory_object tmp(boost::move(moved));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//!Swaps the shared_memory_objects. Does not throw
|
||||
void swap(shared_memory_object &moved);
|
||||
|
||||
//!Erases a shared memory object from the system.
|
||||
//!Returns false on error. Never throws
|
||||
static bool remove(const char *name);
|
||||
|
||||
//!Sets the size of the shared memory mapping
|
||||
void truncate(offset_t length);
|
||||
|
||||
//!Destroys *this and indicates that the calling process is finished using
|
||||
//!the resource. All mapped regions are still
|
||||
//!valid after destruction. The destructor function will deallocate
|
||||
//!any system resources allocated by the system for use by this process for
|
||||
//!this resource. The resource can still be opened again calling
|
||||
//!the open constructor overload. To erase the resource from the system
|
||||
//!use remove().
|
||||
~shared_memory_object();
|
||||
|
||||
//!Returns the name of the shared memory object.
|
||||
const char *get_name() const;
|
||||
|
||||
//!Returns true if the size of the shared memory object
|
||||
//!can be obtained and writes the size in the passed reference
|
||||
bool get_size(offset_t &size) const;
|
||||
|
||||
//!Returns access mode
|
||||
mode_t get_mode() const;
|
||||
|
||||
//!Returns mapping handle. Never throws.
|
||||
mapping_handle_t get_mapping_handle() const;
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
private:
|
||||
|
||||
//!Closes a previously opened file mapping. Never throws.
|
||||
void priv_close();
|
||||
|
||||
//!Opens or creates a shared memory object.
|
||||
bool priv_open_or_create(ipcdetail::create_enum_t type, const char *filename, mode_t mode, const permissions &perm);
|
||||
|
||||
file_handle_t m_handle;
|
||||
mode_t m_mode;
|
||||
std::string m_filename;
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
|
||||
inline shared_memory_object::shared_memory_object()
|
||||
: m_handle(file_handle_t(ipcdetail::invalid_file()))
|
||||
, m_mode(read_only)
|
||||
{}
|
||||
|
||||
inline shared_memory_object::~shared_memory_object()
|
||||
{ this->priv_close(); }
|
||||
|
||||
|
||||
inline const char *shared_memory_object::get_name() const
|
||||
{ return m_filename.c_str(); }
|
||||
|
||||
inline bool shared_memory_object::get_size(offset_t &size) const
|
||||
{ return ipcdetail::get_file_size((file_handle_t)m_handle, size); }
|
||||
|
||||
inline void shared_memory_object::swap(shared_memory_object &other)
|
||||
{
|
||||
boost::adl_move_swap(m_handle, other.m_handle);
|
||||
boost::adl_move_swap(m_mode, other.m_mode);
|
||||
m_filename.swap(other.m_filename);
|
||||
}
|
||||
|
||||
inline mapping_handle_t shared_memory_object::get_mapping_handle() const
|
||||
{
|
||||
return ipcdetail::mapping_handle_from_file_handle(m_handle);
|
||||
}
|
||||
|
||||
inline mode_t shared_memory_object::get_mode() const
|
||||
{ return m_mode; }
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS)
|
||||
|
||||
inline bool shared_memory_object::priv_open_or_create
|
||||
(ipcdetail::create_enum_t type, const char *filename, mode_t mode, const permissions &perm)
|
||||
{
|
||||
m_filename = filename;
|
||||
std::string shmfile;
|
||||
ipcdetail::create_shared_dir_cleaning_old_and_get_filepath(filename, shmfile);
|
||||
|
||||
//Set accesses
|
||||
if (mode != read_write && mode != read_only){
|
||||
error_info err = other_error;
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
|
||||
switch(type){
|
||||
case ipcdetail::DoOpen:
|
||||
m_handle = ipcdetail::open_existing_file(shmfile.c_str(), mode, true);
|
||||
break;
|
||||
case ipcdetail::DoCreate:
|
||||
m_handle = ipcdetail::create_new_file(shmfile.c_str(), mode, perm, true);
|
||||
break;
|
||||
case ipcdetail::DoOpenOrCreate:
|
||||
m_handle = ipcdetail::create_or_open_file(shmfile.c_str(), mode, perm, true);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
error_info err = other_error;
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
}
|
||||
|
||||
//Check for error
|
||||
if(m_handle == ipcdetail::invalid_file()){
|
||||
error_info err = system_error_code();
|
||||
this->priv_close();
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
|
||||
m_mode = mode;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool shared_memory_object::remove(const char *filename)
|
||||
{
|
||||
try{
|
||||
//Make sure a temporary path is created for shared memory
|
||||
std::string shmfile;
|
||||
ipcdetail::shared_filepath(filename, shmfile);
|
||||
return ipcdetail::delete_file(shmfile.c_str());
|
||||
}
|
||||
catch(...){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void shared_memory_object::truncate(offset_t length)
|
||||
{
|
||||
if(!ipcdetail::truncate_file(m_handle, length)){
|
||||
error_info err = system_error_code();
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
}
|
||||
|
||||
inline void shared_memory_object::priv_close()
|
||||
{
|
||||
if(m_handle != ipcdetail::invalid_file()){
|
||||
ipcdetail::close_file(m_handle);
|
||||
m_handle = ipcdetail::invalid_file();
|
||||
}
|
||||
}
|
||||
|
||||
#else //!defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS)
|
||||
|
||||
namespace shared_memory_object_detail {
|
||||
|
||||
#ifdef BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
|
||||
inline bool use_filesystem_based_posix()
|
||||
{
|
||||
int jailed = 0;
|
||||
std::size_t len = sizeof(jailed);
|
||||
::sysctlbyname("security.jail.jailed", &jailed, &len, NULL, 0);
|
||||
return jailed != 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#error "Not supported platform for BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
} //shared_memory_object_detail
|
||||
|
||||
inline bool shared_memory_object::priv_open_or_create
|
||||
(ipcdetail::create_enum_t type,
|
||||
const char *filename,
|
||||
mode_t mode, const permissions &perm)
|
||||
{
|
||||
#if defined(BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY)
|
||||
const bool add_leading_slash = false;
|
||||
#elif defined(BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY)
|
||||
const bool add_leading_slash = !shared_memory_object_detail::use_filesystem_based_posix();
|
||||
#else
|
||||
const bool add_leading_slash = true;
|
||||
#endif
|
||||
if(add_leading_slash){
|
||||
ipcdetail::add_leading_slash(filename, m_filename);
|
||||
}
|
||||
else{
|
||||
ipcdetail::create_shared_dir_cleaning_old_and_get_filepath(filename, m_filename);
|
||||
}
|
||||
|
||||
//Create new mapping
|
||||
int oflag = 0;
|
||||
if(mode == read_only){
|
||||
oflag |= O_RDONLY;
|
||||
}
|
||||
else if(mode == read_write){
|
||||
oflag |= O_RDWR;
|
||||
}
|
||||
else{
|
||||
error_info err(mode_error);
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
int unix_perm = perm.get_permissions();
|
||||
|
||||
switch(type){
|
||||
case ipcdetail::DoOpen:
|
||||
{
|
||||
//No oflag addition
|
||||
m_handle = shm_open(m_filename.c_str(), oflag, unix_perm);
|
||||
}
|
||||
break;
|
||||
case ipcdetail::DoCreate:
|
||||
{
|
||||
oflag |= (O_CREAT | O_EXCL);
|
||||
m_handle = shm_open(m_filename.c_str(), oflag, unix_perm);
|
||||
if(m_handle >= 0){
|
||||
::fchmod(m_handle, unix_perm);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ipcdetail::DoOpenOrCreate:
|
||||
{
|
||||
//We need a create/open loop to change permissions correctly using fchmod, since
|
||||
//with "O_CREAT" only we don't know if we've created or opened the shm.
|
||||
while(1){
|
||||
//Try to create shared memory
|
||||
m_handle = shm_open(m_filename.c_str(), oflag | (O_CREAT | O_EXCL), unix_perm);
|
||||
//If successful change real permissions
|
||||
if(m_handle >= 0){
|
||||
::fchmod(m_handle, unix_perm);
|
||||
}
|
||||
//If already exists, try to open
|
||||
else if(errno == EEXIST){
|
||||
m_handle = shm_open(m_filename.c_str(), oflag, unix_perm);
|
||||
//If open fails and errno tells the file does not exist
|
||||
//(shm was removed between creation and opening tries), just retry
|
||||
if(m_handle < 0 && errno == ENOENT){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//Exit retries
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
error_info err = other_error;
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
}
|
||||
|
||||
//Check for error
|
||||
if(m_handle < 0){
|
||||
error_info err = errno;
|
||||
this->priv_close();
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
|
||||
m_filename = filename;
|
||||
m_mode = mode;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool shared_memory_object::remove(const char *filename)
|
||||
{
|
||||
try{
|
||||
std::string filepath;
|
||||
#if defined(BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY)
|
||||
const bool add_leading_slash = false;
|
||||
#elif defined(BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY)
|
||||
const bool add_leading_slash = !shared_memory_object_detail::use_filesystem_based_posix();
|
||||
#else
|
||||
const bool add_leading_slash = true;
|
||||
#endif
|
||||
if(add_leading_slash){
|
||||
ipcdetail::add_leading_slash(filename, filepath);
|
||||
}
|
||||
else{
|
||||
ipcdetail::shared_filepath(filename, filepath);
|
||||
}
|
||||
return 0 == shm_unlink(filepath.c_str());
|
||||
}
|
||||
catch(...){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void shared_memory_object::truncate(offset_t length)
|
||||
{
|
||||
if(0 != ftruncate(m_handle, length)){
|
||||
error_info err(system_error_code());
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
}
|
||||
|
||||
inline void shared_memory_object::priv_close()
|
||||
{
|
||||
if(m_handle != -1){
|
||||
::close(m_handle);
|
||||
m_handle = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//!A class that stores the name of a shared memory
|
||||
//!and calls shared_memory_object::remove(name) in its destructor
|
||||
//!Useful to remove temporary shared memory objects in the presence
|
||||
//!of exceptions
|
||||
class remove_shared_memory_on_destroy
|
||||
{
|
||||
const char * m_name;
|
||||
public:
|
||||
remove_shared_memory_on_destroy(const char *name)
|
||||
: m_name(name)
|
||||
{}
|
||||
|
||||
~remove_shared_memory_on_destroy()
|
||||
{ shared_memory_object::remove(m_name); }
|
||||
};
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_SHARED_MEMORY_OBJECT_HPP
|
||||
@@ -0,0 +1,61 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2014-2015 Kohei Takahashi
|
||||
|
||||
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 FUSION_LIST_MAIN_10262014_0447
|
||||
#define FUSION_LIST_MAIN_10262014_0447
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/fusion/support/config.hpp>
|
||||
#include <boost/fusion/container/list/list_fwd.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Without variadics, we will use the PP version
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(BOOST_FUSION_HAS_VARIADIC_LIST)
|
||||
# include <boost/fusion/container/list/detail/cpp03/list_to_cons.hpp>
|
||||
#else
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// C++11 interface
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/fusion/container/list/cons.hpp>
|
||||
#include <boost/fusion/support/detail/access.hpp>
|
||||
|
||||
namespace boost { namespace fusion { namespace detail
|
||||
{
|
||||
template <typename ...T>
|
||||
struct list_to_cons;
|
||||
|
||||
template <>
|
||||
struct list_to_cons<>
|
||||
{
|
||||
typedef nil_ type;
|
||||
|
||||
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
||||
static type call() { return type(); }
|
||||
};
|
||||
|
||||
template <typename Head, typename ...Tail>
|
||||
struct list_to_cons<Head, Tail...>
|
||||
{
|
||||
typedef Head head_type;
|
||||
typedef list_to_cons<Tail...> tail_list_to_cons;
|
||||
typedef typename tail_list_to_cons::type tail_type;
|
||||
|
||||
typedef cons<head_type, tail_type> type;
|
||||
|
||||
BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
|
||||
static type
|
||||
call(typename detail::call_param<Head>::type _h,
|
||||
typename detail::call_param<Tail>::type ..._t)
|
||||
{
|
||||
return type(_h, tail_list_to_cons::call(_t...));
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,195 @@
|
||||
// Copyright Neil Groves 2009. Use, modification and
|
||||
// distribution is subject to the Boost Software License, Version
|
||||
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
//
|
||||
// For more information, see http://www.boost.org/libs/range/
|
||||
//
|
||||
#ifndef BOOST_RANGE_ALGORITHM_MISMATCH_HPP_INCLUDED
|
||||
#define BOOST_RANGE_ALGORITHM_MISMATCH_HPP_INCLUDED
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/concepts.hpp>
|
||||
#include <boost/range/difference_type.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace range_detail
|
||||
{
|
||||
template< class SinglePassTraversalReadableIterator1,
|
||||
class SinglePassTraversalReadableIterator2 >
|
||||
inline std::pair<SinglePassTraversalReadableIterator1,
|
||||
SinglePassTraversalReadableIterator2>
|
||||
mismatch_impl(SinglePassTraversalReadableIterator1 first1,
|
||||
SinglePassTraversalReadableIterator1 last1,
|
||||
SinglePassTraversalReadableIterator2 first2,
|
||||
SinglePassTraversalReadableIterator2 last2)
|
||||
{
|
||||
while (first1 != last1 && first2 != last2 && *first1 == *first2)
|
||||
{
|
||||
++first1;
|
||||
++first2;
|
||||
}
|
||||
return std::pair<SinglePassTraversalReadableIterator1,
|
||||
SinglePassTraversalReadableIterator2>(first1, first2);
|
||||
}
|
||||
|
||||
template< class SinglePassTraversalReadableIterator1,
|
||||
class SinglePassTraversalReadableIterator2,
|
||||
class BinaryPredicate >
|
||||
inline std::pair<SinglePassTraversalReadableIterator1,
|
||||
SinglePassTraversalReadableIterator2>
|
||||
mismatch_impl(SinglePassTraversalReadableIterator1 first1,
|
||||
SinglePassTraversalReadableIterator1 last1,
|
||||
SinglePassTraversalReadableIterator2 first2,
|
||||
SinglePassTraversalReadableIterator2 last2,
|
||||
BinaryPredicate pred)
|
||||
{
|
||||
while (first1 != last1 && first2 != last2 && pred(*first1, *first2))
|
||||
{
|
||||
++first1;
|
||||
++first2;
|
||||
}
|
||||
return std::pair<SinglePassTraversalReadableIterator1,
|
||||
SinglePassTraversalReadableIterator2>(first1, first2);
|
||||
}
|
||||
} // namespace range_detail
|
||||
|
||||
namespace range
|
||||
{
|
||||
/// \brief template function mismatch
|
||||
///
|
||||
/// range-based version of the mismatch std algorithm
|
||||
///
|
||||
/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
|
||||
/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
|
||||
/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
||||
template< class SinglePassRange1, class SinglePassRange2 >
|
||||
inline std::pair<
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
|
||||
mismatch(SinglePassRange1& rng1, const SinglePassRange2 & rng2)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||
|
||||
return ::boost::range_detail::mismatch_impl(
|
||||
::boost::begin(rng1), ::boost::end(rng1),
|
||||
::boost::begin(rng2), ::boost::end(rng2));
|
||||
}
|
||||
|
||||
/// \overload
|
||||
template< class SinglePassRange1, class SinglePassRange2 >
|
||||
inline std::pair<
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
|
||||
mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||
|
||||
return ::boost::range_detail::mismatch_impl(
|
||||
::boost::begin(rng1), ::boost::end(rng1),
|
||||
::boost::begin(rng2), ::boost::end(rng2));
|
||||
}
|
||||
|
||||
/// \overload
|
||||
template< class SinglePassRange1, class SinglePassRange2 >
|
||||
inline std::pair<
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
|
||||
mismatch(SinglePassRange1& rng1, SinglePassRange2 & rng2)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
|
||||
|
||||
return ::boost::range_detail::mismatch_impl(
|
||||
::boost::begin(rng1), ::boost::end(rng1),
|
||||
::boost::begin(rng2), ::boost::end(rng2));
|
||||
}
|
||||
|
||||
/// \overload
|
||||
template< class SinglePassRange1, class SinglePassRange2 >
|
||||
inline std::pair<
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
|
||||
mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
|
||||
|
||||
return ::boost::range_detail::mismatch_impl(
|
||||
::boost::begin(rng1), ::boost::end(rng1),
|
||||
::boost::begin(rng2), ::boost::end(rng2));
|
||||
}
|
||||
|
||||
|
||||
/// \overload
|
||||
template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
|
||||
inline std::pair<
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
|
||||
mismatch(SinglePassRange1& rng1, const SinglePassRange2& rng2, BinaryPredicate pred)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||
|
||||
return ::boost::range_detail::mismatch_impl(
|
||||
::boost::begin(rng1), ::boost::end(rng1),
|
||||
::boost::begin(rng2), ::boost::end(rng2), pred);
|
||||
}
|
||||
|
||||
/// \overload
|
||||
template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
|
||||
inline std::pair<
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
|
||||
mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2, BinaryPredicate pred)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
||||
|
||||
return ::boost::range_detail::mismatch_impl(
|
||||
::boost::begin(rng1), ::boost::end(rng1),
|
||||
::boost::begin(rng2), ::boost::end(rng2), pred);
|
||||
}
|
||||
|
||||
/// \overload
|
||||
template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
|
||||
inline std::pair<
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
|
||||
mismatch(SinglePassRange1& rng1, SinglePassRange2& rng2, BinaryPredicate pred)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
|
||||
|
||||
return ::boost::range_detail::mismatch_impl(
|
||||
::boost::begin(rng1), ::boost::end(rng1),
|
||||
::boost::begin(rng2), ::boost::end(rng2), pred);
|
||||
}
|
||||
|
||||
/// \overload
|
||||
template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
|
||||
inline std::pair<
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
|
||||
mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2, BinaryPredicate pred)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
|
||||
|
||||
return ::boost::range_detail::mismatch_impl(
|
||||
::boost::begin(rng1), ::boost::end(rng1),
|
||||
::boost::begin(rng2), ::boost::end(rng2), pred);
|
||||
}
|
||||
|
||||
} // namespace range
|
||||
using range::mismatch;
|
||||
} // namespace boost
|
||||
|
||||
#endif // include guard
|
||||
@@ -0,0 +1,178 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file vararg_matches_impl.hpp
|
||||
/// Specializations of the vararg_matches_impl template
|
||||
//
|
||||
// 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)
|
||||
template<typename Args, typename Back, long To>
|
||||
struct vararg_matches_impl<Args, Back, 2, To>
|
||||
: and_2<
|
||||
matches_<
|
||||
typename detail::expr_traits<typename Args::child1>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child1>::value_type::proto_grammar
|
||||
, Back
|
||||
>::value
|
||||
, vararg_matches_impl<Args, Back, 2 + 1, To>
|
||||
>
|
||||
{};
|
||||
template<typename Args, typename Back>
|
||||
struct vararg_matches_impl<Args, Back, 2, 2>
|
||||
: matches_<
|
||||
typename detail::expr_traits<typename Args::child1>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child1>::value_type::proto_grammar
|
||||
, Back
|
||||
>
|
||||
{};
|
||||
template<typename Args, typename Back, long To>
|
||||
struct vararg_matches_impl<Args, Back, 3, To>
|
||||
: and_2<
|
||||
matches_<
|
||||
typename detail::expr_traits<typename Args::child2>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child2>::value_type::proto_grammar
|
||||
, Back
|
||||
>::value
|
||||
, vararg_matches_impl<Args, Back, 3 + 1, To>
|
||||
>
|
||||
{};
|
||||
template<typename Args, typename Back>
|
||||
struct vararg_matches_impl<Args, Back, 3, 3>
|
||||
: matches_<
|
||||
typename detail::expr_traits<typename Args::child2>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child2>::value_type::proto_grammar
|
||||
, Back
|
||||
>
|
||||
{};
|
||||
template<typename Args, typename Back, long To>
|
||||
struct vararg_matches_impl<Args, Back, 4, To>
|
||||
: and_2<
|
||||
matches_<
|
||||
typename detail::expr_traits<typename Args::child3>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child3>::value_type::proto_grammar
|
||||
, Back
|
||||
>::value
|
||||
, vararg_matches_impl<Args, Back, 4 + 1, To>
|
||||
>
|
||||
{};
|
||||
template<typename Args, typename Back>
|
||||
struct vararg_matches_impl<Args, Back, 4, 4>
|
||||
: matches_<
|
||||
typename detail::expr_traits<typename Args::child3>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child3>::value_type::proto_grammar
|
||||
, Back
|
||||
>
|
||||
{};
|
||||
template<typename Args, typename Back, long To>
|
||||
struct vararg_matches_impl<Args, Back, 5, To>
|
||||
: and_2<
|
||||
matches_<
|
||||
typename detail::expr_traits<typename Args::child4>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child4>::value_type::proto_grammar
|
||||
, Back
|
||||
>::value
|
||||
, vararg_matches_impl<Args, Back, 5 + 1, To>
|
||||
>
|
||||
{};
|
||||
template<typename Args, typename Back>
|
||||
struct vararg_matches_impl<Args, Back, 5, 5>
|
||||
: matches_<
|
||||
typename detail::expr_traits<typename Args::child4>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child4>::value_type::proto_grammar
|
||||
, Back
|
||||
>
|
||||
{};
|
||||
template<typename Args, typename Back, long To>
|
||||
struct vararg_matches_impl<Args, Back, 6, To>
|
||||
: and_2<
|
||||
matches_<
|
||||
typename detail::expr_traits<typename Args::child5>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child5>::value_type::proto_grammar
|
||||
, Back
|
||||
>::value
|
||||
, vararg_matches_impl<Args, Back, 6 + 1, To>
|
||||
>
|
||||
{};
|
||||
template<typename Args, typename Back>
|
||||
struct vararg_matches_impl<Args, Back, 6, 6>
|
||||
: matches_<
|
||||
typename detail::expr_traits<typename Args::child5>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child5>::value_type::proto_grammar
|
||||
, Back
|
||||
>
|
||||
{};
|
||||
template<typename Args, typename Back, long To>
|
||||
struct vararg_matches_impl<Args, Back, 7, To>
|
||||
: and_2<
|
||||
matches_<
|
||||
typename detail::expr_traits<typename Args::child6>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child6>::value_type::proto_grammar
|
||||
, Back
|
||||
>::value
|
||||
, vararg_matches_impl<Args, Back, 7 + 1, To>
|
||||
>
|
||||
{};
|
||||
template<typename Args, typename Back>
|
||||
struct vararg_matches_impl<Args, Back, 7, 7>
|
||||
: matches_<
|
||||
typename detail::expr_traits<typename Args::child6>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child6>::value_type::proto_grammar
|
||||
, Back
|
||||
>
|
||||
{};
|
||||
template<typename Args, typename Back, long To>
|
||||
struct vararg_matches_impl<Args, Back, 8, To>
|
||||
: and_2<
|
||||
matches_<
|
||||
typename detail::expr_traits<typename Args::child7>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child7>::value_type::proto_grammar
|
||||
, Back
|
||||
>::value
|
||||
, vararg_matches_impl<Args, Back, 8 + 1, To>
|
||||
>
|
||||
{};
|
||||
template<typename Args, typename Back>
|
||||
struct vararg_matches_impl<Args, Back, 8, 8>
|
||||
: matches_<
|
||||
typename detail::expr_traits<typename Args::child7>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child7>::value_type::proto_grammar
|
||||
, Back
|
||||
>
|
||||
{};
|
||||
template<typename Args, typename Back, long To>
|
||||
struct vararg_matches_impl<Args, Back, 9, To>
|
||||
: and_2<
|
||||
matches_<
|
||||
typename detail::expr_traits<typename Args::child8>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child8>::value_type::proto_grammar
|
||||
, Back
|
||||
>::value
|
||||
, vararg_matches_impl<Args, Back, 9 + 1, To>
|
||||
>
|
||||
{};
|
||||
template<typename Args, typename Back>
|
||||
struct vararg_matches_impl<Args, Back, 9, 9>
|
||||
: matches_<
|
||||
typename detail::expr_traits<typename Args::child8>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child8>::value_type::proto_grammar
|
||||
, Back
|
||||
>
|
||||
{};
|
||||
template<typename Args, typename Back, long To>
|
||||
struct vararg_matches_impl<Args, Back, 10, To>
|
||||
: and_2<
|
||||
matches_<
|
||||
typename detail::expr_traits<typename Args::child9>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child9>::value_type::proto_grammar
|
||||
, Back
|
||||
>::value
|
||||
, vararg_matches_impl<Args, Back, 10 + 1, To>
|
||||
>
|
||||
{};
|
||||
template<typename Args, typename Back>
|
||||
struct vararg_matches_impl<Args, Back, 10, 10>
|
||||
: matches_<
|
||||
typename detail::expr_traits<typename Args::child9>::value_type::proto_derived_expr
|
||||
, typename detail::expr_traits<typename Args::child9>::value_type::proto_grammar
|
||||
, Back
|
||||
>
|
||||
{};
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef REFCOUNT_DWA2002615_HPP
|
||||
# define REFCOUNT_DWA2002615_HPP
|
||||
|
||||
# include <boost/python/detail/prefix.hpp>
|
||||
# include <boost/python/cast.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class T>
|
||||
inline T* incref(T* p)
|
||||
{
|
||||
Py_INCREF(python::upcast<PyObject>(p));
|
||||
return p;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T* xincref(T* p)
|
||||
{
|
||||
Py_XINCREF(python::upcast<PyObject>(p));
|
||||
return p;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void decref(T* p)
|
||||
{
|
||||
assert( Py_REFCNT(python::upcast<PyObject>(p)) > 0 );
|
||||
Py_DECREF(python::upcast<PyObject>(p));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void xdecref(T* p)
|
||||
{
|
||||
assert( !p || Py_REFCNT(python::upcast<PyObject>(p)) > 0 );
|
||||
Py_XDECREF(python::upcast<PyObject>(p));
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // REFCOUNT_DWA2002615_HPP
|
||||
@@ -0,0 +1,110 @@
|
||||
program wsprlf
|
||||
|
||||
parameter (NN=121) !Total symbols
|
||||
parameter (NSPS=28800) !Samples per symbol @ fs=12000 Hz
|
||||
parameter (NZ=NSPS*NN) !Samples in waveform
|
||||
|
||||
character*8 arg
|
||||
complex c(0:NZ-1)
|
||||
real*8 twopi,fs,f0,dt,phi,dphi
|
||||
real x(0:NZ-1)
|
||||
real p(0:NZ/2)
|
||||
real h0(0:NSPS/2) !Pulse shape, rising edge
|
||||
real h1(0:NSPS/2) !Pulse shape, trailing edge
|
||||
real tmp(NN)
|
||||
integer id(NN) !Generated data
|
||||
integer ie(NN) !Differentially encoded data
|
||||
data fs/12000.d0/
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.ne.3) then
|
||||
print*,'Usage: wsprlf f0 t1 snr'
|
||||
goto 999
|
||||
endif
|
||||
call getarg(1,arg)
|
||||
read(arg,*) f0
|
||||
call getarg(2,arg)
|
||||
read(arg,*) t1
|
||||
call getarg(3,arg)
|
||||
read(arg,*) snrdb
|
||||
|
||||
call random_number(tmp) !Generate random bipolar data
|
||||
id=1
|
||||
where(tmp.lt.0.5) id=-1
|
||||
ie(1)=1
|
||||
do i=2,NN !Differentially encode
|
||||
ie(i)=id(i)*ie(i-1)
|
||||
enddo
|
||||
|
||||
n1=nint(t1*NSPS)
|
||||
twopi=8.d0*atan(1.d0)
|
||||
|
||||
do i=0,2*n1-1 !Define the shape functions
|
||||
if(i.le.n1-1) then
|
||||
h0(i)=0.5*(1.0-cos(0.5*i*twopi/n1))
|
||||
else
|
||||
h1(i-n1)=0.5*(1.0-cos(0.5*i*twopi/n1))
|
||||
endif
|
||||
enddo
|
||||
if(t1.eq.0.0) h0=1
|
||||
if(t1.eq.0.0) h1=1
|
||||
|
||||
! Shape the channel pulses
|
||||
x=1.
|
||||
x(0:n1-1)=h0(0:n1-1) !Leading edge of 1st pulse
|
||||
do j=2,NN !Leading edges
|
||||
if(ie(j).ne.ie(j-1)) then
|
||||
ia=(j-1)*NSPS + 1
|
||||
ib=ia+n1-1
|
||||
x(ia:ib)=h0(0:n1-1)
|
||||
endif
|
||||
enddo
|
||||
do j=1,NN-1 !Trailing edges
|
||||
if(ie(j+1).ne.ie(j)) then
|
||||
ib=j*NSPS
|
||||
ia=ib-n1+1
|
||||
x(ia:ib)=h1(0:n1-1)
|
||||
endif
|
||||
enddo
|
||||
ib=NN*NSPS-1
|
||||
ia=ib-n1+1
|
||||
x(ia:ib)=h1(0:n1-1) !Trailing edge of last pulse
|
||||
|
||||
dt=1.d0/fs
|
||||
ts=dt*NSPS
|
||||
baud=fs/NSPS
|
||||
write(*,1000) baud,ts
|
||||
1000 format('Baud:',f6.3,' Tsym:',f6.3)
|
||||
|
||||
dphi=twopi*f0*dt
|
||||
phi=0.d0
|
||||
i=-1
|
||||
do j=1,NN !Generate the baseband waveform
|
||||
a=ie(j)
|
||||
do k=1,NSPS
|
||||
i=i+1
|
||||
x(i)=a*x(i)
|
||||
phi=phi+dphi
|
||||
if(phi.gt.twopi) phi=phi-twopi
|
||||
xphi=phi
|
||||
c(i)=x(i)*cmplx(cos(xphi),sin(xphi))
|
||||
sym=i*dt/ts
|
||||
if(j.le.20) write(13,1010) sym,x(i),c(i)
|
||||
1010 format(4f12.6)
|
||||
enddo
|
||||
enddo
|
||||
|
||||
call four2a(c,NZ,1,-1,1) !To freq domain
|
||||
df=fs/NZ
|
||||
nh=NZ/2
|
||||
do i=0,nh
|
||||
f=i*df
|
||||
p(i)=real(c(i))**2 + aimag(c(i))**2
|
||||
enddo
|
||||
p=p/maxval(p)
|
||||
do i=0,nh !Save spectrum for plotting
|
||||
write(14,1020) i*df,p(i),10.0*log10(p(i)+1.e-8)
|
||||
1020 format(f10.3,2e12.3)
|
||||
enddo
|
||||
|
||||
999 end program wsprlf
|
||||
@@ -0,0 +1,72 @@
|
||||
subroutine fil3c(c1,n1,c2,n2)
|
||||
|
||||
! FIR complex-to-complex low-pass filter designed with ScopeFIR
|
||||
!
|
||||
!-----------------------------------------------
|
||||
! fsample (Hz) 12000 Input sample rate
|
||||
! Ntaps 113 Number of filter taps
|
||||
! fc (Hz) 500 Cutoff frequency
|
||||
! fstop (Hz) 750 Lower limit of stopband
|
||||
! Ripple (dB) 0.2 Ripple in passband
|
||||
! Stop Atten (dB) 50 Stopband attenuation
|
||||
! fout (Hz) 1500 Output sample rate
|
||||
|
||||
! Suggest calling with n1 = 8*n2 + 105, where n2 is the desired number
|
||||
! of 1500 Hz output samples.
|
||||
|
||||
parameter (NTAPS=113)
|
||||
parameter (NH=NTAPS/2)
|
||||
parameter (NDOWN=8) !Downsample ratio = 1/8
|
||||
complex c1(n1)
|
||||
complex c2(n1/NDOWN)
|
||||
complex z
|
||||
|
||||
! Filter coefficients:
|
||||
real a(-NH:NH)
|
||||
data a/ &
|
||||
-0.001818142144,-0.000939132050,-0.001044063556,-0.001042685542, &
|
||||
-0.000908957610,-0.000628132309,-0.000202701465, 0.000346307629, &
|
||||
0.000978154552, 0.001634336295, 0.002243121592, 0.002726064379, &
|
||||
0.003006201675, 0.003018055983, 0.002717699575, 0.002091546534, &
|
||||
0.001162489032,-0.000007904811,-0.001321554806,-0.002649908053, &
|
||||
-0.003843608784,-0.004747338068,-0.005218967042,-0.005148229529, &
|
||||
-0.004470167307,-0.003177923811,-0.001335998901, 0.000915924193, &
|
||||
0.003386100636, 0.005818719744, 0.007939147967, 0.009465071347, &
|
||||
0.010145641899, 0.009787447819, 0.008285915754, 0.005645995244, &
|
||||
0.001995842303,-0.002410369720,-0.007202515555,-0.011916811719, &
|
||||
-0.016028350845,-0.018993391440,-0.020297455955,-0.019503792208, &
|
||||
-0.016298136197,-0.010526834635,-0.002223837363, 0.008378305829, &
|
||||
0.020854478160, 0.034608532659, 0.048909701463, 0.062944127288, &
|
||||
0.075874892030, 0.086903764340, 0.095332017649, 0.100619428175, &
|
||||
0.102420526192, 0.100619428175, 0.095332017649, 0.086903764340, &
|
||||
0.075874892030, 0.062944127288, 0.048909701463, 0.034608532659, &
|
||||
0.020854478160, 0.008378305829,-0.002223837363,-0.010526834635, &
|
||||
-0.016298136197,-0.019503792208,-0.020297455955,-0.018993391440, &
|
||||
-0.016028350845,-0.011916811719,-0.007202515555,-0.002410369720, &
|
||||
0.001995842303, 0.005645995244, 0.008285915754, 0.009787447819, &
|
||||
0.010145641899, 0.009465071347, 0.007939147967, 0.005818719744, &
|
||||
0.003386100636, 0.000915924193,-0.001335998901,-0.003177923811, &
|
||||
-0.004470167307,-0.005148229529,-0.005218967042,-0.004747338068, &
|
||||
-0.003843608784,-0.002649908053,-0.001321554806,-0.000007904811, &
|
||||
0.001162489032, 0.002091546534, 0.002717699575, 0.003018055983, &
|
||||
0.003006201675, 0.002726064379, 0.002243121592, 0.001634336295, &
|
||||
0.000978154552, 0.000346307629,-0.000202701465,-0.000628132309, &
|
||||
-0.000908957610,-0.001042685542,-0.001044063556,-0.000939132050, &
|
||||
-0.001818142144/
|
||||
save a
|
||||
|
||||
n2=(n1-NTAPS+NDOWN)/NDOWN
|
||||
k0=NH-NDOWN+1
|
||||
|
||||
! Loop over all output samples
|
||||
do i=1,n2
|
||||
z=0.
|
||||
k=k0 + NDOWN*i
|
||||
do j=-NH,NH
|
||||
z=z + c1(j+k)*a(j)
|
||||
enddo
|
||||
c2(i)=z
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine fil3c
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,25 @@
|
||||
|
||||
#ifndef BOOST_MPL_ARITHMETIC_HPP_INCLUDED
|
||||
#define BOOST_MPL_ARITHMETIC_HPP_INCLUDED
|
||||
|
||||
// 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#include <boost/mpl/plus.hpp>
|
||||
#include <boost/mpl/minus.hpp>
|
||||
#include <boost/mpl/times.hpp>
|
||||
#include <boost/mpl/divides.hpp>
|
||||
#include <boost/mpl/modulus.hpp>
|
||||
#include <boost/mpl/negate.hpp>
|
||||
#include <boost/mpl/multiplies.hpp> // deprecated
|
||||
|
||||
#endif // BOOST_MPL_ARITHMETIC_HPP_INCLUDED
|
||||
@@ -0,0 +1,156 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_counted_base_sync.hpp - g++ 4.1+ __sync intrinsics
|
||||
//
|
||||
// Copyright (c) 2007 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
#include <limits.h>
|
||||
|
||||
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
|
||||
# include <ia64intrin.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if INT_MAX >= 2147483647
|
||||
|
||||
typedef int sp_int32_t;
|
||||
|
||||
#else
|
||||
|
||||
typedef long sp_int32_t;
|
||||
|
||||
#endif
|
||||
|
||||
inline void atomic_increment( sp_int32_t * pw )
|
||||
{
|
||||
__sync_fetch_and_add( pw, 1 );
|
||||
}
|
||||
|
||||
inline sp_int32_t atomic_decrement( sp_int32_t * pw )
|
||||
{
|
||||
return __sync_fetch_and_add( pw, -1 );
|
||||
}
|
||||
|
||||
inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw )
|
||||
{
|
||||
// long r = *pw;
|
||||
// if( r != 0 ) ++*pw;
|
||||
// return r;
|
||||
|
||||
sp_int32_t r = *pw;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
if( r == 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
sp_int32_t r2 = __sync_val_compare_and_swap( pw, r, r + 1 );
|
||||
|
||||
if( r2 == r )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = r2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
sp_int32_t use_count_; // #shared
|
||||
sp_int32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return const_cast< sp_int32_t const volatile & >( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
|
||||
@@ -0,0 +1,100 @@
|
||||
#include "IARURegions.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
#include <QModelIndex>
|
||||
#include <QMetaType>
|
||||
|
||||
#include "moc_IARURegions.cpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
// human readable strings for each Region enumeration value
|
||||
char const * const region_names[] =
|
||||
{
|
||||
"All",
|
||||
"Region 1",
|
||||
"Region 2",
|
||||
"Region 3",
|
||||
};
|
||||
std::size_t constexpr region_names_size = sizeof (region_names) / sizeof (region_names[0]);
|
||||
}
|
||||
|
||||
IARURegions::IARURegions (QObject * parent)
|
||||
: QAbstractListModel {parent}
|
||||
{
|
||||
static_assert (region_names_size == SENTINAL,
|
||||
"region_names array must match Region enumeration");
|
||||
}
|
||||
|
||||
char const * IARURegions::name (Region r)
|
||||
{
|
||||
return region_names[static_cast<int> (r)];
|
||||
}
|
||||
|
||||
auto IARURegions::value (QString const& s) -> Region
|
||||
{
|
||||
auto end = region_names + region_names_size;
|
||||
auto p = std::find_if (region_names, end
|
||||
, [&s] (char const * const name) {
|
||||
return name == s;
|
||||
});
|
||||
return p != end ? static_cast<Region> (p - region_names) : ALL;
|
||||
}
|
||||
|
||||
QVariant IARURegions::data (QModelIndex const& index, int role) const
|
||||
{
|
||||
QVariant item;
|
||||
|
||||
if (index.isValid ())
|
||||
{
|
||||
auto const& row = index.row ();
|
||||
switch (role)
|
||||
{
|
||||
case Qt::ToolTipRole:
|
||||
case Qt::AccessibleDescriptionRole:
|
||||
item = tr ("IARU Region");
|
||||
break;
|
||||
|
||||
case Qt::EditRole:
|
||||
item = static_cast<Region> (row);
|
||||
break;
|
||||
|
||||
case Qt::DisplayRole:
|
||||
case Qt::AccessibleTextRole:
|
||||
item = region_names[row];
|
||||
break;
|
||||
|
||||
case Qt::TextAlignmentRole:
|
||||
item = Qt::AlignHCenter + Qt::AlignVCenter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
QVariant IARURegions::headerData (int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
QVariant result;
|
||||
|
||||
if (Qt::DisplayRole == role && Qt::Horizontal == orientation)
|
||||
{
|
||||
result = tr ("IARU Region");
|
||||
}
|
||||
else
|
||||
{
|
||||
result = QAbstractListModel::headerData (section, orientation, role);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#if !defined (QT_NO_DEBUG_STREAM)
|
||||
ENUM_QDEBUG_OPS_IMPL (IARURegions, Region);
|
||||
#endif
|
||||
|
||||
ENUM_QDATASTREAM_OPS_IMPL (IARURegions, Region);
|
||||
ENUM_CONVERSION_OPS_IMPL (IARURegions, Region);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2007 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_INCLUDE_VALUE_OF)
|
||||
#define FUSION_INCLUDE_VALUE_OF
|
||||
|
||||
#include <boost/fusion/support/config.hpp>
|
||||
#include <boost/fusion/iterator/value_of.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
[auto_generated]
|
||||
boost/numeric/odeint/integrate/check_adapter.hpp
|
||||
|
||||
[begin_description]
|
||||
Adapters to add checking facility to stepper and observer
|
||||
[end_description]
|
||||
|
||||
Copyright 2015 Mario Mulansky
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or
|
||||
copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_NUMERIC_ODEINT_INTEGRATE_CHECK_ADAPTER_HPP_INCLUDED
|
||||
#define BOOST_NUMERIC_ODEINT_INTEGRATE_CHECK_ADAPTER_HPP_INCLUDED
|
||||
|
||||
#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
|
||||
#include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace numeric {
|
||||
namespace odeint {
|
||||
|
||||
template<class Stepper, class Checker,
|
||||
class StepperCategory = typename base_tag<typename Stepper::stepper_category>::type>
|
||||
class checked_stepper;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Adapter to combine basic stepper and checker.
|
||||
*/
|
||||
template<class Stepper, class Checker>
|
||||
class checked_stepper<Stepper, Checker, stepper_tag>
|
||||
{
|
||||
|
||||
public:
|
||||
typedef Stepper stepper_type;
|
||||
typedef Checker checker_type;
|
||||
// forward stepper typedefs
|
||||
typedef typename stepper_type::state_type state_type;
|
||||
typedef typename stepper_type::value_type value_type;
|
||||
typedef typename stepper_type::deriv_type deriv_type;
|
||||
typedef typename stepper_type::time_type time_type;
|
||||
|
||||
private:
|
||||
stepper_type &m_stepper;
|
||||
checker_type &m_checker;
|
||||
|
||||
public:
|
||||
/**
|
||||
* \brief Construct the checked_stepper.
|
||||
*/
|
||||
checked_stepper(stepper_type &stepper, checker_type &checker)
|
||||
: m_stepper(stepper), m_checker(checker) { }
|
||||
|
||||
/**
|
||||
* \brief forward of the do_step method
|
||||
*/
|
||||
template<class System, class StateInOut>
|
||||
void do_step(System system, StateInOut &state, const time_type t, const time_type dt)
|
||||
{
|
||||
// do the step
|
||||
m_stepper.do_step(system, state, t, dt);
|
||||
// call the checker
|
||||
m_checker();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Adapter to combine controlled stepper and checker.
|
||||
*/
|
||||
template<class ControlledStepper, class Checker>
|
||||
class checked_stepper<ControlledStepper, Checker, controlled_stepper_tag>
|
||||
{
|
||||
|
||||
public:
|
||||
typedef ControlledStepper stepper_type;
|
||||
typedef Checker checker_type;
|
||||
// forward stepper typedefs
|
||||
typedef typename stepper_type::state_type state_type;
|
||||
typedef typename stepper_type::value_type value_type;
|
||||
typedef typename stepper_type::deriv_type deriv_type;
|
||||
typedef typename stepper_type::time_type time_type;
|
||||
|
||||
private:
|
||||
stepper_type &m_stepper;
|
||||
checker_type &m_checker;
|
||||
|
||||
public:
|
||||
/**
|
||||
* \brief Construct the checked_stepper.
|
||||
*/
|
||||
checked_stepper(stepper_type &stepper, checker_type &checker)
|
||||
: m_stepper(stepper), m_checker(checker) { }
|
||||
|
||||
/**
|
||||
* \brief forward of the do_step method
|
||||
*/
|
||||
template< class System , class StateInOut >
|
||||
controlled_step_result try_step( System system , StateInOut &state , time_type &t , time_type &dt )
|
||||
{
|
||||
// do the step
|
||||
if( m_stepper.try_step(system, state, t, dt) == success )
|
||||
{
|
||||
// call the checker if step was successful
|
||||
m_checker();
|
||||
return success;
|
||||
} else
|
||||
{
|
||||
// step failed -> return fail
|
||||
return fail;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Adapter to combine dense out stepper and checker.
|
||||
*/
|
||||
template<class DenseOutStepper, class Checker>
|
||||
class checked_stepper<DenseOutStepper, Checker, dense_output_stepper_tag>
|
||||
{
|
||||
|
||||
public:
|
||||
typedef DenseOutStepper stepper_type;
|
||||
typedef Checker checker_type;
|
||||
// forward stepper typedefs
|
||||
typedef typename stepper_type::state_type state_type;
|
||||
typedef typename stepper_type::value_type value_type;
|
||||
typedef typename stepper_type::deriv_type deriv_type;
|
||||
typedef typename stepper_type::time_type time_type;
|
||||
|
||||
private:
|
||||
stepper_type &m_stepper;
|
||||
checker_type &m_checker;
|
||||
|
||||
public:
|
||||
/**
|
||||
* \brief Construct the checked_stepper.
|
||||
*/
|
||||
checked_stepper(stepper_type &stepper, checker_type &checker)
|
||||
: m_stepper(stepper), m_checker(checker) { }
|
||||
|
||||
|
||||
template< class System >
|
||||
std::pair< time_type , time_type > do_step( System system )
|
||||
{
|
||||
m_checker();
|
||||
return m_stepper.do_step(system);
|
||||
}
|
||||
|
||||
/* provide the remaining dense out stepper interface */
|
||||
template< class StateType >
|
||||
void initialize( const StateType &x0 , time_type t0 , time_type dt0 )
|
||||
{ m_stepper.initialize(x0, t0, dt0); }
|
||||
|
||||
|
||||
template< class StateOut >
|
||||
void calc_state( time_type t , StateOut &x ) const
|
||||
{ m_stepper.calc_state(t, x); }
|
||||
|
||||
template< class StateOut >
|
||||
void calc_state( time_type t , const StateOut &x ) const
|
||||
{ m_stepper.calc_state(t, x); }
|
||||
|
||||
const state_type& current_state( void ) const
|
||||
{ return m_stepper.current_state(); }
|
||||
|
||||
time_type current_time( void ) const
|
||||
{ return m_stepper.current_time(); }
|
||||
|
||||
const state_type& previous_state( void ) const
|
||||
{ return m_stepper.previous_state(); }
|
||||
|
||||
time_type previous_time( void ) const
|
||||
{ return m_stepper.previous_time(); }
|
||||
|
||||
time_type current_time_step( void ) const
|
||||
{ return m_stepper.current_time_step(); }
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Adapter to combine observer and checker.
|
||||
*/
|
||||
template<class Observer, class Checker>
|
||||
class checked_observer
|
||||
{
|
||||
public:
|
||||
typedef Observer observer_type;
|
||||
typedef Checker checker_type;
|
||||
|
||||
private:
|
||||
observer_type &m_observer;
|
||||
checker_type &m_checker;
|
||||
|
||||
public:
|
||||
checked_observer(observer_type &observer, checker_type &checker)
|
||||
: m_observer(observer), m_checker(checker)
|
||||
{}
|
||||
|
||||
template< class State , class Time >
|
||||
void operator()(const State& state, Time t) const
|
||||
{
|
||||
// call the observer
|
||||
m_observer(state, t);
|
||||
// reset the checker
|
||||
m_checker.reset();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace odeint
|
||||
} // namespace numeric
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,79 @@
|
||||
#ifndef BOOST_SERIALIZATION_COLLECTION_TRAITS_HPP
|
||||
#define BOOST_SERIALIZATION_COLLECTION_TRAITS_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// collection_traits.hpp:
|
||||
|
||||
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
// This header assigns a level implemenation trait to a collection type
|
||||
// for all primitives. It is needed so that archives which are meant to be
|
||||
// portable don't write class information in the archive. Since, not all
|
||||
// compiles recognize the same set of primitive types, the possibility
|
||||
// exists for archives to be non-portable if class information for primitive
|
||||
// types is included. This is addressed by the following macros.
|
||||
#include <boost/config.hpp>
|
||||
//#include <boost/mpl/integral_c.hpp>
|
||||
#include <boost/mpl/integral_c_tag.hpp>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/integer_traits.hpp>
|
||||
#include <climits> // ULONG_MAX
|
||||
#include <boost/serialization/level.hpp>
|
||||
|
||||
#define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(T, C) \
|
||||
template<> \
|
||||
struct implementation_level< C < T > > { \
|
||||
typedef mpl::integral_c_tag tag; \
|
||||
typedef mpl::int_<object_serializable> type; \
|
||||
BOOST_STATIC_CONSTANT(int, value = object_serializable); \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
#if defined(BOOST_NO_CWCHAR) || defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
#define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C)
|
||||
#else
|
||||
#define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C) \
|
||||
BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(wchar_t, C) \
|
||||
/**/
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_LONG_LONG)
|
||||
#define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C) \
|
||||
BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(boost::long_long_type, C) \
|
||||
BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(boost::ulong_long_type, C) \
|
||||
/**/
|
||||
#else
|
||||
#define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C)
|
||||
#endif
|
||||
|
||||
#define BOOST_SERIALIZATION_COLLECTION_TRAITS(C) \
|
||||
namespace boost { namespace serialization { \
|
||||
BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(bool, C) \
|
||||
BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(char, C) \
|
||||
BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed char, C) \
|
||||
BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned char, C) \
|
||||
BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed int, C) \
|
||||
BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned int, C) \
|
||||
BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed long, C) \
|
||||
BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned long, C) \
|
||||
BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(float, C) \
|
||||
BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(double, C) \
|
||||
BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned short, C) \
|
||||
BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed short, C) \
|
||||
BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C) \
|
||||
BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C) \
|
||||
} } \
|
||||
/**/
|
||||
|
||||
#endif // BOOST_SERIALIZATION_COLLECTION_TRAITS
|
||||
@@ -0,0 +1,15 @@
|
||||
Except as otherwise specified, all program code and documentation in this
|
||||
directory is copyright (c) 1995-2012 by Radford M. Neal.
|
||||
|
||||
Permission is granted for anyone to copy, use, modify, and distribute
|
||||
these programs and accompanying documents for any purpose, provided
|
||||
this copyright notice is retained and prominently displayed, and note
|
||||
is made of any changes made to these programs. These programs and
|
||||
documents are distributed without any warranty, express or implied.
|
||||
As the programs were written for research purposes only, they have not
|
||||
been tested to the degree that would be advisable in any important
|
||||
application. All use of these programs is entirely at the user's own
|
||||
risk.
|
||||
|
||||
Some routines in the module rand.c are taken from the GNU C Library,
|
||||
and are copyrighted as described there and in the file LGPL.
|
||||
@@ -0,0 +1,419 @@
|
||||
#include "MessageClient.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <QUdpSocket>
|
||||
#include <QHostInfo>
|
||||
#include <QTimer>
|
||||
#include <QQueue>
|
||||
#include <QByteArray>
|
||||
#include <QHostAddress>
|
||||
|
||||
#include "NetworkMessage.hpp"
|
||||
|
||||
#include "pimpl_impl.hpp"
|
||||
|
||||
#include "moc_MessageClient.cpp"
|
||||
|
||||
class MessageClient::impl
|
||||
: public QUdpSocket
|
||||
{
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
impl (QString const& id, QString const& version, QString const& revision,
|
||||
port_type server_port, MessageClient * self)
|
||||
: self_ {self}
|
||||
, id_ {id}
|
||||
, version_ {version}
|
||||
, revision_ {revision}
|
||||
, server_port_ {server_port}
|
||||
, schema_ {2} // use 2 prior to negotiation not 1 which is broken
|
||||
, heartbeat_timer_ {new QTimer {this}}
|
||||
{
|
||||
connect (heartbeat_timer_, &QTimer::timeout, this, &impl::heartbeat);
|
||||
connect (this, &QIODevice::readyRead, this, &impl::pending_datagrams);
|
||||
|
||||
heartbeat_timer_->start (NetworkMessage::pulse * 1000);
|
||||
|
||||
// bind to an ephemeral port
|
||||
bind ();
|
||||
}
|
||||
|
||||
~impl ()
|
||||
{
|
||||
closedown ();
|
||||
}
|
||||
|
||||
enum StreamStatus {Fail, Short, OK};
|
||||
|
||||
void parse_message (QByteArray const& msg);
|
||||
void pending_datagrams ();
|
||||
void heartbeat ();
|
||||
void closedown ();
|
||||
StreamStatus check_status (QDataStream const&) const;
|
||||
void send_message (QByteArray const&);
|
||||
void send_message (QDataStream const& out, QByteArray const& message)
|
||||
{
|
||||
if (OK == check_status (out))
|
||||
{
|
||||
send_message (message);
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_EMIT self_->error ("Error creating UDP message");
|
||||
}
|
||||
}
|
||||
|
||||
Q_SLOT void host_info_results (QHostInfo);
|
||||
|
||||
MessageClient * self_;
|
||||
QString id_;
|
||||
QString version_;
|
||||
QString revision_;
|
||||
QString server_string_;
|
||||
port_type server_port_;
|
||||
QHostAddress server_;
|
||||
quint32 schema_;
|
||||
QTimer * heartbeat_timer_;
|
||||
|
||||
// hold messages sent before host lookup completes asynchronously
|
||||
QQueue<QByteArray> pending_messages_;
|
||||
QByteArray last_message_;
|
||||
};
|
||||
|
||||
#include "MessageClient.moc"
|
||||
|
||||
void MessageClient::impl::host_info_results (QHostInfo host_info)
|
||||
{
|
||||
if (QHostInfo::NoError != host_info.error ())
|
||||
{
|
||||
Q_EMIT self_->error ("UDP server lookup failed:\n" + host_info.errorString ());
|
||||
pending_messages_.clear (); // discard
|
||||
}
|
||||
else if (host_info.addresses ().size ())
|
||||
{
|
||||
server_ = host_info.addresses ()[0];
|
||||
|
||||
// send initial heartbeat which allows schema negotiation
|
||||
heartbeat ();
|
||||
|
||||
// clear any backlog
|
||||
while (pending_messages_.size ())
|
||||
{
|
||||
send_message (pending_messages_.dequeue ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MessageClient::impl::pending_datagrams ()
|
||||
{
|
||||
while (hasPendingDatagrams ())
|
||||
{
|
||||
QByteArray datagram;
|
||||
datagram.resize (pendingDatagramSize ());
|
||||
QHostAddress sender_address;
|
||||
port_type sender_port;
|
||||
if (0 <= readDatagram (datagram.data (), datagram.size (), &sender_address, &sender_port))
|
||||
{
|
||||
parse_message (datagram);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MessageClient::impl::parse_message (QByteArray const& msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
//
|
||||
// message format is described in NetworkMessage.hpp
|
||||
//
|
||||
NetworkMessage::Reader in {msg};
|
||||
if (OK == check_status (in) && id_ == in.id ()) // OK and for us
|
||||
{
|
||||
if (schema_ < in.schema ()) // one time record of server's
|
||||
// negotiated schema
|
||||
{
|
||||
schema_ = in.schema ();
|
||||
}
|
||||
|
||||
//
|
||||
// message format is described in NetworkMessage.hpp
|
||||
//
|
||||
switch (in.type ())
|
||||
{
|
||||
case NetworkMessage::Reply:
|
||||
{
|
||||
// unpack message
|
||||
QTime time;
|
||||
qint32 snr;
|
||||
float delta_time;
|
||||
quint32 delta_frequency;
|
||||
QByteArray mode;
|
||||
QByteArray message;
|
||||
bool low_confidence {false};
|
||||
in >> time >> snr >> delta_time >> delta_frequency >> mode >> message >> low_confidence;
|
||||
if (check_status (in) != Fail)
|
||||
{
|
||||
Q_EMIT self_->reply (time, snr, delta_time, delta_frequency
|
||||
, QString::fromUtf8 (mode), QString::fromUtf8 (message)
|
||||
, low_confidence);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NetworkMessage::Replay:
|
||||
if (check_status (in) != Fail)
|
||||
{
|
||||
last_message_.clear ();
|
||||
Q_EMIT self_->replay ();
|
||||
}
|
||||
break;
|
||||
|
||||
case NetworkMessage::HaltTx:
|
||||
{
|
||||
bool auto_only {false};
|
||||
in >> auto_only;
|
||||
if (check_status (in) != Fail)
|
||||
{
|
||||
Q_EMIT self_->halt_tx (auto_only);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NetworkMessage::FreeText:
|
||||
{
|
||||
QByteArray message;
|
||||
bool send {true};
|
||||
in >> message >> send;
|
||||
if (check_status (in) != Fail)
|
||||
{
|
||||
Q_EMIT self_->free_text (QString::fromUtf8 (message), send);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Ignore
|
||||
//
|
||||
// Note that although server heartbeat messages are not
|
||||
// parsed here they are still partially parsed in the
|
||||
// message reader class to negotiate the maximum schema
|
||||
// number being used on the network.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
Q_EMIT self_->error (QString {"MessageClient exception: %1"}.arg (e.what ()));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
Q_EMIT self_->error ("Unexpected exception in MessageClient");
|
||||
}
|
||||
}
|
||||
|
||||
void MessageClient::impl::heartbeat ()
|
||||
{
|
||||
if (server_port_ && !server_.isNull ())
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder hb {&message, NetworkMessage::Heartbeat, id_, schema_};
|
||||
hb << NetworkMessage::Builder::schema_number // maximum schema number accepted
|
||||
<< version_.toUtf8 () << revision_.toUtf8 ();
|
||||
if (OK == check_status (hb))
|
||||
{
|
||||
writeDatagram (message, server_, server_port_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MessageClient::impl::closedown ()
|
||||
{
|
||||
if (server_port_ && !server_.isNull ())
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::Close, id_, schema_};
|
||||
if (OK == check_status (out))
|
||||
{
|
||||
writeDatagram (message, server_, server_port_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MessageClient::impl::send_message (QByteArray const& message)
|
||||
{
|
||||
if (server_port_)
|
||||
{
|
||||
if (!server_.isNull ())
|
||||
{
|
||||
if (message != last_message_) // avoid duplicates
|
||||
{
|
||||
writeDatagram (message, server_, server_port_);
|
||||
last_message_ = message;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pending_messages_.enqueue (message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto MessageClient::impl::check_status (QDataStream const& stream) const -> StreamStatus
|
||||
{
|
||||
auto stat = stream.status ();
|
||||
StreamStatus result {Fail};
|
||||
switch (stat)
|
||||
{
|
||||
case QDataStream::ReadPastEnd:
|
||||
result = Short;
|
||||
break;
|
||||
|
||||
case QDataStream::ReadCorruptData:
|
||||
Q_EMIT self_->error ("Message serialization error: read corrupt data");
|
||||
break;
|
||||
|
||||
case QDataStream::WriteFailed:
|
||||
Q_EMIT self_->error ("Message serialization error: write error");
|
||||
break;
|
||||
|
||||
default:
|
||||
result = OK;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MessageClient::MessageClient (QString const& id, QString const& version, QString const& revision,
|
||||
QString const& server, port_type server_port, QObject * self)
|
||||
: QObject {self}
|
||||
, m_ {id, version, revision, server_port, this}
|
||||
{
|
||||
connect (&*m_, static_cast<void (impl::*) (impl::SocketError)> (&impl::error)
|
||||
, [this] (impl::SocketError e)
|
||||
{
|
||||
#if defined (Q_OS_WIN) && QT_VERSION >= 0x050500
|
||||
if (e != impl::NetworkError // take this out when Qt 5.5
|
||||
// stops doing this
|
||||
// spuriously
|
||||
&& e != impl::ConnectionRefusedError) // not
|
||||
// interested
|
||||
// in this with
|
||||
// UDP socket
|
||||
#else
|
||||
Q_UNUSED (e);
|
||||
#endif
|
||||
{
|
||||
Q_EMIT error (m_->errorString ());
|
||||
}
|
||||
});
|
||||
set_server (server);
|
||||
}
|
||||
|
||||
QHostAddress MessageClient::server_address () const
|
||||
{
|
||||
return m_->server_;
|
||||
}
|
||||
|
||||
auto MessageClient::server_port () const -> port_type
|
||||
{
|
||||
return m_->server_port_;
|
||||
}
|
||||
|
||||
void MessageClient::set_server (QString const& server)
|
||||
{
|
||||
m_->server_.clear ();
|
||||
m_->server_string_ = server;
|
||||
if (!server.isEmpty ())
|
||||
{
|
||||
// queue a host address lookup
|
||||
QHostInfo::lookupHost (server, &*m_, SLOT (host_info_results (QHostInfo)));
|
||||
}
|
||||
}
|
||||
|
||||
void MessageClient::set_server_port (port_type server_port)
|
||||
{
|
||||
m_->server_port_ = server_port;
|
||||
}
|
||||
|
||||
void MessageClient::send_raw_datagram (QByteArray const& message, QHostAddress const& dest_address
|
||||
, port_type dest_port)
|
||||
{
|
||||
if (dest_port && !dest_address.isNull ())
|
||||
{
|
||||
m_->writeDatagram (message, dest_address, dest_port);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageClient::status_update (Frequency f, QString const& mode, QString const& dx_call
|
||||
, QString const& report, QString const& tx_mode
|
||||
, bool tx_enabled, bool transmitting, bool decoding
|
||||
, qint32 rx_df, qint32 tx_df, QString const& de_call
|
||||
, QString const& de_grid, QString const& dx_grid
|
||||
, bool watchdog_timeout, QString const& sub_mode
|
||||
, bool fast_mode)
|
||||
{
|
||||
if (m_->server_port_ && !m_->server_string_.isEmpty ())
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::Status, m_->id_, m_->schema_};
|
||||
out << f << mode.toUtf8 () << dx_call.toUtf8 () << report.toUtf8 () << tx_mode.toUtf8 ()
|
||||
<< tx_enabled << transmitting << decoding << rx_df << tx_df << de_call.toUtf8 ()
|
||||
<< de_grid.toUtf8 () << dx_grid.toUtf8 () << watchdog_timeout << sub_mode.toUtf8 ()
|
||||
<< fast_mode;
|
||||
m_->send_message (out, message);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageClient::decode (bool is_new, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
||||
, QString const& mode, QString const& message_text, bool low_confidence)
|
||||
{
|
||||
if (m_->server_port_ && !m_->server_string_.isEmpty ())
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::Decode, m_->id_, m_->schema_};
|
||||
out << is_new << time << snr << delta_time << delta_frequency << mode.toUtf8 ()
|
||||
<< message_text.toUtf8 () << low_confidence;
|
||||
m_->send_message (out, message);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageClient::WSPR_decode (bool is_new, QTime time, qint32 snr, float delta_time, Frequency frequency
|
||||
, qint32 drift, QString const& callsign, QString const& grid, qint32 power)
|
||||
{
|
||||
if (m_->server_port_ && !m_->server_string_.isEmpty ())
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::WSPRDecode, m_->id_, m_->schema_};
|
||||
out << is_new << time << snr << delta_time << frequency << drift << callsign.toUtf8 ()
|
||||
<< grid.toUtf8 () << power;
|
||||
m_->send_message (out, message);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageClient::clear_decodes ()
|
||||
{
|
||||
if (m_->server_port_ && !m_->server_string_.isEmpty ())
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::Clear, m_->id_, m_->schema_};
|
||||
m_->send_message (out, message);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageClient::qso_logged (QDateTime timeOff, QString const& dx_call, QString const& dx_grid
|
||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||
, QString const& report_received, QString const& tx_power
|
||||
, QString const& comments, QString const& name, QDateTime timeOn)
|
||||
{
|
||||
if (m_->server_port_ && !m_->server_string_.isEmpty ())
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::QSOLogged, m_->id_, m_->schema_};
|
||||
out << timeOff << dx_call.toUtf8 () << dx_grid.toUtf8 () << dial_frequency << mode.toUtf8 ()
|
||||
<< report_sent.toUtf8 () << report_received.toUtf8 () << tx_power.toUtf8 () << comments.toUtf8 () << name.toUtf8 () << timeOn;
|
||||
m_->send_message (out, message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// (C) Copyright Gennadiy Rozental 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
//!@file
|
||||
//!@brief few helpers for working with variadic macros
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_PP_VARIADIC_HPP_021515GER
|
||||
#define BOOST_TEST_PP_VARIADIC_HPP_021515GER
|
||||
|
||||
// Boost
|
||||
#include <boost/preprocessor/control/iif.hpp>
|
||||
#include <boost/preprocessor/comparison/equal.hpp>
|
||||
#include <boost/preprocessor/variadic/size.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#if BOOST_PP_VARIADICS
|
||||
|
||||
#if BOOST_PP_VARIADICS_MSVC
|
||||
# define BOOST_TEST_INVOKE_VARIADIC( tool, ... ) BOOST_PP_CAT( tool (__VA_ARGS__), )
|
||||
#else
|
||||
# define BOOST_TEST_INVOKE_VARIADIC( tool, ... ) tool (__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
/// if sizeof(__VA_ARGS__) == N: F1(__VA_ARGS__)
|
||||
/// else: F2(__VA_ARGS__)
|
||||
#define BOOST_TEST_INVOKE_IF_N_ARGS( N, F1, F2, ... ) \
|
||||
BOOST_TEST_INVOKE_VARIADIC( \
|
||||
BOOST_PP_IIF( \
|
||||
BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), N), \
|
||||
F1, \
|
||||
F2), \
|
||||
__VA_ARGS__ ) \
|
||||
/**/
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#endif /* BOOST_PP_VARIADICS */
|
||||
|
||||
#endif // BOOST_TEST_PP_VARIADIC_HPP_021515GER
|
||||
|
||||
// EOF
|
||||
Reference in New Issue
Block a user