text:
/*
 *          Copyright Andrey Semashev 2007 - 2015.
 * Distributed under the Boost Software License, Version 1.0.
 *    (See accompanying file LICENSE_1_0.txt or copy at
 *          http://www.boost.org/LICENSE_1_0.txt)
 */
/*!
 * \file   formatting_ostream.hpp
 * \author Andrey Semashev
 * \date   11.07.2012
 *
 * The header contains implementation of a string stream used for log record formatting.
 */

#ifndef BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_
#define BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_

#include <ostream>
#include <string>
#include <memory>
#include <locale>
#include <boost/core/enable_if.hpp>
#include <boost/core/explicit_operator_bool.hpp>
#include <boost/utility/string_ref_fwd.hpp>
#include <boost/utility/string_view_fwd.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_scalar.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/log/detail/config.hpp>
#include <boost/log/detail/attachable_sstream_buf.hpp>
#include <boost/log/detail/code_conversion.hpp>
#include <boost/log/utility/string_literal_fwd.hpp>
#include <boost/log/utility/formatting_ostream_fwd.hpp>
#include <boost/log/detail/header.hpp>

#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif

namespace boost {

BOOST_LOG_OPEN_NAMESPACE

namespace aux {

template< typename T, typename R >
struct enable_if_streamable_char_type {};
template< typename R >
struct enable_if_streamable_char_type< char, R > { typedef R type; };
template< typename R >
struct enable_if_streamable_char_type< wchar_t, R > { typedef R type; };
#if !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
#if !defined(BOOST_NO_CXX11_CHAR16_T)
template< typename R >
struct enable_if_streamable_char_type< char16_t, R > { typedef R type; };
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
template< typename R >
struct enable_if_streamable_char_type< char32_t, R > { typedef R type; };
#endif
#endif

template< typename StreamT, typename T, bool ByValueV, typename R >
struct enable_formatting_ostream_generic_operator {};
template< typename CharT, typename TraitsT, typename AllocatorT, typename T, typename R >
struct enable_formatting_ostream_generic_operator< basic_formatting_ostream< CharT, TraitsT, AllocatorT >, T, false, R > :
    public boost::disable_if_c< boost::is_scalar< typename boost::remove_cv< T >::type >::value, R >
{
};
template< typename CharT, typename TraitsT, typename AllocatorT, typename T, typename R >
struct enable_formatting_ostream_generic_operator< basic_formatting_ostream< CharT, TraitsT, AllocatorT >, T, true, R > :
    public boost::enable_if_c< boost::is_enum< typename boost::remove_cv< T >::type >::value, R >
{
};

} // namespace aux

/*!
 * \brief Stream wrapper for log records formatting.
 *
 * This stream wrapper is used by the library for log record formatting. It implements the standard string stream interface
 * with a few differences:
 *
 * \li It does not derive from standard types <tt>std::basic_ostream</tt>, <tt>std::basic_ios</tt> and <tt>std::ios_base</tt>,
 *     although it tries to implement their interfaces closely. There are a few small differences, mostly regarding <tt>rdbuf</tt>
 *     and <tt>str</tt> signatures, as well as the supported insertion operator overloads. The actual wrapped stream can be accessed
 *     through the <tt>stream</tt> methods.
 * \li By default, \c bool values are formatted using alphabetical representation rather than numeric.
 * \li The stream supports writing strings of character types different from the stream character type. The stream will perform
 *     character code conversion as needed using the imbued locale.
 * \li The stream operates on an external string object rather than on the embedded one. The string can be attached or detached
 *     from the stream dynamically.
 *
 * Although <tt>basic_formatting_ostream</tt> does not derive from <tt>std::basic_ostream</tt>, users are not required to add
 * special overloads of \c operator<< for it since the stream will by default reuse the operators for <tt>std::basic_ostream</tt>.
 * However, one can define special overloads of \c operator<< for <tt>basic_formatting_ostream</tt> if a certain type needs
 * special formatting when output to log.
 */
template< typename CharT, typename TraitsT, typename AllocatorT >
class basic_formatting_ostream
{
public:
    //! Character type
    typedef CharT char_type;
    //! Character traits
    typedef TraitsT traits_type;
    //! Memory allocator
    typedef AllocatorT allocator_type;
    //! Stream buffer type
    typedef boost::log::aux::basic_ostringstreambuf< char_type, traits_type, allocator_type > streambuf_type;
    //! Target string type
    typedef typename streambuf_type::string_type string_type;

    //! Stream type
    typedef std::basic_ostream< char_type, traits_type > ostream_type;
    //! Stream position type
    typedef typename ostream_type::pos_type pos_type;
    //! Stream offset type
    typedef typename ostream_type::off_type off_type;
    //! Integer type for characters
    typedef typename ostream_type::int_type int_type;

    typedef typename ostream_type::failure failure;
    typedef typename ostream_type::fmtflags fmtflags;
    typedef typename ostream_type::iostate iostate;
    typedef typename ostream_type::openmode openmode;
    typedef typename ostream_type::seekdir seekdir;
    typedef typename ostream_type::Init Init;

    typedef typename ostream_type::event event;
    typedef typename ostream_type::event_callback event_callback;

    class sentry :
        public ostream_type::sentry
    {
        typedef typename ostream_type::sentry base_type;

    public:
        explicit sentry(basic_formatting_ostream& strm) : base_type(strm.stream())
        {
        }

        // A workaround for Solaris Studio 12.4 compiler, see: https://svn.boost.org/trac/boost/ticket/11545
        BOOST_EXPLICIT_OPERATOR_BOOL()
        bool operator! () const { return !static_cast< base_type const& >(*this); }

        BOOST_DELETED_FUNCTION(sentry(sentry const&))
        BOOST_DELETED_FUNCTION(sentry& operator= (sentry const&))
    };

protected:
    //  Function types
    typedef std::ios_base& (*ios_base_manip)(std::ios_base&);
    typedef std::basic_ios< char_type, traits_type >& (*basic_ios_manip)(std::basic_ios< char_type, traits_type >&);
    typedef ostream_type& (*stream_manip)(ostream_type&);

public:
    static BOOST_CONSTEXPR_OR_CONST fmtflags boolalpha = ostream_type::boolalpha;
    static BOOST_CONSTEXPR_OR_CONST fmtflags dec = ostream_type::dec;
    static BOOST_CONSTEXPR_OR_CONST fmtflags fixed = ostream_type::fixed;
    static BOOST_CONSTEXPR_OR_CONST fmtflags hex = ostream_type::hex;
    static BOOST_CONSTEXPR_OR_CONST fmtflags internal = ostream_type::internal;
    static BOOST_CONSTEXPR_OR_CONST fmtflags left = ostream_type::left;
    static BOOST_CONSTEXPR_OR_CONST fmtflags oct = ostream_type::oct;
    static BOOST_CONSTEXPR_OR_CONST fmtflags right = ostream_type::right;
    static BOOST_CONSTEXPR_OR_CONST fmtflags scientific = ostream_type::scientific;
    static BOOST_CONSTEXPR_OR_CONST fmtflags showbase = ostream_type::showbase;
    static BOOST_CONSTEXPR_OR_CONST fmtflags showpoint = ostream_type::showpoint;
    static BOOST_CONSTEXPR_OR_CONST fmtflags skipws = ostream_type::skipws;
    static BOOST_CONSTEXPR_OR_CONST fmtflags unitbuf = ostream_type::unitbuf;
    static BOOST_CONSTEXPR_OR_CONST fmtflags uppercase = ostream_type::uppercase;
    static BOOST_CONSTEXPR_OR_CONST fmtflags adjustfield = ostream_type::adjustfield;
    static BOOST_CONSTEXPR_OR_CONST fmtflags basefield = ostream_type::basefield;
    static BOOST_CONSTEXPR_OR_CONST fmtflags floatfield = ostream_type::floatfield;

    static BOOST_CONSTEXPR_OR_CONST iostate badbit = ostream_type::badbit;
    static BOOST_CONSTEXPR_OR_CONST iostate eofbit = ostream_type::eofbit;
    static BOOST_CONSTEXPR_OR_CONST iostate failbit = ostream_type::failbit;
    static BOOST_CONSTEXPR_OR_CONST iostate goodbit = ostream_type::goodbit;

    static BOOST_CONSTEXPR_OR_CONST openmode app = ostream_type::app;
    static BOOST_CONSTEXPR_OR_CONST openmode ate = ostream_type::ate;
    static BOOST_CONSTEXPR_OR_CONST openmode binary = ostream_type::binary;
    static BOOST_CONSTEXPR_OR_CONST openmode in = ostream_type::in;
    static BOOST_CONSTEXPR_OR_CONST openmode out = ostream_type::out;
    static BOOST_CONSTEXPR_OR_CONST openmode trunc = ostream_type::trunc;

    static BOOST_CONSTEXPR_OR_CONST seekdir beg = ostream_type::beg;
    static BOOST_CONSTEXPR_OR_CONST seekdir cur = ostream_type::cur;
    static BOOST_CONSTEXPR_OR_CONST seekdir end = ostream_type::end;

    static BOOST_CONSTEXPR_OR_CONST event erase_event = ostream_type::erase_event;
    static BOOST_CONSTEXPR_OR_CONST event imbue_event = ostream_type::imbue_event;
    static BOOST_CONSTEXPR_OR_CONST event copyfmt_event = ostream_type::copyfmt_event;

private:
    mutable streambuf_type m_streambuf;
    ostream_type m_stream;

public:
    /*!
     * Default constructor. Creates an empty record that is equivalent to the invalid record handle.
     * The stream capability is not available after construction.
     *
     * \post <tt>!*this == true</tt>
     */
    basic_formatting_ostream() : m_stream(&m_streambuf)
    {
        init_stream();
    }

    /*!
     * Initializing constructor. Attaches the string to the constructed stream.
     * The string will be used to store the formatted characters.
     *
     * \post <tt>!*this == false</tt>
     * \param str The string buffer to attach.
     */
    explicit basic_formatting_ostream(string_type& str) :
        m_streambuf(str),
        m_stream(&m_streambuf)
    {
        init_stream();
    }

    /*!
     * Destructor. Destroys the record, releases any sinks and attribute values that were involved in processing this record.
     */
    ~basic_formatting_ostream()
    {
        if (m_streambuf.storage())
            flush();
    }

    /*!
     * Attaches the stream to the string. The string will be used to store the formatted characters.
     *
     * \param str The string buffer to attach.
     */
    void attach(string_type& str)
    {
        m_streambuf.attach(str);
        m_stream.clear(ostream_type::goodbit);
    }
    /*!
     * Detaches the stream from the string. Any buffered data is flushed to the string.
     */
    void detach()
    {
        m_streambuf.detach();
        m_stream.clear(ostream_type::badbit);
    }

    /*!
     * \returns Reference to the attached string. The string must be attached before calling this method.
     */
    string_type const& str() const
    {
        string_type* const storage = m_streambuf.storage();
        BOOST_ASSERT(storage != NULL);

        m_streambuf.pubsync();

        return *storage;
    }

    /*!
     * \returns Reference to the wrapped stream
     */
    ostream_type& stream() { return m_stream; }

    /*!
     * \returns Reference to the wrapped stream
     */
    ostream_type const& stream() const { return m_stream; }

    // std::ios_base method forwarders
    fmtflags flags() const { return m_stream.flags(); }
    fmtflags flags(fmtflags f) { return m_stream.flags(f); }
    fmtflags setf(fmtflags f) { return m_stream.setf(f); }
    fmtflags setf(fmtflags f, fmtflags mask) { return m_stream.setf(f, mask); }
    void unsetf(fmtflags f) { m_stream.unsetf(f); }

    std::streamsize precision() const { return m_stream.precision(); }
    std::streamsize precision(std::streamsize p) { return m_stream.precision(p); }

    std::streamsize width() const { return m_stream.width(); }
    std::streamsize width(std::streamsize w) { return m_stream.width(w); }

    std::locale getloc() const { return m_stream.getloc(); }
    std::locale imbue(std::locale const& loc) { return m_stream.imbue(loc); }

    static int xalloc() { return ostream_type::xalloc(); }
    long& iword(int index) { return m_stream.iword(index); }
    void*& pword(int index) { return m_stream.pword(index); }

    void register_callback(event_callback fn, int index) { m_stream.register_callback(fn, index); }

    static bool sync_with_stdio(bool sync = true) { return ostream_type::sync_with_stdio(sync); }

    // std::basic_ios method forwarders
    BOOST_EXPLICIT_OPERATOR_BOOL()
    bool operator! () const { return !m_stream; }

    iostate rdstate() const { return m_stream.rdstate(); }
    void clear(iostate state = goodbit) { m_stream.clear(state); }
    void setstate(iostate state) { m_stream.setstate(state); }
    bool good() const { return m_stream.good(); }
    bool eof() const { return m_stream.eof(); }
    bool fail() const { return m_stream.fail(); }
    bool bad() const { return m_stream.bad(); }

    iostate exceptions() const { return m_stream.exceptions(); }
    void exceptions(iostate s) { m_stream.exceptions(s); }

    ostream_type* tie() const { return m_stream.tie(); }
    ostream_type* tie(ostream_type* strm) { return m_stream.tie(strm); }

    streambuf_type* rdbuf() const { return &m_streambuf; }

    basic_formatting_ostream& copyfmt(std::basic_ios< char_type, traits_type >& rhs)
    {
        m_stream.copyfmt(rhs);
        return *this;
    }
    basic_formatting_ostream& copyfmt(basic_formatting_ostream& rhs)
    {
        m_stream.copyfmt(rhs.stream());
        return *this;
    }

    char_type fill() const { return m_stream.fill(); }
    char_type fill(char_type ch) { return m_stream.fill(ch); }

    char narrow(char_type ch, char def) const { return m_stream.narrow(ch, def); }
    char_type widen(char ch) const { return m_stream.widen(ch); }

    // std::basic_ostream method forwarders
    basic_formatting_ostream& flush()
    {
        m_stream.flush();
        return *this;
    }

    pos_type tellp() { return m_stream.tellp(); }
    basic_formatting_ostream& seekp(pos_type pos)
    {
        m_stream.seekp(pos);
        return *this;
    }
    basic_formatting_ostream& seekp(off_type off, std::ios_base::seekdir dir)
    {
        m_stream.seekp(off, dir);
        return *this;
    }

    basic_formatting_ostream& put(char_type c)
    {
        m_stream.put(c);
        return *this;
    }

    template< typename OtherCharT >
    typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    put(OtherCharT c)
    {
        write(&c, 1);
        return *this;
    }

    basic_formatting_ostream& write(const char_type* p, std::streamsize size)
    {
        m_stream.write(p, size);
        return *this;
    }

    template< typename OtherCharT >
    typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    write(const OtherCharT* p, std::streamsize size)
    {
        sentry guard(*this);
        if (!!guard)
        {
            m_stream.flush();

            if (!m_streambuf.storage_overflow())
            {
                string_type* storage = m_streambuf.storage();
                if (!aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_streambuf.max_size(), m_stream.getloc()))
                    m_streambuf.storage_overflow(true);
            }
        }

        return *this;
    }

    basic_formatting_ostream& operator<< (ios_base_manip manip)
    {
        m_stream << manip;
        return *this;
    }
    basic_formatting_ostream& operator<< (basic_ios_manip manip)
    {
        m_stream << manip;
        return *this;
    }
    basic_formatting_ostream& operator<< (stream_manip manip)
    {
        m_stream << manip;
        return *this;
    }

    basic_formatting_ostream& operator<< (char c)
    {
        return this->formatted_write(&c, 1);
    }
    basic_formatting_ostream& operator<< (const char* p)
    {
        return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char >::length(p)));
    }

    // When no native character type is supported, the following overloads are disabled as they have ambiguous meaning.
    // Use basic_string_view or basic_string to explicitly indicate that the data is a string.
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
    basic_formatting_ostream& operator<< (wchar_t c)
    {
        return this->formatted_write(&c, 1);
    }
    basic_formatting_ostream& operator<< (const wchar_t* p)
    {
        return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< wchar_t >::length(p)));
    }
#endif
#if !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
#if !defined(BOOST_NO_CXX11_CHAR16_T)
    basic_formatting_ostream& operator<< (char16_t c)
    {
        return this->formatted_write(&c, 1);
    }
    basic_formatting_ostream& operator<< (const char16_t* p)
    {
        return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char16_t >::length(p)));
    }
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
    basic_formatting_ostream& operator<< (char32_t c)
    {
        return this->formatted_write(&c, 1);
    }
    basic_formatting_ostream& operator<< (const char32_t* p)
    {
        return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char32_t >::length(p)));
    }
#endif
#endif

    basic_formatting_ostream& operator<< (bool value)
    {
        m_stream << value;
        return *this;
    }
    basic_formatting_ostream& operator<< (signed char value)
    {
        m_stream << value;
        return *this;
    }
    basic_formatting_ostream& operator<< (unsigned char value)
    {
        m_stream << value;
        return *this;
    }
    basic_formatting_ostream& operator<< (short value)
    {
        m_stream << value;
        return *this;
    }
    basic_formatting_ostream& operator<< (unsigned short value)
    {
        m_stream << value;
        return *this;
    }
    basic_formatting_ostream& operator<< (int value)
    {
        m_stream << value;
        return *this;
    }
    basic_formatting_ostream& operator<< (unsigned int value)
    {
        m_stream << value;
        return *this;
    }
    basic_formatting_ostream& operator<< (long value)
    {
        m_stream << value;
        return *this;
    }
    basic_formatting_ostream& operator<< (unsigned long value)
    {
        m_stream << value;
        return *this;
    }
#if !defined(BOOST_NO_LONG_LONG)
    basic_formatting_ostream& operator<< (long long value)
    {
        m_stream << value;
        return *this;
    }
    basic_formatting_ostream& operator<< (unsigned long long value)
    {
        m_stream << value;
        return *this;
    }
#endif

    basic_formatting_ostream& operator<< (float value)
    {
        m_stream << value;
        return *this;
    }
    basic_formatting_ostream& operator<< (double value)
    {
        m_stream << value;
        return *this;
    }
    basic_formatting_ostream& operator<< (long double value)
    {
        m_stream << value;
        return *this;
    }

    basic_formatting_ostream& operator<< (const void* value)
    {
        m_stream << value;
        return *this;
    }

    basic_formatting_ostream& operator<< (std::basic_streambuf< char_type, traits_type >* buf)
    {
        m_stream << buf;
        return *this;
    }

    template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
    friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    operator<< (basic_formatting_ostream& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT > const& str)
    {
        return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
    }

    template< typename OtherCharT, typename OtherTraitsT >
    friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    operator<< (basic_formatting_ostream& strm, basic_string_literal< OtherCharT, OtherTraitsT > const& str)
    {
        return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
    }

    template< typename OtherCharT, typename OtherTraitsT >
    friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    operator<< (basic_formatting_ostream& strm, basic_string_view< OtherCharT, OtherTraitsT > const& str)
    {
        return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
    }

    // Deprecated overload
    template< typename OtherCharT, typename OtherTraitsT >
    friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    operator<< (basic_formatting_ostream& strm, basic_string_ref< OtherCharT, OtherTraitsT > const& str)
    {
        return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
    }

    template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
    friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    operator<< (basic_formatting_ostream& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT >& str)
    {
        return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
    }

    template< typename OtherCharT, typename OtherTraitsT >
    friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    operator<< (basic_formatting_ostream& strm, basic_string_literal< OtherCharT, OtherTraitsT >& str)
    {
        return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
    }

    template< typename OtherCharT, typename OtherTraitsT >
    friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    operator<< (basic_formatting_ostream& strm, basic_string_view< OtherCharT, OtherTraitsT >& str)
    {
        return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
    }

    // Deprecated overload
    template< typename OtherCharT, typename OtherTraitsT >
    friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    operator<< (basic_formatting_ostream& strm, basic_string_ref< OtherCharT, OtherTraitsT >& str)
    {
        return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
    }

#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
    template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
    friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    operator<< (basic_formatting_ostream&& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT > const& str)
    {
        return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
    }

    template< typename OtherCharT, typename OtherTraitsT >
    friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    operator<< (basic_formatting_ostream&& strm, basic_string_literal< OtherCharT, OtherTraitsT > const& str)
    {
        return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
    }

    template< typename OtherCharT, typename OtherTraitsT >
    friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    operator<< (basic_formatting_ostream&& strm, basic_string_view< OtherCharT, OtherTraitsT > const& str)
    {
        return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
    }

    // Deprecated overload
    template< typename OtherCharT, typename OtherTraitsT >
    friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    operator<< (basic_formatting_ostream&& strm, basic_string_ref< OtherCharT, OtherTraitsT > const& str)
    {
        return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
    }

    template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
    friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    operator<< (basic_formatting_ostream&& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT >& str)
    {
        return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
    }

    template< typename OtherCharT, typename OtherTraitsT >
    friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    operator<< (basic_formatting_ostream&& strm, basic_string_literal< OtherCharT, OtherTraitsT >& str)
    {
        return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
    }

    template< typename OtherCharT, typename OtherTraitsT >
    friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    operator<< (basic_formatting_ostream&& strm, basic_string_view< OtherCharT, OtherTraitsT >& str)
    {
        return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
    }

    // Deprecated overload
    template< typename OtherCharT, typename OtherTraitsT >
    friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
    operator<< (basic_formatting_ostream&& strm, basic_string_ref< OtherCharT, OtherTraitsT >& str)
    {
        return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
    }
#endif

protected:
    void init_stream()
    {
        m_stream.exceptions(ostream_type::goodbit);
        m_stream.clear(m_streambuf.storage() ? ostream_type::goodbit : ostream_type::badbit);
        m_stream.flags
        (
            ostream_type::dec |
            ostream_type::skipws |
            ostream_type::boolalpha // this differs from the default stream flags but makes logs look better
        );
        m_stream.width(0);
        m_stream.precision(6);
        m_stream.fill(static_cast< char_type >(' '));
    }

private:
    basic_formatting_ostream& formatted_write(const char_type* p, std::streamsize size)
    {
        sentry guard(*this);
        if (!!guard)
        {
            m_stream.flush();

            if (m_stream.width() <= size)
                m_streambuf.append(p, static_cast< std::size_t >(size));
            else
                this->aligned_write(p, size);

            m_stream.width(0);
        }

        return *this;
    }

    template< typename OtherCharT >
    basic_formatting_ostream& formatted_write(const OtherCharT* p, std::streamsize size)
    {
        sentry guard(*this);
        if (!!guard)
        {
            m_stream.flush();

            if (m_stream.width() <= size)
            {
                if (!m_streambuf.storage_overflow())
                {
                    if (!aux::code_convert(p, static_cast< std::size_t >(size), *m_streambuf.storage(), m_streambuf.max_size(), m_stream.getloc()))
                        m_streambuf.storage_overflow(true);
                }
            }
            else
                this->aligned_write(p, size);

            m_stream.width(0);
        }

        return *this;
    }

    void aligned_write(const char_type* p, std::streamsize size);

    template< typename OtherCharT >
    void aligned_write(const OtherCharT* p, std::streamsize size);

    //! Copy constructor (closed)
    BOOST_DELETED_FUNCTION(basic_formatting_ostream(basic_formatting_ostream const& that))
    //! Assignment (closed)
    BOOST_DELETED_FUNCTION(basic_formatting_ostream& operator= (basic_formatting_ostream const& that))
};

template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::boolalpha;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::dec;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fixed;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::hex;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::internal;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::left;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::oct;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::right;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::scientific;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::showbase;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::showpoint;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::skipws;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::unitbuf;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::uppercase;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::adjustfield;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::basefield;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::floatfield;

template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::badbit;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::eofbit;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::failbit;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::goodbit;

template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::app;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::ate;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::binary;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::in;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::out;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::trunc;

template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::beg;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::cur;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::end;

template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::erase_event;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::imbue_event;
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::copyfmt_event;

template< typename CharT, typename TraitsT, typename AllocatorT >
void basic_formatting_ostream< CharT, TraitsT, AllocatorT >::aligned_write(const char_type* p, std::streamsize size)
{
    typename string_type::size_type const alignment_size =
        static_cast< typename string_type::size_type >(m_stream.width() - size);
    const bool align_left = (m_stream.flags() & ostream_type::adjustfield) == ostream_type::left;
    if (align_left)
    {
        m_streambuf.append(p, static_cast< std::size_t >(size));
        m_streambuf.append(alignment_size, m_stream.fill());
    }
    else
    {
        m_streambuf.append(alignment_size, m_stream.fill());
        m_streambuf.append(p, static_cast< std::size_t >(size));
    }
}

template< typename CharT, typename TraitsT, typename AllocatorT >
template< typename OtherCharT >
void basic_formatting_ostream< CharT, TraitsT, AllocatorT >::aligned_write(const OtherCharT* p, std::streamsize size)
{
    string_type* const storage = m_streambuf.storage();
    typename string_type::size_type const alignment_size =
        static_cast< typename string_type::size_type >(m_stream.width() - size);
    const bool align_left = (m_stream.flags() & ostream_type::adjustfield) == ostream_type::left;
    if (align_left)
    {
        if (!m_streambuf.storage_overflow())
        {
            if (!aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_streambuf.max_size(), m_stream.getloc()))
                m_streambuf.storage_overflow(true);
        }
        m_streambuf.append(alignment_size, m_stream.fill());
    }
    else
    {
        m_streambuf.append(alignment_size, m_stream.fill());
        if (!m_streambuf.storage_overflow())
        {
            if (!aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_streambuf.max_size(), m_stream.getloc()))
                m_streambuf.storage_overflow(true);
        }
    }
}

// Implementation note: these operators below should be the least attractive for the compiler
// so that user's overloads are chosen, when present. We use function template partial ordering for this purpose.
// We also don't use perfect forwarding for the right hand argument because in this case the generic overload
// would be more preferred than the typical one written by users:
//
// formatting_ostream& operator<< (formatting_ostream& strm, my_type const& arg);
//
// This is because my_type rvalues require adding const to the type, which counts as a conversion that is not required
// if there is a perfect forwarding overload.
template< typename StreamT, typename T >
inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, true, StreamT& >::type
operator<< (StreamT& strm, T value)
{
    strm.stream() << value;
    return strm;
}

template< typename StreamT, typename T >
inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, false, StreamT& >::type
operator<< (StreamT& strm, T const& value)
{
    strm.stream() << value;
    return strm;
}

template< typename StreamT, typename T >
inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, false, StreamT& >::type
operator<< (StreamT& strm, T& value)
{
    strm.stream() << value;
    return strm;
}

#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)

template< typename StreamT, typename T >
inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, true, StreamT& >::type
operator<< (StreamT&& strm, T value)
{
    strm.stream() << value;
    return strm;
}

template< typename StreamT, typename T >
inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, false, StreamT& >::type
operator<< (StreamT&& strm, T const& value)
{
    strm.stream() << value;
    return strm;
}

template< typename StreamT, typename T >
inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, false, StreamT& >::type
operator<< (StreamT&& strm, T& value)
{
    strm.stream() << value;
    return strm;
}

#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)

BOOST_LOG_CLOSE_NAMESPACE // namespace log

} // namespace boost

#include <boost/log/detail/footer.hpp>

#endif // BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_

max_stars_repo_name: ZCube/boost-cmake


text:
//  Copyright 2015 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/mp11/tuple.hpp>
#include <boost/config.hpp>

// Technically std::tuple isn't constexpr enabled in C++11, but it works with libstdc++

#if defined( BOOST_NO_CXX11_CONSTEXPR ) || ( defined( _LIBCPP_VERSION ) && __cplusplus < 201400L )

int main() {}

#else

#include <tuple>
#include <array>
#include <utility>

struct T1
{
    int x, y, z;

    constexpr T1( int x = 0, int y = 0, int z = 0 ): x(x), y(y), z(z) {}
};

int main()
{
    using boost::mp11::construct_from_tuple;

    {
        constexpr std::tuple<int, short, char> tp{ 1, 2, 3 };

        constexpr auto r = construct_from_tuple<T1>( tp );

        static_assert( r.x == 1, "r.x == 1" );
        static_assert( r.y == 2, "r.y == 2" );
        static_assert( r.z == 3, "r.z == 3" );
    }

    {
        constexpr std::pair<short, char> tp{ 1, 2 };

        constexpr auto r = construct_from_tuple<T1>( tp );

        static_assert( r.x == 1, "r.x == 1" );
        static_assert( r.y == 2, "r.y == 2" );
        static_assert( r.z == 0, "r.z == 0" );
    }

    {
        constexpr std::array<short, 3> tp{{ 1, 2, 3 }};

        constexpr auto r = construct_from_tuple<T1>( tp );

        static_assert( r.x == 1, "r.x == 1" );
        static_assert( r.y == 2, "r.y == 2" );
        static_assert( r.z == 3, "r.z == 3" );
    }

#if defined( __clang_major__ ) && __clang_major__ == 3 && __clang_minor__ < 9
// "error: default initialization of an object of const type 'const std::tuple<>' without a user-provided default constructor"
#else

    {
        constexpr std::tuple<> tp;

        constexpr auto r = construct_from_tuple<T1>( tp );

        static_assert( r.x == 0, "r.x == 0" );
        static_assert( r.y == 0, "r.y == 0" );
        static_assert( r.z == 0, "r.z == 0" );
    }

#endif
}

#endif

ext: cpp

max_stars_repo_name: yinhangfeng/react-native

max_issues_repo_name: yinhangfeng/react-native

max_forks_repo_name: yinhangfeng/react-native


text:
#include <boost/asio.hpp>
#include <iostream>

void print(const boost::system::error_code& /*e*/)
{
  std::cout << "Hello, async callback world!\n";
}

int main()
{
	boost::asio::io_context io;

	std::cout << "start\n";
	boost::asio::steady_timer t(io, boost::asio::chrono::seconds(2));
	t.async_wait(&print);

	std::cout << "start run()\n";
	io.run();

	std::cout << "End\n";
}

max_stars_repo_name: deodates-dev/FSM-CPP-spaghetti

max_issues_repo_name: deodates-dev/FSM-CPP-spaghetti

max_forks_repo_name: deodates-dev/FSM-CPP-spaghetti


text: #include <boost/range/const_reverse_iterator.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
///////////////////////////////////////////////////////////////
//  Copyright Christopher Kormanyos 2002 - 2011.
//  Copyright 2011 John Maddock. Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
//
// This work is based on an earlier work:
// "Algorithm 910: A Portable C++ Multiple-Precision System for Special-Function Calculations",
// in ACM TOMS, {VOL 37, ISSUE 4, (February 2011)} (C) ACM, 2011. http://doi.acm.org/10.1145/1916461.1916469

#ifdef _MSC_VER
#  define _SCL_SECURE_NO_WARNINGS
#endif

#include <boost/detail/lightweight_test.hpp>
#include "test.hpp"

#include <boost/multiprecision/mpfi.hpp>

template <class T>
T make_rvalue_copy(const T a)
{
   return a;
}

int main()
{
   using namespace boost::multiprecision;
   //
   // Test change of default precision:
   //
   mpfi_float::default_precision(100);
   mpfi_float a("0.1");
   BOOST_CHECK_EQUAL(a.precision(), 100);
   mpfi_float::default_precision(20);
   {
      // test assignment from lvalue:
      mpfi_float b(2);
      BOOST_CHECK_EQUAL(b.precision(), 20);
      b = a;
      BOOST_CHECK_EQUAL(b.precision(), a.precision());
   }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
   {
      // test assignment from rvalue:
      mpfi_float b(2);
      BOOST_CHECK_EQUAL(b.precision(), 20);
      b = make_rvalue_copy(a);
      BOOST_CHECK_EQUAL(b.precision(), a.precision());
   }
#endif
   mpfi_float::default_precision(20);
   {
      // test construct from lvalue:
      mpfi_float b(a);
      BOOST_CHECK_EQUAL(b.precision(), 100);
   }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
   {
      // test construct from rvalue:
      mpfi_float b(make_rvalue_copy(a));
      BOOST_CHECK_EQUAL(b.precision(), 100);
   }
#endif
   {
      mpfi_float f150(2, 2, 150);
      BOOST_CHECK_EQUAL(f150.precision(), 150);
   }
   {
      mpfi_float f150("1.2", "1.2", 150);
      BOOST_CHECK_EQUAL(f150.precision(), 150);
   }
   //
   // From https://github.com/boostorg/multiprecision/issues/65
   //
   {
      mpfi_float a(2);
      a.precision(100);
      BOOST_CHECK_EQUAL(a, 2);
      BOOST_CHECK_EQUAL(a.precision(), 100);
   }

   //
   // string_view with explicit precision:
   //
#ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
   {
      std::string s("222");
      std::string_view v(s.c_str(), 1);
      mpfi_float f(v, v, 100);
      BOOST_CHECK_EQUAL(f, 2);
      BOOST_CHECK_EQUAL(f.precision(), 100);
   }
#endif
   // Swap:
   {
      mpfi_float x(2, 2, 100);  // 100 digits precision.
      mpfi_float y(3, 3, 50);   // 50 digits precision.
      swap(x, y);
      BOOST_CHECK_EQUAL(x, 3);
      BOOST_CHECK_EQUAL(y, 2);
      BOOST_CHECK_EQUAL(x.precision(), 50);
      BOOST_CHECK_EQUAL(y.precision(), 100);
      x.swap(y);
      BOOST_CHECK_EQUAL(x, 2);
      BOOST_CHECK_EQUAL(y, 3);
      BOOST_CHECK_EQUAL(x.precision(), 100);
      BOOST_CHECK_EQUAL(y.precision(), 50);
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
      x = std::move(mpfi_float(y));
      BOOST_CHECK_EQUAL(x, y);
      BOOST_CHECK_EQUAL(x.precision(), y.precision());
#endif
   }
   {
      mpfi_float c(4), d(8), e(9), f;
      f = (c + d) * d / e;
      mpfi_float g((c + d) * d / e);
   }
   {
      mpfi_float::default_precision(100);
      mpfi_float f1;
      f1 = 3;
      BOOST_CHECK_EQUAL(f1.precision(), 100);
      f1 = 3.5;
      BOOST_CHECK_EQUAL(f1.precision(), 100);
      mpfi_float f2(3.5);
      BOOST_CHECK_EQUAL(f2.precision(), 100);
      mpfi_float f3("5.1");
      BOOST_CHECK_EQUAL(f3.precision(), 100);

      mpfi_float::default_precision(50);
      mpfi_float f4(f3, 50);
      BOOST_CHECK_EQUAL(f4.precision(), 50);
      f4.assign(f1, f4.precision());
      BOOST_CHECK_EQUAL(f4.precision(), 50);
   }
   {
      //
      // Check additional non-member functions,
      // see https://github.com/boostorg/multiprecision/issues/91
      //
      mpfi_float::default_precision(100);
      mpfi_float f1;
      f1 = 3;
      BOOST_CHECK_EQUAL(f1.precision(), 100);
      mpfi_float::default_precision(20);
      BOOST_CHECK_EQUAL(lower(f1).precision(), 100);
      BOOST_CHECK_EQUAL(upper(f1).precision(), 100);
      BOOST_CHECK_EQUAL(median(f1).precision(), 100);
      BOOST_CHECK_EQUAL(width(f1).precision(), 100);
      BOOST_CHECK_EQUAL(intersect(f1, f1).precision(), 100);
      BOOST_CHECK_EQUAL(hull(f1, f1).precision(), 100);

      BOOST_CHECK_EQUAL(asinh(f1).precision(), 100);
      BOOST_CHECK_EQUAL(acosh(f1).precision(), 100);
      BOOST_CHECK_EQUAL(atanh(f1).precision(), 100);
      BOOST_CHECK_EQUAL(log1p(f1).precision(), 100);
      BOOST_CHECK_EQUAL(expm1(f1).precision(), 100);
      BOOST_CHECK_EQUAL(cbrt(f1).precision(), 100);
   }

   return boost::report_errors();
}


text:
//==================================================================================================
/*!

  Copyright 2016 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#include <boost/simd/function/simd/aligned_load.hpp>
#include <boost/simd/pack.hpp>
#include <boost/align/aligned_alloc.hpp>
#include <simd_test.hpp>

namespace ba = boost::alignment;
namespace bs = boost::simd;

template <typename T, std::size_t N, typename Env>
void test_periodic(Env& runtime)
{
  using p_t = bs::pack<T,N>;

  T* data = static_cast<T*>(ba::aligned_alloc(p_t::alignment, (sizeof(T)) * N * 3));
  std::array<T,N> ref0, refN, refmN;

  for(std::size_t i = 0;i < 3*N        ; ++i) data[i] = T(i+1);
  for(std::size_t i = 0;i < ref0.size() ; ++i)
  {
    ref0[i]  = data[N+i];
    refN[i]  = data[2*N+i];
    refmN[i] = data[i];
  }

  static const std::ptrdiff_t O = N;

  p_t p0  = bs::aligned_load<bs::pack<T,N>, 0>(&data[N]  );
  p_t pN  = bs::aligned_load<bs::pack<T,N>, O>(&data[N]+O);
  p_t pmN = bs::aligned_load<bs::pack<T,N>,-O>(&data[N]-O);

  STF_ALL_EQUAL( p0 , ref0  );
  STF_ALL_EQUAL( pN , refN  );
  STF_ALL_EQUAL( pmN, refmN );
}

STF_CASE_TPL( "Check aligned_load behavior with periodic misalignment", STF_NUMERIC_TYPES )
{
  static const std::size_t N = bs::pack<T>::static_size;

  test_periodic<T, N>(runtime);
  test_periodic<T, N/2>(runtime);
  test_periodic<T, N*2>(runtime);
}

template <typename T, std::size_t N, typename Env>
void test_aperiodic(Env& runtime)
{
  using p_t = bs::pack<T,N>;

  T* data = static_cast<T*>(ba::aligned_alloc(p_t::alignment, (sizeof(T)) * N * 3));
  std::array<T,N> ref1, refm2, ref3;

  for(std::size_t i = 0;i < 3*N         ; ++i) data[i] = T(i+1);
  for(std::size_t i = 0;i < ref1.size() ; ++i)
  {
    ref1[i]  = data[N+i+1];
    refm2[i]  = data[N+i-2];
    ref3[i] = data[N+i+3];
  }

  p_t p1  = bs::aligned_load<bs::pack<T,N>,+1>(&data[N]+1);
  p_t pm2 = bs::aligned_load<bs::pack<T,N>,-2>(&data[N]-2);
  p_t p3  = bs::aligned_load<bs::pack<T,N>,+3>(&data[N]+3);

  STF_ALL_EQUAL( p1 , ref1  );
  STF_ALL_EQUAL( pm2, refm2 );
  STF_ALL_EQUAL( p3 , ref3  );
}

STF_CASE_TPL( "Check aligned_load behavior with aperiodic misalignment", STF_NUMERIC_TYPES )
{
  static const std::size_t N = bs::pack<T>::static_size;

  test_aperiodic<T, N>(runtime);
  test_aperiodic<T, N/2>(runtime);
  test_aperiodic<T, N*2>(runtime);
}


text:
#include <boost/hana.hpp>
#include <string>
#include <utility>
#include <iostream>

struct person {
    std::string name;
    int age;

    void serialize(std::ostream &os) const
    {
        os << name << '\n' << age << '\n';
    }
};

auto has_serialize = boost::hana::is_valid([](auto &&obj) -> decltype(obj.serialize(std::declval<std::ostream&>())) {});

template <class T>
void serialize(const T &t)
{
    if constexpr (has_serialize(t))
        t.serialize(std::cout);
    else
        std::cout << t << '\n';
}

int main()
{
    person tom{ "Tom", 35 };
    serialize(tom);

    std::string s{"String"};
    serialize(s);

    int i{1};
    serialize(i);
}

max_stars_repo_name: BorisSchaeling/boost-meta-programming

max_issues_repo_name: BorisSchaeling/boost-meta-programming

max_forks_repo_name: BorisSchaeling/boost-meta-programming


text:
//---------------------------------------------------------------------------//
//!
//! \file   Utility_InterpolationPolicy_def.hpp
//! \author Alex Robinson
//! \brief  Intrepolation policy struct definitions
//!
//---------------------------------------------------------------------------//

#ifndef UTILITY_INTERPOLATION_POLICY_DEF_HPP
#define UTILITY_INTERPOLATION_POLICY_DEF_HPP

// Std Lib Includes
#include <cmath>

// Boost Includes
#include <boost/mpl/or.hpp>

// Trilinos Includes
#include <Teuchos_ScalarTraits.hpp>

// FRENSIE Includes
#include "Utility_ContractException.hpp"

namespace Utility{

// Interpolate between two points
template<typename IndepType, typename DepType>
inline DepType LogLog::interpolate( const IndepType indep_var_0,
				    const IndepType indep_var_1,
				    const IndepType indep_var,
				    const DepType dep_var_0,
				    const DepType dep_var_1 )
{
  // The IndepType must be a floating point type
  testStaticPrecondition( (QuantityTraits<IndepType>::is_floating_point::value) );
  testStaticPrecondition( (QuantityTraits<DepType>::is_floating_point::value) );
  // Make sure the independent variables are valid
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var_0 ) );
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var_1 ) );
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var ) );
  testPrecondition( LogLog::isIndepVarInValidRange( indep_var_0 ) );
  testPrecondition( LogLog::isIndepVarInValidRange( indep_var_1 ) );
  testPrecondition( LogLog::isIndepVarInValidRange( indep_var ) );
  testPrecondition( indep_var_0 < indep_var_1 );
  testPrecondition( indep_var >= indep_var_0 );
  testPrecondition( indep_var <= indep_var_1 );
  // Make sure the dependent variables are valid
  testPrecondition( !QuantityTraits<DepType>::isnaninf( dep_var_0 ) );
  testPrecondition( !QuantityTraits<DepType>::isnaninf( dep_var_1 ) );
  testPrecondition( LogLog::isDepVarInValidRange( dep_var_0 ) );
  testPrecondition( LogLog::isDepVarInValidRange( dep_var_1 ) );

  return dep_var_0*
    pow((dep_var_1/dep_var_0),
	log(indep_var/indep_var_0)/log(indep_var_1/indep_var_0));
}

// Interpolate between two processed point
template<typename T>
inline T LogLog::interpolate( const T processed_indep_var_0,
			      const T processed_indep_var,
			      const T processed_dep_var_0,
			      const T processed_slope )
{
  // T must be a floating point type
  testStaticPrecondition( (boost::is_floating_point<T>::value) );
  // Make sure the processed independent variables are valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						     processed_indep_var_0 ) );
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						       processed_indep_var ) );
  testPrecondition( processed_indep_var_0 <= processed_indep_var );
  // Make sure the processed dependent variable is valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						       processed_dep_var_0 ) );
  // Make sure that the slope is valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf( processed_slope ) );

  return exp( processed_dep_var_0 +
	      processed_slope*(processed_indep_var - processed_indep_var_0) );
}

// Interpolate between two points and return the processed value
template<typename IndepType, typename DepType>
inline typename QuantityTraits<DepType>::RawType
LogLog::interpolateAndProcess( const IndepType indep_var_0,
			       const IndepType indep_var_1,
			       const IndepType indep_var,
			       const DepType dep_var_0,
			       const DepType dep_var_1 )
{
  // T must be a floating point type
  testStaticPrecondition( (QuantityTraits<IndepType>::is_floating_point::value) );
  testStaticPrecondition( (QuantityTraits<DepType>::is_floating_point::value) );
  // Make sure the independent variables are valid
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var_0 ) );
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var_1 ) );
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var ) );
  testPrecondition( LogLog::isIndepVarInValidRange( indep_var_0 ) );
  testPrecondition( LogLog::isIndepVarInValidRange( indep_var_1 ) );
  testPrecondition( LogLog::isIndepVarInValidRange( indep_var ) );
  testPrecondition( indep_var_0 < indep_var_1 );
  testPrecondition( indep_var >= indep_var_0 );
  testPrecondition( indep_var <= indep_var_1 );
  // Make sure the dependent variables are valid
  testPrecondition( !QuantityTraits<DepType>::isnaninf( dep_var_0 ) );
  testPrecondition( !QuantityTraits<DepType>::isnaninf( dep_var_1 ) );
  testPrecondition( LogLog::isDepVarInValidRange( dep_var_0 ) );
  testPrecondition( LogLog::isDepVarInValidRange( dep_var_1 ) );

  return log( getRawQuantity(dep_var_0) ) + log ( dep_var_1/dep_var_0 )*
    log( indep_var/indep_var_0 )/log( indep_var_1/indep_var_0 );
}

// Interpolate between two processed points and return the processed value
template<typename T>
inline T LogLog::interpolateAndProcess( const T processed_indep_var_0,
					const T processed_indep_var,
					const T processed_dep_var_0,
					const T processed_slope )
{
  // T must be a floating point type
  testStaticPrecondition( (boost::is_floating_point<T>::value) );
  // Make sure the processed independent variables are valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						     processed_indep_var_0 ) );
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						       processed_indep_var ) );
  testPrecondition( processed_indep_var_0 <= processed_indep_var );
  // Make sure the processed dependent variable is valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						       processed_dep_var_0 ) );
  // Make sure that the slope is valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf( processed_slope ) );

  return processed_dep_var_0 +
    processed_slope*(processed_indep_var - processed_indep_var_0);
}

// Process the independent value
template<typename T>
inline typename QuantityTraits<T>::RawType
LogLog::processIndepVar( const T indep_var )
{
  // Make sure the indep var value is valid
  testPrecondition( LogLog::isIndepVarInValidRange( indep_var ) );

  return log( getRawQuantity(indep_var) );
}

// Process the dependent value
template<typename T>
inline typename QuantityTraits<T>::RawType
LogLog::processDepVar( const T dep_var )
{
  // Make sure the indep var value is valid
  testPrecondition( LogLog::isIndepVarInValidRange( dep_var ) );

  return log( getRawQuantity(dep_var) );
}

// Recover the processed independent value
template<typename T>
inline T LogLog::recoverProcessedIndepVar( const T processed_indep_var )
{
  return exp( processed_indep_var );
}

// Recover the processed dependent value
template<typename T>
inline T LogLog::recoverProcessedDepVar( const T processed_dep_var )
{
  return exp( processed_dep_var );
}

// Test if the independent value is in a valid range (doesn't check nan/inf)
template<typename T>
inline bool LogLog::isIndepVarInValidRange( const T indep_var )
{
  // Make sure the indep var is not inf or nan
  testPrecondition( !QuantityTraits<T>::isnaninf( indep_var ) );

  return indep_var > QuantityTraits<T>::zero();
}

// Test if the dependent value is in a valid range (doesn't check nan/inf)
template<typename T>
inline bool LogLog::isDepVarInValidRange( const T dep_var )
{
  // Make sure the indep var is not inf or nan
  testPrecondition( !QuantityTraits<T>::isnaninf( dep_var ) );

  return dep_var > QuantityTraits<T>::zero();
}

// The name of the policy
inline const std::string LogLog::name()
{
  return "LogLog";
}

// Interpolate between two points
template<typename IndepType, typename DepType>
inline DepType LogLin::interpolate( const IndepType indep_var_0,
				    const IndepType indep_var_1,
				    const IndepType indep_var,
				    const DepType dep_var_0,
				    const DepType dep_var_1 )
{
  // T must be a floating point type
  testStaticPrecondition( (QuantityTraits<IndepType>::is_floating_point::value) );
  testStaticPrecondition( (QuantityTraits<DepType>::is_floating_point::value) );
  // Make sure the independent variables are valid
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var_0 ) );
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var_1 ) );
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var ) );
  testPrecondition( LogLin::isIndepVarInValidRange( indep_var_0 ) );
  testPrecondition( LogLin::isIndepVarInValidRange( indep_var_1 ) );
  testPrecondition( LogLin::isIndepVarInValidRange( indep_var ) );
  testPrecondition( indep_var_0 < indep_var_1 );
  testPrecondition( indep_var >= indep_var_0 );
  testPrecondition( indep_var <= indep_var_1 );
  // Make sure the dependent variables are valid
  testPrecondition( !QuantityTraits<DepType>::isnaninf( dep_var_0 ) );
  testPrecondition( !QuantityTraits<DepType>::isnaninf( dep_var_1 ) );
  testPrecondition( LogLin::isDepVarInValidRange( dep_var_0 ) );
  testPrecondition( LogLin::isDepVarInValidRange( dep_var_1 ) );

  return dep_var_0*pow((dep_var_1/dep_var_0), (indep_var-indep_var_0)/(indep_var_1-indep_var_0));
}

// Interpolate between two processed points
template<typename T>
inline T LogLin::interpolate( const T processed_indep_var_0,
			      const T processed_indep_var,
			      const T processed_dep_var_0,
			      const T processed_slope )
{
  // T must be a floating point type
  testStaticPrecondition( (boost::is_floating_point<T>::value) );
  // Make sure the processed independent variables are valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						     processed_indep_var_0 ) );
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						       processed_indep_var ) );
  testPrecondition( processed_indep_var_0 <= processed_indep_var );
  // Make sure the processed dependent variable is valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						       processed_dep_var_0 ) );
  // Make sure that the slope is valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf( processed_slope ) );

  return exp( processed_dep_var_0 +
	      processed_slope*(processed_indep_var - processed_indep_var_0) );
}

// Interpolate between two points and return the processed value
template<typename IndepType, typename DepType>
inline typename QuantityTraits<DepType>::RawType
LogLin::interpolateAndProcess( const IndepType indep_var_0,
			       const IndepType indep_var_1,
			       const IndepType indep_var,
			       const DepType dep_var_0,
			       const DepType dep_var_1 )
{
  // T must be a floating point type
  testStaticPrecondition( (QuantityTraits<IndepType>::is_floating_point::value) );
  testStaticPrecondition( (QuantityTraits<DepType>::is_floating_point::value) );
  // Make sure the independent variables are valid
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var_0 ) );
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var_1 ) );
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var ) );
  testPrecondition( LogLin::isIndepVarInValidRange( indep_var_0 ) );
  testPrecondition( LogLin::isIndepVarInValidRange( indep_var_1 ) );
  testPrecondition( LogLin::isIndepVarInValidRange( indep_var ) );
  testPrecondition( indep_var_0 < indep_var_1 );
  testPrecondition( indep_var >= indep_var_0 );
  testPrecondition( indep_var <= indep_var_1 );
  // Make sure the dependent variables are valid
  testPrecondition( !QuantityTraits<DepType>::isnaninf( dep_var_0 ) );
  testPrecondition( !QuantityTraits<DepType>::isnaninf( dep_var_1 ) );
  testPrecondition( LogLin::isDepVarInValidRange( dep_var_0 ) );
  testPrecondition( LogLin::isDepVarInValidRange( dep_var_1 ) );

  return log( getRawQuantity(dep_var_0) ) + log( dep_var_1/dep_var_0 )*
    (indep_var-indep_var_0)/(indep_var_1-indep_var_0);
}

// Interpolate between two processed points and return the processed value
template<typename T>
inline T LogLin::interpolateAndProcess( const T processed_indep_var_0,
					const T processed_indep_var,
					const T processed_dep_var_0,
					const T processed_slope )
{
  // T must be a floating point type
  testStaticPrecondition( (boost::is_floating_point<T>::value) );
  // Make sure the processed independent variables are valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						     processed_indep_var_0 ) );
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						       processed_indep_var ) );
  testPrecondition( processed_indep_var_0 <= processed_indep_var );
  // Make sure the processed dependent variable is valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						       processed_dep_var_0 ) );
  // Make sure that the slope is valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf( processed_slope ) );

  return processed_dep_var_0 +
    processed_slope*(processed_indep_var - processed_indep_var_0);
}

// Process the independent value
template<typename T>
inline typename QuantityTraits<T>::RawType
LogLin::processIndepVar( const T indep_var )
{
  // Make sure the indep var value is valid
  testPrecondition( LogLin::isIndepVarInValidRange( indep_var ) );

  return getRawQuantity(indep_var);
}

// Process the dependent value
template<typename T>
inline typename QuantityTraits<T>::RawType
LogLin::processDepVar( const T dep_var )
{
  // Make sure the indep var value is valid
  testPrecondition( LogLin::isDepVarInValidRange( dep_var ) );

  return log( getRawQuantity(dep_var) );
}

// Recover the processed independent value
template<typename T>
inline T LogLin::recoverProcessedIndepVar( const T processed_indep_var )
{
  return processed_indep_var;
}

// Recover the processed dependent value
template<typename T>
inline T LogLin::recoverProcessedDepVar( const T processed_dep_var )
{
  return exp( processed_dep_var );
}

// Test if the independent value is in a valid range (doesn't check nan/inf)
template<typename T>
inline bool LogLin::isIndepVarInValidRange( const T indep_var )
{
  // Make sure the indep var is not inf or nan
  testPrecondition( !QuantityTraits<T>::isnaninf( indep_var ) );

  return true;
}

// Test if the dependent value is in a valid range (doesn't check nan/inf)
template<typename T>
inline bool LogLin::isDepVarInValidRange( const T dep_var )
{
  // Make sure the indep var is not inf or nan
  testPrecondition( !QuantityTraits<T>::isnaninf( dep_var ) );

  return dep_var > QuantityTraits<T>::zero();
}

// The name of the policy
inline const std::string LogLin::name()
{
  return "LogLin";
}

// Interpolate between two points
template<typename IndepType, typename DepType>
inline DepType LinLog::interpolate( const IndepType indep_var_0,
				    const IndepType indep_var_1,
				    const IndepType indep_var,
				    const DepType dep_var_0,
				    const DepType dep_var_1 )
{
  // T must be a floating point type
  testStaticPrecondition( (QuantityTraits<IndepType>::is_floating_point::value) );
  testStaticPrecondition( (QuantityTraits<DepType>::is_floating_point::value) );
  // Make sure the independent variables are valid
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var_0 ) );
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var_1 ) );
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var ) );
  testPrecondition( LinLog::isIndepVarInValidRange( indep_var_0 ) );
  testPrecondition( LinLog::isIndepVarInValidRange( indep_var_1 ) );
  testPrecondition( LinLog::isIndepVarInValidRange( indep_var ) );
  testPrecondition( indep_var_0 < indep_var_1 );
  testPrecondition( indep_var >= indep_var_0 );
  testPrecondition( indep_var <= indep_var_1 );
  // Make sure the dependent variables are valid
  testPrecondition( !QuantityTraits<DepType>::isnaninf( dep_var_0 ) );
  testPrecondition( !QuantityTraits<DepType>::isnaninf( dep_var_1 ) );
  testPrecondition( LinLog::isDepVarInValidRange( dep_var_0 ) );
  testPrecondition( LinLog::isDepVarInValidRange( dep_var_1 ) );

  DepType term_2( (dep_var_1 - dep_var_0)*log(indep_var/indep_var_0)/
		  log(indep_var_1/indep_var_0) );

  return dep_var_0 + term_2;
}

// Interpolate between two processed point
template<typename T>
inline T LinLog::interpolate( const T processed_indep_var_0,
			      const T processed_indep_var,
			      const T processed_dep_var_0,
			      const T processed_slope )
{
  // T must be a floating point type
  testStaticPrecondition( (boost::is_floating_point<T>::value) );
  // Make sure the processed independent variables are valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						     processed_indep_var_0 ) );
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						       processed_indep_var ) );
  testPrecondition( processed_indep_var_0 <= processed_indep_var );
  // Make sure the processed dependent variable is valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						       processed_dep_var_0 ) );
  // Make sure that the slope is valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf( processed_slope ) );

  return processed_dep_var_0 +
    processed_slope*(processed_indep_var - processed_indep_var_0 );
}

// Interpolate between two points and return the processed value
template<typename IndepType, typename DepType>
inline typename QuantityTraits<DepType>::RawType
LinLog::interpolateAndProcess( const IndepType indep_var_0,
			       const IndepType indep_var_1,
			       const IndepType indep_var,
			       const DepType dep_var_0,
			       const DepType dep_var_1 )
{
  return getRawQuantity( interpolate( indep_var_0,
				      indep_var_1,
				      indep_var,
				      dep_var_0,
				      dep_var_1 ) );
}

// Interpolate between two processed points and return the processed value
template<typename T>
inline T LinLog::interpolateAndProcess( const T processed_indep_var_0,
					const T processed_indep_var,
					const T processed_dep_var_0,
					const T processed_slope )
{
  return interpolate( processed_indep_var_0,
		      processed_indep_var,
		      processed_dep_var_0,
		      processed_slope );
}

// Process the independent value
template<typename T>
inline typename QuantityTraits<T>::RawType
LinLog::processIndepVar( const T indep_var )
{
  // Make sure the indep var value is valid
  testPrecondition( LinLog::isIndepVarInValidRange( indep_var ) );

  return log( getRawQuantity(indep_var) );
}

// Process the dependent value
template<typename T>
inline typename QuantityTraits<T>::RawType
LinLog::processDepVar( const T dep_var )
{
  // Make sure the indep var value is valid
  testPrecondition( LinLog::isDepVarInValidRange( dep_var ) );

  return getRawQuantity(dep_var);
}

// Recover the processed independent value
template<typename T>
inline T LinLog::recoverProcessedIndepVar( const T processed_indep_var )
{
  return exp( processed_indep_var );
}

// Recover the processed dependent value
template<typename T>
inline T LinLog::recoverProcessedDepVar( const T processed_dep_var )
{
  return processed_dep_var;
}

// Test if the independent value is in a valid range (doesn't check nan/inf)
template<typename T>
inline bool LinLog::isIndepVarInValidRange( const T indep_var )
{
  // Make sure the indep var is not inf or nan
  testPrecondition( !QuantityTraits<T>::isnaninf( indep_var ) );

  return indep_var > QuantityTraits<T>::zero();
}

// Test if the dependent value is in a valid range (doesn't check nan/inf)
template<typename T>
inline bool LinLog::isDepVarInValidRange( const T dep_var )
{
  // Make sure the indep var is not inf or nan
  testPrecondition( !QuantityTraits<T>::isnaninf( dep_var ) );

  return true;
}

// The name of the policy
inline const std::string LinLog::name()
{
  return "LinLog";
}

// Interpolate between two points
template<typename IndepType, typename DepType>
inline DepType LinLin::interpolate( const IndepType indep_var_0,
				    const IndepType indep_var_1,
				    const IndepType indep_var,
				    const DepType dep_var_0,
				    const DepType dep_var_1 )
{
  // T must be a floating point type
  testStaticPrecondition( (QuantityTraits<IndepType>::is_floating_point::value) );
  testStaticPrecondition( (QuantityTraits<DepType>::is_floating_point::value) );
  // Make sure the independent variables are valid
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var_0 ) );
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var_1 ) );
  testPrecondition( !QuantityTraits<IndepType>::isnaninf( indep_var ) );
  testPrecondition( LinLin::isIndepVarInValidRange( indep_var_0 ) );
  testPrecondition( LinLin::isIndepVarInValidRange( indep_var_1 ) );
  testPrecondition( LinLin::isIndepVarInValidRange( indep_var ) );
  testPrecondition( indep_var_0 < indep_var_1 );
  testPrecondition( indep_var >= indep_var_0 );
  testPrecondition( indep_var <= indep_var_1 );
  // Make sure the dependent variables are valid
  testPrecondition( !QuantityTraits<DepType>::isnaninf( dep_var_0 ) );
  testPrecondition( !QuantityTraits<DepType>::isnaninf( dep_var_1 ) );
  testPrecondition( LinLin::isDepVarInValidRange( dep_var_0 ) );
  testPrecondition( LinLin::isDepVarInValidRange( dep_var_1 ) );

  DepType term_2( (dep_var_1 - dep_var_0)/(indep_var_1 - indep_var_0)*
		  (indep_var - indep_var_0) );

  return dep_var_0 + term_2;
}

// Interpolate between two processed point
template<typename T>
inline T LinLin::interpolate( const T processed_indep_var_0,
			      const T processed_indep_var,
			      const T processed_dep_var_0,
			      const T processed_slope )
{
  // T must be a floating point type
  testStaticPrecondition( (boost::is_floating_point<T>::value) );
  // Make sure the processed independent variables are valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						     processed_indep_var_0 ) );
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						       processed_indep_var ) );
  testPrecondition( processed_indep_var_0 <= processed_indep_var );
  // Make sure the processed dependent variable is valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(
						       processed_dep_var_0 ) );
  // Make sure the slope is valid
  testPrecondition( !Teuchos::ScalarTraits<T>::isnaninf(processed_slope));

  return processed_dep_var_0 +
    processed_slope*(processed_indep_var - processed_indep_var_0 );
}

// Interpolate between two points and return the processed value
template<typename IndepType, typename DepType>
inline typename QuantityTraits<DepType>::RawType
LinLin::interpolateAndProcess( const IndepType indep_var_0,
			       const IndepType indep_var_1,
			       const IndepType indep_var,
			       const DepType dep_var_0,
			       const DepType dep_var_1 )
{
  return getRawQuantity( interpolate( indep_var_0,
				      indep_var_1,
				      indep_var,
				      dep_var_0,
				      dep_var_1 ) );
}

// Interpolate between two processed points and return the processed value
template<typename T>
inline T LinLin::interpolateAndProcess( const T processed_indep_var_0,
					const T processed_indep_var,
					const T processed_dep_var_0,
					const T processed_slope )
{
  return interpolate( processed_indep_var_0,
		      processed_indep_var,
		      processed_dep_var_0,
		      processed_slope );
}

// Process the independent value
template<typename T>
inline typename QuantityTraits<T>::RawType
LinLin::processIndepVar( const T indep_var )
{
  // Make sure the indep var value is valid
  testPrecondition( LinLin::isIndepVarInValidRange( indep_var  ) );

  return getRawQuantity(indep_var);
}

// Process the dependent value
template<typename T>
inline typename QuantityTraits<T>::RawType
LinLin::processDepVar( const T dep_var )
{
  // Make sure the indep var value is valid
  testPrecondition( LinLin::isIndepVarInValidRange( dep_var ) );

  return getRawQuantity(dep_var);
}

// Recover the processed independent value
template<typename T>
inline T LinLin::recoverProcessedIndepVar( const T processed_indep_var )
{
  return processed_indep_var;
}

// Recover the processed dependent value
template<typename T>
inline T LinLin::recoverProcessedDepVar( const T processed_dep_var )
{
  return processed_dep_var;
}

// Test if the independent value is in a valid range (doesn't check nan/inf)
template<typename T>
inline bool LinLin::isIndepVarInValidRange( const T indep_var )
{
  // Make sure the indep var is not inf or nan
  testPrecondition( !QuantityTraits<T>::isnaninf( indep_var ) );

  return true;
}

// Test if the dependent value is in a valid range (doesn't check nan/inf)
template<typename T>
inline bool LinLin::isDepVarInValidRange( const T dep_var )
{
  // Make sure the indep var is not inf or nan
  testPrecondition( !QuantityTraits<T>::isnaninf( dep_var ) );

  return true;
}

// The name of the policy
inline const std::string LinLin::name()
{
  return "LinLin";
}

} // end Utility namespace

#endif // end UTILITY_INTERPOLATION_POLICY_DEF_HPP

//---------------------------------------------------------------------------//
// end Utility_InterpolationPolicy_def.hpp
//---------------------------------------------------------------------------//


text:
/*
 * internals.hpp - Auxiliary internal functions
 *
 *   Copyright 2010 Jesús Torres <jmtorres@ull.es>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INTERALS_HPP_
#define INTERALS_HPP_

#include <iostream>
#include <string>

#include <boost/system/error_code.hpp>

namespace cli { namespace internals
{

    bool isLineEmpty(const std::string& line);
    bool isStreamTty(const std::ios& stream);

}}

namespace std
{
    using namespace boost::system;
}

#endif /* INTERALS_HPP_ */

max_stars_repo_name: JonathanTrEs/Shell

max_issues_repo_name: JonathanTrEs/Shell

max_forks_repo_name: JonathanTrEs/Shell


text:
#define BOOST_TEST_MODULE pcraster discr raster_data
#include <boost/test/unit_test.hpp>
#include "pcrtypes.h"
#include "discr_rasterdata.h"

BOOST_AUTO_TEST_CASE(constructor)
{
  using namespace discr;

  size_t nrRows = 3;
  size_t nrCols = 4;
  double cellSize = 1.5;
  double west = 1.0;
  double north = 0.0;

  Raster raster(nrRows, nrCols, cellSize, west, north);

  {
    RasterData<REAL4> dem(&raster);

    for(size_t i = 0; i < raster.nrCells(); ++i) {
      BOOST_CHECK(!dem.isMV(i));
      BOOST_CHECK(dem.cell(i) == REAL4());
    }
  }

  {
    RasterData<REAL4> dem(&raster, 5.0);

    for(size_t i = 0; i < raster.nrCells(); ++i) {
      BOOST_CHECK(!dem.isMV(i));
      BOOST_CHECK(dem.cell(i) == 5.0);
    }
  }

  {
    REAL4 values[12] = {
         1.0, 3.0, 5.0, 7.0,
         2.0, 4.0, 6.0, 8.0,
         3.0, 5.0, 7.0, 9.0};
    pcr::setMV(values[6]);

    RasterData<REAL4> dem(&raster, values);

    for(size_t i = 0; i < raster.nrCells(); ++i) {
      if(i != 6) {
        BOOST_CHECK(!dem.isMV(i));
      }
    }

    BOOST_CHECK(dem.cell(0) == 1.0);
    BOOST_CHECK(dem.cell(4) == 2.0);
    BOOST_CHECK(dem.isMV(6));
    BOOST_CHECK(dem.cell(8) == 3.0);
    BOOST_CHECK(dem.cell(11) == 9.0);

    RasterData<REAL4> copyOfDem(dem);
    for(size_t i = 0; i < raster.nrCells(); ++i) {
      if(i != 6) {
        BOOST_CHECK(!dem.isMV(i));
      }
    }

    BOOST_CHECK(dem.cell(0) == 1.0);
    BOOST_CHECK(dem.cell(4) == 2.0);
    BOOST_CHECK(dem.isMV(6));
    BOOST_CHECK(dem.cell(8) == 3.0);
    BOOST_CHECK(dem.cell(11) == 9.0);
  }
}

BOOST_AUTO_TEST_CASE(equals)
{
  using namespace discr;

  Raster raster(3, 4, 1.5, 1.0, 0.0);

  REAL4 values[12] = {
       1.0, 3.0, 5.0, 7.0,
       2.0, 4.0, 6.0, 8.0,
       3.0, 5.0, 7.0, 9.0};
  pcr::setMV(values[6]);

  RasterData<REAL4> dem1(&raster, values);
  RasterData<REAL4> dem2(&raster, values);
  BOOST_CHECK(dem1 == dem1);
  BOOST_CHECK(dem1 == dem2);
  BOOST_CHECK(dem2 == dem1);

  dem2.cell(0) = 10.0;
  BOOST_CHECK(dem1 != dem2);
  BOOST_CHECK(dem2 != dem1);

  RasterData<REAL4> defaultRaster(&raster);
  BOOST_CHECK(defaultRaster == defaultRaster);
  BOOST_CHECK(dem1 != defaultRaster);
  BOOST_CHECK(defaultRaster != dem1);

  for(size_t i = 0; i < 12; ++i) {
    pcr::setMV(values[i]);
  }

  RasterData<REAL4> mvRaster(&raster, values);

  BOOST_CHECK(dem1 != mvRaster);
  dem1.setAllMV();
  BOOST_CHECK(dem1 == mvRaster);
}

BOOST_AUTO_TEST_CASE(assignment_operator)
{
  using namespace discr;

  Raster raster(3, 4, 1.5, 1.0, 0.0);
  RasterData<REAL4> dem1(&raster);

  RasterData<REAL4> dem2(&raster, 5.0);
  BOOST_CHECK(dem1 != dem2);

  dem1 = 5.0;
  BOOST_CHECK(dem1 == dem2);

  dem1 = RasterData<REAL4>(&raster);
  BOOST_CHECK(dem1 != dem2);

  dem1 = dem2;
  BOOST_CHECK(dem1 == dem2);
}

ext: cc

max_stars_repo_name: quanpands/wflow

max_issues_repo_name: quanpands/wflow

max_forks_repo_name: quanpands/wflow


text:
#include <iostream>
#include <tuple>
#include <type_traits>
#include "include/branchless_enum.hpp"

//#include <boost/variant.hpp>
//
//template<bool...> struct bool_pack;
//
//template <bool ...bs>
//using all_true = std::is_same<bool_pack<bs..., true>, bool_pack<true, bs...>>;
//
//template <bool ...bs>
//using all_false = std::is_same<bool_pack<bs..., false>, bool_pack<false, bs...>>;
//
//template <bool ...bs>
//using any_true = std::integral_constant<bool, !all_false<bs...>::value>;
//
//template <typename T, typename ...Args>
//using is_any_of = any_true<std::is_same<T, Args>::value...>;
//
//template <typename T, typename ...Args>
//constexpr bool is_any_of_v = is_any_of<T, Args...>::value;

namespace Magic
{
    enum class Type
    {
        t1,
        t2
    };

    constexpr auto toString(Type type)
    {
        return type == Type::t1 ? "t1" :
            type == Type::t2 ? "t2" : "unknow";
    }

    Type fromString(const std::string &str)
    {
        if (str == "t1") return Type::t1;
        if (str == "t2") return Type::t2;
    }
}

void foo(Magic::Type type)
{
    switch (type)
    {
    case Magic::Type::t1: std::cout << "hello t1\n";
        break;
    case Magic::Type::t2: std::cout << "hello t2\n";
        break;
    default:
        std::cout << "hello default\n";
        break;
    }
}

branchless_enum_value(be, -40, name_1, name_2)

struct Foo
{
    branchless_enum_in_class_value(be, -40, name_1, name_2)
};

struct BranchlessVisitor : public boost::static_visitor<>
{
public:
    void operator()(Foo::be::Types::name_1) const
    {
        std::cout << "hello t1\n";
    }
    void operator()(Foo::be::Types::name_2) const
    {
        std::cout << "hello t2\n";
    }

    template <typename T>
    void operator()(T) const
    {
        std::cout << "hello default\n";
    }
};

struct BenchmarkResult
{

};

void benchmark(const size_t N)
{

}

int main(int argc, char *argv[])
{
    auto magic = Magic::fromString(argv[1]);
    auto branchless = Foo::be::fromString(argv[1]);
    auto branchless2 = Foo::be::fromString(argv[2]);

    auto constexp = Foo::be::name_1;
    auto constexp2 = Foo::be::name_2;

    std::cout << "magic\n";
    foo(magic);

    std::cout << "\n\nbranchless\n";
    boost::apply_visitor(BranchlessVisitor{}, branchless);

    if (constexp == -40)

    std::cout << "\n\nconstexpr compare\n";
    if (constexp == constexp2)
        std::cout << Foo::be::toString(constexp) << " == " << Foo::be::toString(constexp2);
    else
        std::cout << Foo::be::toString(constexp) << " != " << Foo::be::toString(constexp2);

    std::cout << "\n";
    if (constexp == constexp)
        std::cout << Foo::be::toString(constexp) << " == " << Foo::be::toString(constexp);
    else
        std::cout << Foo::be::toString(constexp) << " != " << Foo::be::toString(constexp);

    std::cout << "\n\nbranchless compare\n";
    if (branchless == branchless2)
        std::cout << Foo::be::toString(branchless) << " == " << Foo::be::toString(branchless2);
    else
        std::cout << Foo::be::toString(branchless) << " != " << Foo::be::toString(branchless2);

    std::cout << "\n\nvalue compare\n";
    int value{ 100 };
    if (Foo::be::name_1.value == value)
        std::cout << Foo::be::name_1.toString() << ".value(" << Foo::be::name_1.value << ") == " << value;
    else
        std::cout << Foo::be::name_1.toString() << ".value(" << Foo::be::name_1.value << ") != " << value;

    std::cout << "\n\nvalue compare\n";
    int value2{ -39 };
    if (Foo::be::name_2.value == value2)
        std::cout << Foo::be::name_2.toString() << ".value(" << Foo::be::name_2.value << ") == " << value2;
    else
        std::cout << Foo::be::name_2.toString() << ".value(" << Foo::be::name_2.value << ") != " << value2;

    std::cout << "\n\n";
    return 0;
}


text:
////////////////////////////////////////////////////////////////////////////////
// MIT License
//
// Copyright (c) 2017 Jonas Spenger
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
////////////////////////////////////////////////////////////////////////////////

#include "msax.hpp"
#include <iostream>
#include <fstream>
#include <vector>
#include <boost/program_options.hpp>

int main(int argc, char const ** argv) {

  //////////////////////////////////////////////////////////////////////////////
  // Handle user input and implement help method.
  //////////////////////////////////////////////////////////////////////////////

  // Setup command line options parser.
  // For more information about the options parser (code copied and adapted from):
  // http://www.boost.org/doc/libs/1_65_0/doc/html/program_options/tutorial.html
  namespace po = boost::program_options;
  po::options_description desc("Options");

  // Define options.
  int windowSize;
  int alphabetSize;
  int frameSize;
  std::string mode;
  std::string filename;
  po::positional_options_description p;
  p.add("input", -1);
  desc.add_options()
    ("help,h", "Display help message.")
    ("windowsize,w", po::value<int>(&windowSize)->default_value(100),
      "Choose the sliding window size.")
    ("alphabetsize,a", po::value<int>(&alphabetSize)->default_value(8),
      "Select the size of the alphabet used for the lowdimensional approximation.")
    ("framesize,f", po::value<int>(&frameSize)->default_value(10),
      "Select the frame size of the dimensionality reduction, i.e. the amount of time series data points per symbol.")
    ("mode,m", po::value<std::string>(&mode)->default_value("normal"),
      "(normal | silent) Select the mode of the output.")
    ("input,i", po::value<std::string>(&filename),
      "The name of the input file from which to load the data")
    ("stream,s", "Read data from the standard input stream instead");

  // Parse command line options.
  po::variables_map vm;
  po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
  po::notify(vm);

  // Validate and parse option values.
  // Display help.
  if (vm.count("help")) {
    std::cout << "This is a simple c++ implementation of MSAX" << std::endl << std::endl;
    std::cout << "USAGE: MSAX (FILENAME | -i FILENAME | -s) [-w INT] [-a INT] [-n INT] [-m (normal | silent)]" <<
      std::endl << std::endl;
    std::cout << desc << "\n";
    return 0;
  }

  // Check if both filename and inputstream have been selected.
  if (vm.count("input") && vm.count("stream")) { // cant have both
    std::vector<std::string> ambigous_options;
    boost::throw_exception(po::ambiguous_option(std::vector<std::string>{"input", "stream"}));
  }

  // Check if neither filename nor inputstream have been selected.
  if (!vm.count("input") && !vm.count("stream")) { // must have either
    boost::throw_exception(po::required_option("input"));
  }

  // Check if file filename cannot be openend.
  std::ifstream infile;
  if (vm.count("input")) {
    filename = vm["input"].as< std::string>();
    infile.open(filename);
    if (!infile.is_open()) { // if could not open file
      throw po::validation_error(po::validation_error::invalid_option_value,
        "input", filename);
    }
  }

  // Check if sliding window size is smaller than 1.
  if (vm.count("windowsize")) {
    if (windowSize < 1)
      throw po::validation_error(po::validation_error::invalid_option_value,
        "windowsize", std::to_string(windowSize));
  }

  // Check if alphabet size is smaller than 1.
  if (vm.count("alphabetsize")) {
    if (alphabetSize < 1)
      throw po::validation_error(po::validation_error::invalid_option_value,
        "alphabetsize", std::to_string(alphabetSize));
  }

  // Check if number of symbols for the approximation is smaller than 1.
  if (vm.count("f")) {
    if (frameSize < 1)
      throw po::validation_error(po::validation_error::invalid_option_value,
        "f", std::to_string(frameSize));
  }

  // Check if mode is neither of the allowed values.
  if (vm.count("mode")) {
    if (mode != "silent" && mode != "normal")
      throw po::validation_error(po::validation_error::invalid_option_value,
        "mode", mode);
  }

  //////////////////////////////////////////////////////////////////////////////
  // Read file
  //////////////////////////////////////////////////////////////////////////////

  std::vector<double> input;

  // Load file infile to vector of doubles
  double v;
  if (vm.count("input")) {
    while(infile >> v) { // for every double
      input.push_back(v); // append double to input
    }
  } else if (vm.count("stream")) {
    while(std::cin >> v) { // for every double
      input.push_back(v); // append double to input
    }
  }

  //////////////////////////////////////////////////////////////////////////////
  // Perform MSAX
  //////////////////////////////////////////////////////////////////////////////

  std::vector<int> output = msax::run(input, alphabetSize, frameSize, windowSize);

  //////////////////////////////////////////////////////////////////////////////
  // Write output to cout
  //////////////////////////////////////////////////////////////////////////////

  if (mode != "silent") {
    for (int c : output) {
      std::cout << static_cast<char>('a' + c);
    }
  }

  return 0;
}

max_stars_repo_name: spengerj/MSAX

max_issues_repo_name: spengerj/MSAX

max_forks_repo_name: spengerj/MSAX


text:
//  (C) Copyright Edward Diener 2011-2015
//  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).

#include <boost/vmd/equal.hpp>
#include <boost/vmd/not_equal.hpp>
#include <boost/detail/lightweight_test.hpp>

int main()
  {

#if BOOST_PP_VARIADICS

  #define BOOST_VMD_REGISTER_aaa (aaa)
  #define BOOST_VMD_REGISTER_bbb (bbb)
  #define BOOST_VMD_REGISTER_ccc (ccc)
  #define BOOST_VMD_REGISTER_ddd (ddd)
  #define BOOST_VMD_DETECT_aaa_aaa
  #define BOOST_VMD_DETECT_bbb_bbb
  #define BOOST_VMD_DETECT_ccc_ccc
  #define BOOST_VMD_DETECT_ddd_ddd

  #define ANARRAY (3,(aaa,bbb,38))
  #define ANARRAY2 (3,(bbb,aaa,38))
  #define ANARRAY3 (3,(bbb,aaa,38))
  #define ANARRAY4 (3,(aaa,(aaa,(bbb,(ccc,BOOST_PP_NIL))),(ccc,ddd,(1)(2))))
  #define ANARRAY5 (3,(aaa,(aaa,(bbb,(ccc,BOOST_PP_NIL))),(ccc,ddd,(1)(2))))
  #define ANARRAY6 (4,(aaa,(aaa,(bbb,(ccc,BOOST_PP_NIL))),(ccc,ddd,(1)(2),37)))
  #define ATUPLE (aaa)
  #define ATUPLE2 (aaa)

  BOOST_TEST(BOOST_VMD_EQUAL(ANARRAY4,ANARRAY5,BOOST_VMD_TYPE_ARRAY));
  BOOST_TEST(BOOST_VMD_EQUAL(ANARRAY2,ANARRAY3,BOOST_VMD_TYPE_ARRAY));
  BOOST_TEST(BOOST_VMD_NOT_EQUAL(ANARRAY,ANARRAY2,BOOST_VMD_TYPE_ARRAY));
  BOOST_TEST(BOOST_VMD_NOT_EQUAL(ANARRAY5,ANARRAY6,BOOST_VMD_TYPE_ARRAY));
  BOOST_TEST(BOOST_VMD_NOT_EQUAL(ATUPLE,ATUPLE2,BOOST_VMD_TYPE_ARRAY));

#else

BOOST_ERROR("No variadic macro support");

#endif

  return boost::report_errors();

  }

ext: cxx


text:
// Copyright (c) 2015-2016 Vittorio Romeo
// License: Academic Free License ("AFL") v. 3.0
// AFL License page: http://opensource.org/licenses/AFL-3.0
// http://vittorioromeo.info | vittorio.romeo@outlook.com

#pragma once

#include <ecst/config.hpp>

#ifdef ECST_USE_MEGANZ_MINGW_THREAD

#pragma GCC system_header

#include <thread>
#include <mutex>
#include <condition_variable>

// https://github.com/meganz/mingw-std-threads
#include "./third_party/mingw-std-threads/mingw.thread.h"
#include "./third_party/mingw-std-threads/mingw.mutex.h"
#include "./third_party/mingw-std-threads/mingw.condition_variable.h"

#define BOOST_THREAD_PROVIDES_FUTURE 1
#include <boost/thread/future.hpp>

namespace std
{
    using boost::future;
    using boost::launch;

    template <typename... Ts>
    auto async(Ts&&... xs)
    {
        return boost::async(std::forward<Ts>(xs)...);
    }
}

#define _GLIBCXX_FUTURE 1

#endif

#include <chrono>
#include <thread>
#include <atomic>
#include <mutex>
#include <condition_variable>

ECST_NAMESPACE
{
    namespace this_thread = std::this_thread;
    namespace chrono = std::chrono;
    using std::thread;
    using std::mutex;
    using std::atomic;
    using std::condition_variable;
    using std::lock_guard;
    using std::unique_lock;
}
ECST_NAMESPACE_END

max_issues_repo_name: vittorioromeo/ecst

max_forks_repo_name: vittorioromeo/ecst