<commit_before>//  (C) Copyright Gennadiy Rozental 2004-2005.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision$
//
//  Description : token iterator for string and range tokenization
// ***************************************************************************

#ifndef BOOST_TOKEN_ITERATOR_HPP_071894GER
#define BOOST_TOKEN_ITERATOR_HPP_071894GER

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

#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/iterator_traits.hpp>

#include <boost/test/utils/iterator/input_iterator_facade.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/test/utils/named_params.hpp>
#include <boost/test/utils/foreach.hpp>

// STL
#include <iosfwd>
#include <cctype>

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

//____________________________________________________________________________//

#ifdef BOOST_NO_STDC_NAMESPACE
namespace std{ using ::ispunct; using ::isspace; }
#endif

namespace boost {

namespace unit_test {

// ************************************************************************** //
// **************               ti_delimeter_type              ************** //
// ************************************************************************** //

enum ti_delimeter_type {
    dt_char,        // character is delimeter if it among explicit list of some characters
    dt_ispunct,     // character is delimeter if it satisfies ispunct functor
    dt_isspace,     // character is delimeter if it satisfies isspace functor
    dt_none         // no character is delimeter
};

namespace ut_detail {

// ************************************************************************** //
// **************             default_char_compare             ************** //
// ************************************************************************** //

template<typename CharT>
class default_char_compare {
public:
    bool operator()( CharT c1, CharT c2 )
    {
#ifdef BOOST_CLASSIC_IOSTREAMS
        return std::string_char_traits<CharT>::eq( c1, c2 );
#else
        return std::char_traits<CharT>::eq( c1, c2 );
#endif
    }
};

// ************************************************************************** //
// **************                 delim_policy                 ************** //
// ************************************************************************** //

template<typename CharT,typename CharCompare>
class delim_policy {
    typedef basic_cstring<CharT const> cstring;
public:
    // Constructor
    explicit    delim_policy( ti_delimeter_type t = dt_char, cstring d = cstring() )
    : m_type( t )
    {
        set_delimeters( d );
    }

    void        set_delimeters( ti_delimeter_type t ) { m_type = t; }
    template<typename Src>
    void        set_delimeters( Src d )
    {
        nfp::optionally_assign( m_delimeters, d );

        if( !m_delimeters.is_empty() )
            m_type = dt_char;
    }

    bool        operator()( CharT c )
    {
        #if BOOST_WORKAROUND(__MWERKS__, <= 0x3003)
        if ( dt_char == m_type )
        {
            BOOST_TEST_FOREACH( CharT, delim, m_delimeters )
                if( CharCompare()( delim, c ) )
                    return true;

            return false;
        }
        if ( dt_ispunct == m_type )
        {
            return (std::ispunct)( c ) != 0;
        }
        if ( dt_isspace == m_type )
        {
            return (std::isspace)( c ) != 0;
        }
        if ( dt_none == m_type )
        {
            return false;
        }
        #else
        switch( m_type ) {
        case dt_char:
            BOOST_TEST_FOREACH( CharT, delim, m_delimeters )
                if( CharCompare()( delim, c ) )
                    return true;

            return false;
        case dt_ispunct:
            return (std::ispunct)( c ) != 0;
        case dt_isspace:
            return (std::isspace)( c ) != 0;
        case dt_none:
            return false;
        }
        #endif

        return false;
    }

private:
    // Data members
    cstring             m_delimeters;
    ti_delimeter_type   m_type;
};

// ************************************************************************** //
// **************                 token_assigner               ************** //
// ************************************************************************** //

template<typename TraversalTag>
struct token_assigner {
#if BOOST_WORKAROUND( BOOST_DINKUMWARE_STDLIB, < 306 )
    template<typename Iterator, typename C, typename T>
    static void assign( Iterator b, Iterator e, std::basic_string<C,T>& t )
    { for( ; b != e; ++b ) t += *b; }

    template<typename Iterator, typename C>
    static void assign( Iterator b, Iterator e, basic_cstring<C>& t )  { t.assign( b, e ); }
#else
    template<typename Iterator, typename Token>
    static void assign( Iterator b, Iterator e, Token& t )  { t.assign( b, e ); }
#endif
    template<typename Iterator, typename Token>
    static void append_move( Iterator& b, Token& )          { ++b; }
};

template<>
struct token_assigner<single_pass_traversal_tag> {
    template<typename Iterator, typename Token>
    static void assign( Iterator b, Iterator e, Token& t )  {}

    template<typename Iterator, typename Token>
    static void append_move( Iterator& b, Token& t )        { t += *b; ++b; }
};

} // namespace ut_detail

// ************************************************************************** //
// **************                  modifiers                   ************** //
// ************************************************************************** //

namespace {
nfp::keyword<struct dropped_delimeters_t > dropped_delimeters;
nfp::keyword<struct kept_delimeters_t > kept_delimeters;
nfp::typed_keyword<bool,struct keep_empty_tokens_t > keep_empty_tokens;
nfp::typed_keyword<std::size_t,struct max_tokens_t > max_tokens;
}

// ************************************************************************** //
// **************             token_iterator_base              ************** //
// ************************************************************************** //

template<typename Derived,
         typename CharT,
         typename CharCompare   = ut_detail::default_char_compare<CharT>,
         typename ValueType     = basic_cstring<CharT const>,
         typename Reference     = basic_cstring<CharT const>,
         typename Traversal     = forward_traversal_tag>
class token_iterator_base
: public input_iterator_facade<Derived,ValueType,Reference,Traversal> {
    typedef basic_cstring<CharT const>                                      cstring;
    typedef ut_detail::delim_policy<CharT,CharCompare>                      delim_policy;
    typedef input_iterator_facade<Derived,ValueType,Reference,Traversal>    base;

protected:
    // Constructor
    explicit    token_iterator_base()
    : m_is_dropped( dt_isspace )
    , m_is_kept( dt_ispunct )
    , m_keep_empty_tokens( false )
    , m_token_produced( false )
    , m_tokens_left( (std::size_t)-1 )
    {
    }

    template<typename Modifier>
    void
    apply_modifier( Modifier const& m )
    {
        if( m.has( dropped_delimeters ) )
            m_is_dropped.set_delimeters( m[dropped_delimeters] );

        if( m.has( kept_delimeters ) )
            m_is_kept.set_delimeters( m[kept_delimeters] );

        if( m.has( keep_empty_tokens ) )
            m_keep_empty_tokens = true;

        nfp::optionally_assign( m_tokens_left, m, max_tokens );
    }

    template<typename Iter>
    bool                    get( Iter& begin, Iter end )
    {
        typedef ut_detail::token_assigner<BOOST_DEDUCED_TYPENAME iterator_traversal<Iter>::type> Assigner;
        Iter checkpoint;

#if BOOST_WORKAROUND( BOOST_DINKUMWARE_STDLIB, < 306 ) \
    || BOOST_WORKAROUND( __GNUC__, < 3 ) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
    this->m_value.erase();
#else
    this->m_value.clear();
#endif

        if( !m_keep_empty_tokens ) {
            while( begin != end && m_is_dropped( *begin ) )
                ++begin;

            if( begin == end )
                return false;

            checkpoint = begin;

            if( m_tokens_left == 1 )
                while( begin != end )
                    Assigner::append_move( begin, this->m_value );
            else if( m_is_kept( *begin ) )
                Assigner::append_move( begin, this->m_value );
            else
                while( begin != end && !m_is_dropped( *begin ) && !m_is_kept( *begin ) )
                    Assigner::append_move( begin, this->m_value );

            --m_tokens_left;
        }
        else { // m_keep_empty_tokens is true
            checkpoint = begin;

            if( begin == end ) {
                if( m_token_produced )
                    return false;

                m_token_produced = true;
            }
            if( m_is_kept( *begin ) ) {
                if( m_token_produced )
                    Assigner::append_move( begin, this->m_value );

                m_token_produced = !m_token_produced;
            }
            else if( !m_token_produced && m_is_dropped( *begin ) )
                m_token_produced = true;
            else {
                if( m_is_dropped( *begin ) )
                    checkpoint = ++begin;

                while( begin != end && !m_is_dropped( *begin ) && !m_is_kept( *begin ) )
                    Assigner::append_move( begin, this->m_value );

                m_token_produced = true;
            }
        }

        Assigner::assign( checkpoint, begin, this->m_value );

        return true;
    }

private:
    // Data members
    delim_policy            m_is_dropped;
    delim_policy            m_is_kept;
    bool                    m_keep_empty_tokens;
    std::size_t             m_tokens_left;
    bool                    m_token_produced;
};

// ************************************************************************** //
// **************          basic_string_token_iterator         ************** //
// ************************************************************************** //

template<typename CharT,
         typename CharCompare = ut_detail::default_char_compare<CharT> >
class basic_string_token_iterator
: public token_iterator_base<basic_string_token_iterator<CharT,CharCompare>,CharT,CharCompare> {
    typedef basic_cstring<CharT const> cstring;
    typedef token_iterator_base<basic_string_token_iterator<CharT,CharCompare>,CharT,CharCompare> base;
public:
    explicit    basic_string_token_iterator() {}
    explicit    basic_string_token_iterator( cstring src )
    : m_src( src )
    {
        this->init();
    }

    template<typename Src, typename Modifier>
    basic_string_token_iterator( Src src, Modifier const& m )
    : m_src( src )
    {
        this->apply_modifier( m );

        this->init();
    }

private:
    friend class input_iterator_core_access;

    // input iterator implementation
    bool        get()
    {
        typename cstring::iterator begin = m_src.begin();
        bool res = base::get( begin, m_src.end() );

        m_src.assign( begin, m_src.end() );

        return res;
    }

    // Data members
    cstring     m_src;
};

typedef basic_string_token_iterator<char>       string_token_iterator;
typedef basic_string_token_iterator<wchar_t>    wstring_token_iterator;

// ************************************************************************** //
// **************              range_token_iterator            ************** //
// ************************************************************************** //

template<typename Iter,
         typename CharCompare = ut_detail::default_char_compare<BOOST_DEDUCED_TYPENAME iterator_value<Iter>::type>,
         typename ValueType   = std::basic_string<BOOST_DEDUCED_TYPENAME iterator_value<Iter>::type>,
         typename Reference   = ValueType const&>
class range_token_iterator
: public token_iterator_base<range_token_iterator<Iter,CharCompare,ValueType,Reference>,
                             typename iterator_value<Iter>::type,CharCompare,ValueType,Reference> {
    typedef basic_cstring<typename ValueType::value_type> cstring;
    typedef token_iterator_base<range_token_iterator<Iter,CharCompare,ValueType,Reference>,
                                typename iterator_value<Iter>::type,CharCompare,ValueType,Reference> base;
public:
    explicit    range_token_iterator() {}
    explicit    range_token_iterator( Iter begin, Iter end = Iter() )
    : m_begin( begin ), m_end( end )
    {
        this->init();
    }

    template<typename Modifier>
    range_token_iterator( Iter begin, Iter end, Modifier const& m )
    : m_begin( begin ), m_end( end )
    {
        this->apply_modifier( m );

        this->init();
    }

private:
    friend class input_iterator_core_access;

    // input iterator implementation
    bool        get()
    {
        return base::get( m_begin, m_end );
    }

    // Data members
    Iter m_begin;
    Iter m_end;
};

// ************************************************************************** //
// **************            make_range_token_iterator         ************** //
// ************************************************************************** //

template<typename Iter>
inline range_token_iterator<Iter>
make_range_token_iterator( Iter begin, Iter end = Iter() )
{
    return range_token_iterator<Iter>( begin, end );
}

//____________________________________________________________________________//

template<typename Iter,typename Modifier>
inline range_token_iterator<Iter>
make_range_token_iterator( Iter begin, Iter end, Modifier const& m )
{
    return range_token_iterator<Iter>( begin, end, m );
}

//____________________________________________________________________________//

} // namespace unit_test

} // namespace boost

//____________________________________________________________________________//

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

// ***************************************************************************
//  Revision History :
//
//  $Log$
//  Revision 1.6  2005/06/05 16:07:51  grafik
//  Work around CW-8 problem parsing the switch statement.
//
//  Revision 1.5  2005/04/12 06:46:42  rogeeff
//  use named_param facilites
//
//  Revision 1.4  2005/02/20 08:27:09  rogeeff
//  This a major update for Boost.Test framework. See release docs for complete list of fixes/updates
//
//  Revision 1.3  2005/02/01 06:40:08  rogeeff
//  copyright update
//  old log entries removed
//  minor stylitic changes
//  deprecated tools removed
//
//  Revision 1.2  2005/01/22 19:22:14  rogeeff
//  implementation moved into headers section to eliminate dependency of included/minimal component on src directory
//
//  Revision 1.1  2005/01/22 18:21:40  rogeeff
//  moved sharable staff into utils
//
// ***************************************************************************

#endif // BOOST_TOKEN_ITERATOR_HPP_071894GER

<commit_msg>1. Always use clear reorder field in constructor to eliminate warning remove cw workaround - doesn't seems to be needed<commit_after>//  (C) Copyright Gennadiy Rozental 2004-2005.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision$
//
//  Description : token iterator for string and range tokenization
// ***************************************************************************

#ifndef BOOST_TOKEN_ITERATOR_HPP_071894GER
#define BOOST_TOKEN_ITERATOR_HPP_071894GER

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

#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/iterator_traits.hpp>

#include <boost/test/utils/iterator/input_iterator_facade.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/test/utils/named_params.hpp>
#include <boost/test/utils/foreach.hpp>

// STL
#include <iosfwd>
#include <cctype>

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

//____________________________________________________________________________//

#ifdef BOOST_NO_STDC_NAMESPACE
namespace std{ using ::ispunct; using ::isspace; }
#endif

namespace boost {

namespace unit_test {

// ************************************************************************** //
// **************               ti_delimeter_type              ************** //
// ************************************************************************** //

enum ti_delimeter_type {
    dt_char,        // character is delimeter if it among explicit list of some characters
    dt_ispunct,     // character is delimeter if it satisfies ispunct functor
    dt_isspace,     // character is delimeter if it satisfies isspace functor
    dt_none         // no character is delimeter
};

namespace ut_detail {

// ************************************************************************** //
// **************             default_char_compare             ************** //
// ************************************************************************** //

template<typename CharT>
class default_char_compare {
public:
    bool operator()( CharT c1, CharT c2 )
    {
#ifdef BOOST_CLASSIC_IOSTREAMS
        return std::string_char_traits<CharT>::eq( c1, c2 );
#else
        return std::char_traits<CharT>::eq( c1, c2 );
#endif
    }
};

// ************************************************************************** //
// **************                 delim_policy                 ************** //
// ************************************************************************** //

template<typename CharT,typename CharCompare>
class delim_policy {
    typedef basic_cstring<CharT const> cstring;
public:
    // Constructor
    explicit    delim_policy( ti_delimeter_type t = dt_char, cstring d = cstring() )
    : m_type( t )
    {
        set_delimeters( d );
    }

    void        set_delimeters( ti_delimeter_type t ) { m_type = t; }
    template<typename Src>
    void        set_delimeters( Src d )
    {
        nfp::optionally_assign( m_delimeters, d );

        if( !m_delimeters.is_empty() )
            m_type = dt_char;
    }

    bool        operator()( CharT c )
    {
        switch( m_type ) {
        case dt_char: {
            BOOST_TEST_FOREACH( CharT, delim, m_delimeters )
                if( CharCompare()( delim, c ) )
                    return true;

            return false;
        }
        case dt_ispunct:
            return (std::ispunct)( c ) != 0;
        case dt_isspace:
            return (std::isspace)( c ) != 0;
        case dt_none:
            return false;
        }

        return false;
    }

private:
    // Data members
    cstring             m_delimeters;
    ti_delimeter_type   m_type;
};

// ************************************************************************** //
// **************                 token_assigner               ************** //
// ************************************************************************** //

template<typename TraversalTag>
struct token_assigner {
#if BOOST_WORKAROUND( BOOST_DINKUMWARE_STDLIB, < 306 )
    template<typename Iterator, typename C, typename T>
    static void assign( Iterator b, Iterator e, std::basic_string<C,T>& t )
    { for( ; b != e; ++b ) t += *b; }

    template<typename Iterator, typename C>
    static void assign( Iterator b, Iterator e, basic_cstring<C>& t )  { t.assign( b, e ); }
#else
    template<typename Iterator, typename Token>
    static void assign( Iterator b, Iterator e, Token& t )  { t.assign( b, e ); }
#endif
    template<typename Iterator, typename Token>
    static void append_move( Iterator& b, Token& )          { ++b; }
};

//____________________________________________________________________________//

template<>
struct token_assigner<single_pass_traversal_tag> {
    template<typename Iterator, typename Token>
    static void assign( Iterator b, Iterator e, Token& t )  {}

    template<typename Iterator, typename Token>
    static void append_move( Iterator& b, Token& t )        { t += *b; ++b; }
};

} // namespace ut_detail

// ************************************************************************** //
// **************                  modifiers                   ************** //
// ************************************************************************** //

namespace {
nfp::keyword<struct dropped_delimeters_t > dropped_delimeters;
nfp::keyword<struct kept_delimeters_t > kept_delimeters;
nfp::typed_keyword<bool,struct keep_empty_tokens_t > keep_empty_tokens;
nfp::typed_keyword<std::size_t,struct max_tokens_t > max_tokens;
}

// ************************************************************************** //
// **************             token_iterator_base              ************** //
// ************************************************************************** //

template<typename Derived,
         typename CharT,
         typename CharCompare   = ut_detail::default_char_compare<CharT>,
         typename ValueType     = basic_cstring<CharT const>,
         typename Reference     = basic_cstring<CharT const>,
         typename Traversal     = forward_traversal_tag>
class token_iterator_base
: public input_iterator_facade<Derived,ValueType,Reference,Traversal> {
    typedef basic_cstring<CharT const>                                      cstring;
    typedef ut_detail::delim_policy<CharT,CharCompare>                      delim_policy;
    typedef input_iterator_facade<Derived,ValueType,Reference,Traversal>    base;

protected:
    // Constructor
    explicit    token_iterator_base()
    : m_is_dropped( dt_isspace )
    , m_is_kept( dt_ispunct )
    , m_keep_empty_tokens( false )
    , m_tokens_left( (std::size_t)-1 )
    , m_token_produced( false )
    {
    }

    template<typename Modifier>
    void
    apply_modifier( Modifier const& m )
    {
        if( m.has( dropped_delimeters ) )
            m_is_dropped.set_delimeters( m[dropped_delimeters] );

        if( m.has( kept_delimeters ) )
            m_is_kept.set_delimeters( m[kept_delimeters] );

        if( m.has( keep_empty_tokens ) )
            m_keep_empty_tokens = true;

        nfp::optionally_assign( m_tokens_left, m, max_tokens );
    }

    template<typename Iter>
    bool                    get( Iter& begin, Iter end )
    {
        typedef ut_detail::token_assigner<BOOST_DEDUCED_TYPENAME iterator_traversal<Iter>::type> Assigner;
        Iter checkpoint;

        this->m_value.clear();

        if( !m_keep_empty_tokens ) {
            while( begin != end && m_is_dropped( *begin ) )
                ++begin;

            if( begin == end )
                return false;

            checkpoint = begin;

            if( m_tokens_left == 1 )
                while( begin != end )
                    Assigner::append_move( begin, this->m_value );
            else if( m_is_kept( *begin ) )
                Assigner::append_move( begin, this->m_value );
            else
                while( begin != end && !m_is_dropped( *begin ) && !m_is_kept( *begin ) )
                    Assigner::append_move( begin, this->m_value );

            --m_tokens_left;
        }
        else { // m_keep_empty_tokens is true
            checkpoint = begin;

            if( begin == end ) {
                if( m_token_produced )
                    return false;

                m_token_produced = true;
            }
            if( m_is_kept( *begin ) ) {
                if( m_token_produced )
                    Assigner::append_move( begin, this->m_value );

                m_token_produced = !m_token_produced;
            }
            else if( !m_token_produced && m_is_dropped( *begin ) )
                m_token_produced = true;
            else {
                if( m_is_dropped( *begin ) )
                    checkpoint = ++begin;

                while( begin != end && !m_is_dropped( *begin ) && !m_is_kept( *begin ) )
                    Assigner::append_move( begin, this->m_value );

                m_token_produced = true;
            }
        }

        Assigner::assign( checkpoint, begin, this->m_value );

        return true;
    }

private:
    // Data members
    delim_policy            m_is_dropped;
    delim_policy            m_is_kept;
    bool                    m_keep_empty_tokens;
    std::size_t             m_tokens_left;
    bool                    m_token_produced;
};

// ************************************************************************** //
// **************          basic_string_token_iterator         ************** //
// ************************************************************************** //

template<typename CharT,
         typename CharCompare = ut_detail::default_char_compare<CharT> >
class basic_string_token_iterator
: public token_iterator_base<basic_string_token_iterator<CharT,CharCompare>,CharT,CharCompare> {
    typedef basic_cstring<CharT const> cstring;
    typedef token_iterator_base<basic_string_token_iterator<CharT,CharCompare>,CharT,CharCompare> base;
public:
    explicit    basic_string_token_iterator() {}
    explicit    basic_string_token_iterator( cstring src )
    : m_src( src )
    {
        this->init();
    }

    template<typename Src, typename Modifier>
    basic_string_token_iterator( Src src, Modifier const& m )
    : m_src( src )
    {
        this->apply_modifier( m );

        this->init();
    }

private:
    friend class input_iterator_core_access;

    // input iterator implementation
    bool        get()
    {
        typename cstring::iterator begin = m_src.begin();
        bool res = base::get( begin, m_src.end() );

        m_src.assign( begin, m_src.end() );

        return res;
    }

    // Data members
    cstring     m_src;
};

typedef basic_string_token_iterator<char>       string_token_iterator;
typedef basic_string_token_iterator<wchar_t>    wstring_token_iterator;

// ************************************************************************** //
// **************              range_token_iterator            ************** //
// ************************************************************************** //

template<typename Iter,
         typename CharCompare = ut_detail::default_char_compare<BOOST_DEDUCED_TYPENAME iterator_value<Iter>::type>,
         typename ValueType   = std::basic_string<BOOST_DEDUCED_TYPENAME iterator_value<Iter>::type>,
         typename Reference   = ValueType const&>
class range_token_iterator
: public token_iterator_base<range_token_iterator<Iter,CharCompare,ValueType,Reference>,
                             typename iterator_value<Iter>::type,CharCompare,ValueType,Reference> {
    typedef basic_cstring<typename ValueType::value_type> cstring;
    typedef token_iterator_base<range_token_iterator<Iter,CharCompare,ValueType,Reference>,
                                typename iterator_value<Iter>::type,CharCompare,ValueType,Reference> base;
public:
    explicit    range_token_iterator() {}
    explicit    range_token_iterator( Iter begin, Iter end = Iter() )
    : m_begin( begin ), m_end( end )
    {
        this->init();
    }

    template<typename Modifier>
    range_token_iterator( Iter begin, Iter end, Modifier const& m )
    : m_begin( begin ), m_end( end )
    {
        this->apply_modifier( m );

        this->init();
    }

private:
    friend class input_iterator_core_access;

    // input iterator implementation
    bool        get()
    {
        return base::get( m_begin, m_end );
    }

    // Data members
    Iter m_begin;
    Iter m_end;
};

// ************************************************************************** //
// **************            make_range_token_iterator         ************** //
// ************************************************************************** //

template<typename Iter>
inline range_token_iterator<Iter>
make_range_token_iterator( Iter begin, Iter end = Iter() )
{
    return range_token_iterator<Iter>( begin, end );
}

//____________________________________________________________________________//

template<typename Iter,typename Modifier>
inline range_token_iterator<Iter>
make_range_token_iterator( Iter begin, Iter end, Modifier const& m )
{
    return range_token_iterator<Iter>( begin, end, m );
}

//____________________________________________________________________________//

} // namespace unit_test

} // namespace boost

//____________________________________________________________________________//

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

// ***************************************************************************
//  Revision History :
//
//  $Log$
//  Revision 1.7  2005/06/11 19:23:28  rogeeff
//  1. Always use clear
//  reorder field in constructor to eliminate warning
//  remove cw workaround - doesn't seems to be needed
//
//  Revision 1.6  2005/06/05 16:07:51  grafik
//  Work around CW-8 problem parsing the switch statement.
//
//  Revision 1.5  2005/04/12 06:46:42  rogeeff
//  use named_param facilites
//
//  Revision 1.4  2005/02/20 08:27:09  rogeeff
//  This a major update for Boost.Test framework. See release docs for complete list of fixes/updates
//
//  Revision 1.3  2005/02/01 06:40:08  rogeeff
//  copyright update
//  old log entries removed
//  minor stylitic changes
//  deprecated tools removed
//
//  Revision 1.2  2005/01/22 19:22:14  rogeeff
//  implementation moved into headers section to eliminate dependency of included/minimal component on src directory
//
//  Revision 1.1  2005/01/22 18:21:40  rogeeff
//  moved sharable staff into utils
//
// ***************************************************************************

#endif // BOOST_TOKEN_ITERATOR_HPP_071894GER

<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

// This file contains the WebRTC suppressions for ThreadSanitizer.
// Please refer to
// http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2
// for more info.

#if defined(THREAD_SANITIZER)

// Please make sure the code below declares a single string variable
// kTSanDefaultSuppressions contains TSan suppressions delimited by newlines.
// See http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2
// for the instructions on writing suppressions.
char kTSanDefaultSuppressions[] =

    // WebRTC specific suppressions.

    // Split up suppressions covered previously by thread.cc and
    // messagequeue.cc.
    "race:vp8cx_remove_encoder_threads\n"
    "race:third_party/libvpx/source/libvpx/vp9/common/vp9_scan.h\n"

    // rtc_unittests
    // https://code.google.com/p/webrtc/issues/detail?id=2080
    "race:rtc_base/logging.cc\n"
    "race:rtc_base/shared_exclusive_lock_unittest.cc\n"
    "race:rtc_base/signal_thread_unittest.cc\n"

    // rtc_pc_unittests
    // https://code.google.com/p/webrtc/issues/detail?id=2079
    "race:rtc_base/test_client.cc\n"
    "race:rtc_base/virtual_socket_server.cc\n"
    "race:talk/p2p/base/stun_server_unittest.cc\n"

    // third_party/usrsctp
    // TODO(jiayl): https://code.google.com/p/webrtc/issues/detail?id=3492
    "race:user_sctp_timer_iterate\n"

    // https://code.google.com/p/webrtc/issues/detail?id=5151
    "race:sctp_close\n"

    // Potential deadlocks detected after roll in r6516.
    // https://code.google.com/p/webrtc/issues/detail?id=3509
    "deadlock:webrtc::test::UdpSocketManagerPosixImpl::RemoveSocket\n"

    // TODO(pbos): Trace events are racy due to lack of proper POD atomics.
    // https://code.google.com/p/webrtc/issues/detail?id=2497
    "race:*trace_event_unique_catstatic*\n"

    // Race between InitCpuFlags and TestCpuFlag in libyuv.
    // https://code.google.com/p/libyuv/issues/detail?id=508
    "race:InitCpuFlags\n"

    // Test-only race due to PeerConnection::session() being virtual for
    // testing. The stats collector may call session() before or after the
    // destructor begins executing, which modifies the vtable.
    "race:*RTCStatsIntegrationTest_GetsStatsWhileDestroyingPeerConnections_"
    "Test::TestBody\n"

    // End of suppressions.
    ;  // Please keep this semicolon.

#endif  // THREAD_SANITIZER
<commit_msg>[tsan] Suppress all of libpulsecommon*.so, following chromium.<commit_after>/*
 *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

// This file contains the WebRTC suppressions for ThreadSanitizer.
// Please refer to
// http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2
// for more info.

#if defined(THREAD_SANITIZER)

// Please make sure the code below declares a single string variable
// kTSanDefaultSuppressions contains TSan suppressions delimited by newlines.
// See http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2
// for the instructions on writing suppressions.
char kTSanDefaultSuppressions[] =

    // WebRTC specific suppressions.

    // Split up suppressions covered previously by thread.cc and
    // messagequeue.cc.
    "race:vp8cx_remove_encoder_threads\n"
    "race:third_party/libvpx/source/libvpx/vp9/common/vp9_scan.h\n"

    // rtc_unittests
    // https://code.google.com/p/webrtc/issues/detail?id=2080
    "race:rtc_base/logging.cc\n"
    "race:rtc_base/shared_exclusive_lock_unittest.cc\n"
    "race:rtc_base/signal_thread_unittest.cc\n"

    // rtc_pc_unittests
    // https://code.google.com/p/webrtc/issues/detail?id=2079
    "race:rtc_base/test_client.cc\n"
    "race:rtc_base/virtual_socket_server.cc\n"
    "race:talk/p2p/base/stun_server_unittest.cc\n"

    // third_party/usrsctp
    // TODO(jiayl): https://code.google.com/p/webrtc/issues/detail?id=3492
    "race:user_sctp_timer_iterate\n"

    // https://code.google.com/p/webrtc/issues/detail?id=5151
    "race:sctp_close\n"

    // Potential deadlocks detected after roll in r6516.
    // https://code.google.com/p/webrtc/issues/detail?id=3509
    "deadlock:webrtc::test::UdpSocketManagerPosixImpl::RemoveSocket\n"

    // TODO(pbos): Trace events are racy due to lack of proper POD atomics.
    // https://code.google.com/p/webrtc/issues/detail?id=2497
    "race:*trace_event_unique_catstatic*\n"

    // Race between InitCpuFlags and TestCpuFlag in libyuv.
    // https://code.google.com/p/libyuv/issues/detail?id=508
    "race:InitCpuFlags\n"

    // Test-only race due to PeerConnection::session() being virtual for
    // testing. The stats collector may call session() before or after the
    // destructor begins executing, which modifies the vtable.
    "race:*RTCStatsIntegrationTest_GetsStatsWhileDestroyingPeerConnections_"
    "Test::TestBody\n"

    // http://crbug.com/244856
    "race:libpulsecommon*.so\n"

    // End of suppressions.
    ;  // Please keep this semicolon.

#endif  // THREAD_SANITIZER
<|endoftext|>


<commit_before>#include <QApplication>
#include <QFileInfo>
#include "player.h"
#include "config.h"
#include "tokolosh_interface.h"

int main(int argc, char * argv[])
{
    QApplication app(argc,argv);
    app.setApplicationName("tokoloshhead_v2");

    TokoloshInterface dbusInterface("com.TokoloshXineBackend.TokoloshMediaPlayer",
                                    "/TokoloshMediaPlayer",
                                    QDBusConnection::sessionBus(),
                                    &app);

    const QMetaObject *dbusInterfaceMetaObject = dbusInterface.metaObject();

    foreach(QString arg, Config::unusedArguments()) {
        if (QFile::exists(arg)) {
            // does QFile match for dirs?
            //If dir: add path + scan
            //If file, load file?
            QString consideredPath(arg);
            while(QFileInfo(consideredPath).isSymLink()) {
                //FIXME: might want to have a counter incase there is a cyclical symlink
                consideredPath = QFileInfo(consideredPath).symLinkTarget();
            }
            if(QFileInfo(consideredPath).isFile()){
                dbusInterface.load(arg);
            }
            //path loading not in interface! investigating seperately
        } else if (arg.startsWith('-')) {
            //Does not handle slots with arguments, which can be largely reduced to the file paths above
            const char* charArg = arg.endsWith("()")
                            ? arg.toAscii().constData()
                            : arg.append("()").toAscii().constData();
            //char*+1 is a nasty but efficient way to drop the first char
            const int index = dbusInterfaceMetaObject->indexOfSlot(charArg+1);
            if(index != -1) {
                qWarning("%s has index %d",charArg+1,index);
                dbusInterfaceMetaObject->method(index).invoke( &dbusInterface,
                                                               Qt::DirectConnection,
                                                               QGenericReturnArgument());
            } else {
                qWarning("Unknown argument %s", qPrintable(arg));
            }
            app.quit();
            return 0;
        } else {
            qWarning("%s doesn't seem to exist", qPrintable(arg));
        }
    }
    Player player(&dbusInterface);
    if (!player.setSkin(Config::value<QString>("skin", QString(":/skins/dullSod")))) {
        const bool ret = player.setSkin(QLatin1String(":/skins/dullSod"));
        Q_ASSERT(ret);
        Q_UNUSED(ret);
    }
    player.show();
    return app.exec();
}
/*
   Donald Carr (sirspudd_at_gmail.com) plays songs occasionally
   Copyright (C) 2007 Donald Car

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation, Inc.,
   51 Franklin Street, Fifth Floor, Boston, MAction 02110-1301 USAction.
   */
<commit_msg>- Allow -arg arguments to be followed by single QString argument which   is passed to the method on invocation<commit_after>#include <QApplication>
#include <QFileInfo>
#include "player.h"
#include "config.h"
#include "tokolosh_interface.h"

int main(int argc, char * argv[])
{
    QApplication app(argc,argv);
    app.setApplicationName("tokoloshhead_v2");

    TokoloshInterface dbusInterface("com.TokoloshXineBackend.TokoloshMediaPlayer",
                                    "/TokoloshMediaPlayer",
                                    QDBusConnection::sessionBus(),
                                    &app);

    int queuedMethodIndex = -1;
    const QMetaObject *dbusInterfaceMetaObject = dbusInterface.metaObject();

    foreach(QString arg, Config::unusedArguments()) {
        if ((queuedMethodIndex == -1) &&
            QFile::exists(arg))
        {
            // does QFile match for dirs?
            //If dir: add path + scan
            //If file, load file?
            QString consideredPath(arg);
            while(QFileInfo(consideredPath).isSymLink()) {
                //FIXME: might want to have a counter incase there is a cyclical symlink
                consideredPath = QFileInfo(consideredPath).symLinkTarget();
            }
            if(QFileInfo(consideredPath).isFile()){
                dbusInterface.load(arg);
            } else {
                //handle me
                //path loading not in interface! investigating seperately
            }
        } else if (arg.startsWith('-')) {
            queuedMethodIndex = -1;
            const char* charArg = arg.endsWith("()")
                            ? arg.toAscii().constData()
                            : arg.append("()").toAscii().constData();
            //char*+1 is a nasty but efficient way to drop the first char
            const int index = dbusInterfaceMetaObject->indexOfSlot(charArg+1);
            if(index != -1) {
                qWarning("%s has index %d",charArg+1,index);
                QMetaMethod calledMethod = dbusInterfaceMetaObject->method(index);
                if(calledMethod.parameterNames().size() > 0) {
                    //gag for your arg beatch
                    queuedMethodIndex = index;
                } else {
                    calledMethod.invoke( &dbusInterface,
                            Qt::DirectConnection,
                            QGenericReturnArgument());

                    app.quit();
                    return 0;
                }
            } else {
                qWarning("Unknown argument %s", qPrintable(arg));
            }
        } else {
            if(queuedMethodIndex!=-1)
            {
                QMetaMethod calledMethod = dbusInterfaceMetaObject->method(queuedMethodIndex);
                calledMethod.invoke( &dbusInterface,
                        Qt::DirectConnection,
                        QGenericReturnArgument(),
                        Q_ARG(QString, arg));

                app.quit();
                return 0;
            }
            qWarning("%s doesn't seem to exist", qPrintable(arg));
            queuedMethodIndex = -1;
        }
    }
    Player player(&dbusInterface);
    if (!player.setSkin(Config::value<QString>("skin", QString(":/skins/dullSod")))) {
        const bool ret = player.setSkin(QLatin1String(":/skins/dullSod"));
        Q_ASSERT(ret);
        Q_UNUSED(ret);
    }
    player.show();
    return app.exec();
}
/*
   Donald Carr (sirspudd_at_gmail.com) plays songs occasionally
   Copyright (C) 2007 Donald Car

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation, Inc.,
   51 Franklin Street, Fifth Floor, Boston, MAction 02110-1301 USAction.
   */
<|endoftext|>


<commit_before>/** \copyright
 * Copyright (c) 2013, Balazs Racz
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are  permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file Notifiable.hxx
 * Basic building block of asynchronous operations: a zero-argument callback.
 *
 * @author Balazs Racz
 * @date 2 September 2013
 */

#ifndef _EXECUTOR_NOTIFIABLE_HXX_
#define _EXECUTOR_NOTIFIABLE_HXX_

#include "os/OS.hxx"
#include "utils/Atomic.hxx"

/// An object that can schedule itself on an executor to run.
class Notifiable
{
public:
    virtual void notify() = 0;
};

// A Notifiable for synchronously waiting for a notification.
// TODO(balazs.racz): We should make a syncnotifiable not need a semaphore
// of itself, but rather use a thread-local semaphore.
class SyncNotifiable : public Notifiable
{
public:
    SyncNotifiable() : sem_(0)
    {
    }

    virtual void notify()
    {
        sem_.post();
    }

    /* Blocks the current thread until the notification is delivered. */
    void wait_for_notification()
    {
        sem_.wait();
    }

private:
    OSSem sem_;

    DISALLOW_COPY_AND_ASSIGN(SyncNotifiable);
};

class EmptyNotifiable : public Notifiable
{
public:
    virtual void notify()
    {
    }

    static Notifiable* DefaultInstance();
};

// This notifiable will crash whenever called.
class CrashNotifiable : public Notifiable
{
public:
    virtual void notify();

    static Notifiable* DefaultInstance();
};

/** A class for reliably detecting whether a Notification has happened yet or
 * not.
 *
 * ProxyNotifiable can give a Notifiable callback, proxy to a parent Notifiable
 * any calls that may come in, and tell through {@link HasBeenNotified} whether
 * such a callback has happened yet or not.
 *
 */

class ProxyNotifiable : private Notifiable
{
public:
    ProxyNotifiable() : parent_(nullptr)
    {
    }
    /// Creates a new callback. When this callback is called, the parent
    /// notifiable is called and HasBeenNotified() will return true after that
    /// point. This function must not be called again until the returned
    // callback
    /// is invoked.
    //
    /// @returns a Notifiable to be used as a done callback for some
    // asynchronous
    /// processing.
    Notifiable* NewCallback(Notifiable* parent)
    {
        HASSERT(!parent_);
        parent_ = parent;
        return this;
    }
    /// @Returns true if the Notifiable returned by NewCallback has already been
    /// called.
    bool HasBeenNotified()
    {
        return !parent_;
    };

private:
    /// Implementation of the private Notifiable interface.
    virtual void notify()
    {
        Notifiable* p = parent_;
        HASSERT(p);
        parent_ = nullptr;
        p->notify();
    }

    Notifiable* parent_;
};

// A BarrierNotifiable allows to create a number of child Notifiable and wait
// for all of them to finish. When the last one is finished, the parent done
// callback is called.
class BarrierNotifiable : public Notifiable, private Atomic
{
public:
    /** Constructs a barrier notifiable that is done. Users should call reset()
     * later. */
    BarrierNotifiable() : count_(0), done_(nullptr)
    {
    }
    BarrierNotifiable(Notifiable* done) : count_(1), done_(done)
    {
    }

    // Resets the barrier. Returns &*this. Asserts that is_done().
    BarrierNotifiable* reset(Notifiable* done);

    ~BarrierNotifiable();

    // Call this for each child task.
    BarrierNotifiable* new_child();
    // When there are no more child tasks to add, call MaybeDone. Then once all
    // previously added child tasks are done, the parent callback will be
    // called. If you haven't added any children, this will call the parent
    // callback inline.
    void maybe_done()
    {
        notify();
    }
    virtual void notify();

    // Returns true if the barrier condition is true, i.e., the owner has clled
    // MaybeDone and all children have called Done.
    bool is_done()
    {
        return !count_;
    }

private:
    unsigned count_;
    Notifiable* done_;
};

inline BarrierNotifiable* NewBarrierNotifiable(Notifiable* done)
{
    return new BarrierNotifiable(done);
}

/** This class sends a notification in its destructor. Use as RAII class:
 *
 * bool DoFoo(Notifiable* done)
 * {
 *    AutoNotify n(done);
 *    // ... doo stuuufff ...
 *    if (something_wrong) return false;
 *    // do more stuff
 *    return true;
 * }
 *
 * The notification will be called on all return statements. */
class AutoNotify
{
public:
    AutoNotify(Notifiable* n) : n_(n)
    {
    }

    ~AutoNotify()
    {
        if (n_)
        {
            n_->notify();
        }
    }

    /* Transfers the ownership of the notification; it will NOT be called in
     * the destructor. The caller is now responsible for calling it.
     * @returns the notification pointer stored in the constructor. */
    Notifiable* Transfer()
    {
        Notifiable* r = n_;
        n_ = nullptr;
        return r;
    }

private:
    Notifiable* n_;
};

#define AutoNotify(l) int error_omitted_autonotify_holder_variable[-1]

#endif // _EXECUTOR_NOTIFIABLE_HXX_
<commit_msg>Adds notify_from_isr call to the Notifiable class under freertos.<commit_after>/** \copyright
 * Copyright (c) 2013, Balazs Racz
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are  permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file Notifiable.hxx
 * Basic building block of asynchronous operations: a zero-argument callback.
 *
 * @author Balazs Racz
 * @date 2 September 2013
 */

#ifndef _EXECUTOR_NOTIFIABLE_HXX_
#define _EXECUTOR_NOTIFIABLE_HXX_

#include "os/OS.hxx"
#include "utils/Atomic.hxx"

/// An object that can schedule itself on an executor to run.
class Notifiable
{
public:
    virtual void notify() = 0;
#ifdef __FreeRTOS__
    virtual void notify_from_isr()
    {
        DIE("Unexpected call to notify_from_isr.");
    }
#endif
};

// A Notifiable for synchronously waiting for a notification.
// TODO(balazs.racz): We should make a syncnotifiable not need a semaphore
// of itself, but rather use a thread-local semaphore.
class SyncNotifiable : public Notifiable
{
public:
    SyncNotifiable() : sem_(0)
    {
    }

    virtual void notify()
    {
        sem_.post();
    }

    /* Blocks the current thread until the notification is delivered. */
    void wait_for_notification()
    {
        sem_.wait();
    }

private:
    OSSem sem_;

    DISALLOW_COPY_AND_ASSIGN(SyncNotifiable);
};

class EmptyNotifiable : public Notifiable
{
public:
    virtual void notify()
    {
    }

    static Notifiable* DefaultInstance();
};

// This notifiable will crash whenever called.
class CrashNotifiable : public Notifiable
{
public:
    virtual void notify();

    static Notifiable* DefaultInstance();
};

/** A class for reliably detecting whether a Notification has happened yet or
 * not.
 *
 * ProxyNotifiable can give a Notifiable callback, proxy to a parent Notifiable
 * any calls that may come in, and tell through {@link HasBeenNotified} whether
 * such a callback has happened yet or not.
 *
 */

class ProxyNotifiable : private Notifiable
{
public:
    ProxyNotifiable() : parent_(nullptr)
    {
    }
    /// Creates a new callback. When this callback is called, the parent
    /// notifiable is called and HasBeenNotified() will return true after that
    /// point. This function must not be called again until the returned
    // callback
    /// is invoked.
    //
    /// @returns a Notifiable to be used as a done callback for some
    // asynchronous
    /// processing.
    Notifiable* NewCallback(Notifiable* parent)
    {
        HASSERT(!parent_);
        parent_ = parent;
        return this;
    }
    /// @Returns true if the Notifiable returned by NewCallback has already been
    /// called.
    bool HasBeenNotified()
    {
        return !parent_;
    };

private:
    /// Implementation of the private Notifiable interface.
    virtual void notify()
    {
        Notifiable* p = parent_;
        HASSERT(p);
        parent_ = nullptr;
        p->notify();
    }

    Notifiable* parent_;
};

// A BarrierNotifiable allows to create a number of child Notifiable and wait
// for all of them to finish. When the last one is finished, the parent done
// callback is called.
class BarrierNotifiable : public Notifiable, private Atomic
{
public:
    /** Constructs a barrier notifiable that is done. Users should call reset()
     * later. */
    BarrierNotifiable() : count_(0), done_(nullptr)
    {
    }
    BarrierNotifiable(Notifiable* done) : count_(1), done_(done)
    {
    }

    // Resets the barrier. Returns &*this. Asserts that is_done().
    BarrierNotifiable* reset(Notifiable* done);

    ~BarrierNotifiable();

    // Call this for each child task.
    BarrierNotifiable* new_child();
    // When there are no more child tasks to add, call MaybeDone. Then once all
    // previously added child tasks are done, the parent callback will be
    // called. If you haven't added any children, this will call the parent
    // callback inline.
    void maybe_done()
    {
        notify();
    }
    virtual void notify();

    // Returns true if the barrier condition is true, i.e., the owner has clled
    // MaybeDone and all children have called Done.
    bool is_done()
    {
        return !count_;
    }

private:
    unsigned count_;
    Notifiable* done_;
};

inline BarrierNotifiable* NewBarrierNotifiable(Notifiable* done)
{
    return new BarrierNotifiable(done);
}

/** This class sends a notification in its destructor. Use as RAII class:
 *
 * bool DoFoo(Notifiable* done)
 * {
 *    AutoNotify n(done);
 *    // ... doo stuuufff ...
 *    if (something_wrong) return false;
 *    // do more stuff
 *    return true;
 * }
 *
 * The notification will be called on all return statements. */
class AutoNotify
{
public:
    AutoNotify(Notifiable* n) : n_(n)
    {
    }

    ~AutoNotify()
    {
        if (n_)
        {
            n_->notify();
        }
    }

    /* Transfers the ownership of the notification; it will NOT be called in
     * the destructor. The caller is now responsible for calling it.
     * @returns the notification pointer stored in the constructor. */
    Notifiable* Transfer()
    {
        Notifiable* r = n_;
        n_ = nullptr;
        return r;
    }

private:
    Notifiable* n_;
};

#define AutoNotify(l) int error_omitted_autonotify_holder_variable[-1]

#endif // _EXECUTOR_NOTIFIABLE_HXX_
<|endoftext|>


<commit_before>#include "xcint.hpp"

static struct alias_data aliases_array[XC_MAX_ALIASES] =
{
  {"null","No functional",{{"slaterx",0.0}} },
  {"lda","Slater exchange and VWN5 correlation",{{"slaterx",1.0},{"vwn5c",1.0}} },
  {"blyp","Becke exchange and LYP correlation",{{"beckex",1.0},{"lypc",1.0}} },
  {"pbe","PBE exchange and correlation",{{"pbex",1.0},{"pbec",1.0}} },
  {"bp86","Becke-Perdew 1986",{{"beckex",1.0},{"p86c",1.0}} },
  {"kt1","Keal-Tozer 2",{{"slaterx",1.},{"ktx",-0.006},{"vwn5c",1.}} },
  {"kt2","Keal-Tozer 2",{{"slaterx",1.07173},{"ktx",-0.006},{"vwn5c",0.576727}} },
  {"kt3","Keal-Tozer 3",{{"slaterx",1.092},{"ktx",-0.004},{"optxcorr",-0.925452},{"lypc",0.864409}} },
  {"ldaerf","Short-range exchange and correlation LDA functional",{{"ldaerfx",1.0},{"ldaerfc",1.0}}},
  // Hybrid Functionals
  {"pbe0","Perdew-Burke-Ernzerhof",{{"pbex",0.75},{"pbec",1.0},{"exx",0.25}} },
  {"b3lyp","Becke-3-paramater-LYP (VWN5 form)", {{"slaterx",0.80},{"beckecorrx",0.72},{"lypc",0.81},{"vwn5c",0.19},{"exx",0.20}} },
  {"m06","M06", {{"m06c",1.0},{"m06x",1.0}} },
  {"m06-2x","M06 2X", {{"m06x2c",1.0},{"m06x2x",1.0}} },
  {"m06L","M06 L", {{"m06lc",1.0},{"m06lx",1.0}} },
  {"b3lyp-g","Becke-3-paramater-LYP (VWN3 form)", {{"slaterx",0.80},{"beckecorrx",0.72},{"lypc",0.81},{"vwn3c",0.19},{"exx",0.20}} },
  {"b3p86","Becke-3-paramater-LYP (VWN5 form)", {{"slaterx",0.80},{"beckecorrx",0.72},{"p86corrc",0.81},{"vwn5c",1.0},{"exx",0.20}} },
  {"b3p86-g","Becke-3-paramater-LYP (VWN3 form)", {{"slaterx",0.80},{"beckecorrx",0.72},{"p86corrc",0.81},{"vwn3c",1.0},{"exx",0.20}} },
  {"bpw91","Becke 88 exchange+PW91",{{"beckex",1.0},{"pw91c",1.0}} },
  {"b97","B97 exchange and correlation", {{"b97x",1.0},{"b97c",1.0},{"exx",0.1943}} },
  {"b97-1","B97-1 exchange and correlation", {{"b97_1x",1.0},{"b97_1c",1.0},{"exx",0.21}} },
  {"b97_2","B97-2 exchange and correlation", {{"b97_2x",1.0},{"b97_2c",1.0},{"exx",0.21}} },
  {"camb3lyp","CAM-B3LYP",{{"cam_alpha",0.19},{"cam_beta",0.46},{"rangesep_mu",0.33},{"beckecamx",1.0},{"vwn5c",0.19},{"lypc",0.81},{"exx",1.0}} },
  // Some of these are there to match the names used in Dalton
  {"vwn","VWN5 correlation",{{"vwn5c",1.0}}},
  {"vwn5","VWN5 correlation",{{"vwn5c",1.0}}},
  {"vwn3","VWN5 correlation",{{"vwn3c",1.0}}},
  {"svwn","Slater exchange and VWN5 correlation",{{"slaterx",1.0},{"vwn5c",1.0}} },
  {"svwn5","Slater exchange and VWN5 correlation",{{"slaterx",1.0},{"vwn5c",1.0}} },
  {"svwn3","Slater exchange and VWN3 correlation",{{"slaterx",1.0},{"vwn3c",1.0}} },
  {"becke","Becke exchange",{{"beckecorrx",1.0}}},
  {"slater","Slater exchange",{{"slaterx",1.0}}},
  {"olyp","LYP correlation and OPTX exchange",{{"lypc",1.0},{"optx",1.0}}},
  {"lyp","LYP correlation",{{"lypc",1.0}}},
  // ADMM exchange funtional corrections
  {"B88X","Becke exchange",{{"slaterx",1.},{"beckecorrx",1.0}} },
  {"LDAX","Slater exchange",{{"slaterx",1.}} },
  {"PBEX","PBE exchange",{{"pbex",1.0}} },
  {"KT3X","Keal-Tozer 3 exchange",{{"slaterx",1.092},{"ktx",-0.004},{"optxcorr",-0.925452}} },
  {"OPTX","OptX exchange",{{"slaterx",1.05151},{"optxcorr",-1.43169}} },
  {"camcompx","Complementary part of CAM exchange",{{"beckex",1.0},{"beckecamx",-1.0}} },
};

struct alias_data *xcint_aliases = aliases_array;
<commit_msg>More camcompx.<commit_after>#include "xcint.hpp"

static struct alias_data aliases_array[XC_MAX_ALIASES] =
{
  {"null","No functional",{{"slaterx",0.0}} },
  {"lda","Slater exchange and VWN5 correlation",{{"slaterx",1.0},{"vwn5c",1.0}} },
  {"blyp","Becke exchange and LYP correlation",{{"beckex",1.0},{"lypc",1.0}} },
  {"pbe","PBE exchange and correlation",{{"pbex",1.0},{"pbec",1.0}} },
  {"bp86","Becke-Perdew 1986",{{"beckex",1.0},{"p86c",1.0}} },
  {"kt1","Keal-Tozer 2",{{"slaterx",1.},{"ktx",-0.006},{"vwn5c",1.}} },
  {"kt2","Keal-Tozer 2",{{"slaterx",1.07173},{"ktx",-0.006},{"vwn5c",0.576727}} },
  {"kt3","Keal-Tozer 3",{{"slaterx",1.092},{"ktx",-0.004},{"optxcorr",-0.925452},{"lypc",0.864409}} },
  {"ldaerf","Short-range exchange and correlation LDA functional",{{"ldaerfx",1.0},{"ldaerfc",1.0}}},
  // Hybrid Functionals
  {"pbe0","Perdew-Burke-Ernzerhof",{{"pbex",0.75},{"pbec",1.0},{"exx",0.25}} },
  {"b3lyp","Becke-3-paramater-LYP (VWN5 form)", {{"slaterx",0.80},{"beckecorrx",0.72},{"lypc",0.81},{"vwn5c",0.19},{"exx",0.20}} },
  {"m06","M06", {{"m06c",1.0},{"m06x",1.0}} },
  {"m06-2x","M06 2X", {{"m06x2c",1.0},{"m06x2x",1.0}} },
  {"m06L","M06 L", {{"m06lc",1.0},{"m06lx",1.0}} },
  {"b3lyp-g","Becke-3-paramater-LYP (VWN3 form)", {{"slaterx",0.80},{"beckecorrx",0.72},{"lypc",0.81},{"vwn3c",0.19},{"exx",0.20}} },
  {"b3p86","Becke-3-paramater-LYP (VWN5 form)", {{"slaterx",0.80},{"beckecorrx",0.72},{"p86corrc",0.81},{"vwn5c",1.0},{"exx",0.20}} },
  {"b3p86-g","Becke-3-paramater-LYP (VWN3 form)", {{"slaterx",0.80},{"beckecorrx",0.72},{"p86corrc",0.81},{"vwn3c",1.0},{"exx",0.20}} },
  {"bpw91","Becke 88 exchange+PW91",{{"beckex",1.0},{"pw91c",1.0}} },
  {"b97","B97 exchange and correlation", {{"b97x",1.0},{"b97c",1.0},{"exx",0.1943}} },
  {"b97-1","B97-1 exchange and correlation", {{"b97_1x",1.0},{"b97_1c",1.0},{"exx",0.21}} },
  {"b97_2","B97-2 exchange and correlation", {{"b97_2x",1.0},{"b97_2c",1.0},{"exx",0.21}} },
  {"camb3lyp","CAM-B3LYP",{{"cam_alpha",0.19},{"cam_beta",0.46},{"rangesep_mu",0.33},{"beckecamx",1.0},{"vwn5c",0.19},{"lypc",0.81},{"exx",1.0}} },
  // Some of these are there to match the names used in Dalton
  {"vwn","VWN5 correlation",{{"vwn5c",1.0}}},
  {"vwn5","VWN5 correlation",{{"vwn5c",1.0}}},
  {"vwn3","VWN5 correlation",{{"vwn3c",1.0}}},
  {"svwn","Slater exchange and VWN5 correlation",{{"slaterx",1.0},{"vwn5c",1.0}} },
  {"svwn5","Slater exchange and VWN5 correlation",{{"slaterx",1.0},{"vwn5c",1.0}} },
  {"svwn3","Slater exchange and VWN3 correlation",{{"slaterx",1.0},{"vwn3c",1.0}} },
  {"becke","Becke exchange",{{"beckecorrx",1.0}}},
  {"slater","Slater exchange",{{"slaterx",1.0}}},
  {"olyp","LYP correlation and OPTX exchange",{{"lypc",1.0},{"optx",1.0}}},
  {"lyp","LYP correlation",{{"lypc",1.0}}},
  // ADMM exchange funtional corrections
  {"B88X","Becke exchange",{{"slaterx",1.},{"beckecorrx",1.0}} },
  {"LDAX","Slater exchange",{{"slaterx",1.}} },
  {"PBEX","PBE exchange",{{"pbex",1.0}} },
  {"KT3X","Keal-Tozer 3 exchange",{{"slaterx",1.092},{"ktx",-0.004},{"optxcorr",-0.925452}} },
  {"OPTX","OptX exchange",{{"slaterx",1.05151},{"optxcorr",-1.43169}} },
  {"camcompx","Complementary part of CAM exchange",{{"beckex",1.0},{"beckecamx",-1.0},{"cam_alpha",0.19},
						    {"cam_beta",0.46},{"rangesep_mu",0.33}}},
};

struct alias_data *xcint_aliases = aliases_array;
<|endoftext|>


<commit_before>#include "game/deploymentzone.hpp"

#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Graphics/RenderTarget.hpp>

#include "game/renderlayers.hpp"

namespace qrw
{

DeploymentZone::DeploymentZone()
    : Renderable(RENDER_LAYER_DEPLOYMENT_ZONE),
      color_(sf::Color::Green)
{
}

DeploymentZone::~DeploymentZone()
{
}

void DeploymentZone::render(sf::RenderTarget& renderTarget)
{
    sf::RectangleShape rectangle;
    rectangle.setSize({32, 32});
    rectangle.setFillColor(color_);

    for(auto& coordinate : zone_)
    {
        rectangle.setPosition({32 * coordinate.getX(), 32 * coordinate.getY()});
        renderTarget.draw(rectangle);
    }
}

void DeploymentZone::setPosition(const sf::Vector2f& position)
{
    position_ = position;
}

const sf::Vector2f& DeploymentZone::getPosition() const
{
    return position_;
}

void DeploymentZone::setColor(const sf::Color& color)
{
    color_ = color;
}

void DeploymentZone::addSquare(const Coordinates& coordinate)
{
    zone_.insert(coordinate);
}

void DeploymentZone::removeSquare(const Coordinates& coordinate)
{
    zone_.erase(coordinate);
}

bool DeploymentZone::containsSquare(const Coordinates& coordinate)
{
    return zone_.find(coordinate) != zone_.end();
}

} // namespace qrw
<commit_msg>Fix compiler warning<commit_after>#include "game/deploymentzone.hpp"

#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Graphics/RenderTarget.hpp>

#include "game/renderlayers.hpp"

namespace qrw
{

DeploymentZone::DeploymentZone()
    : Renderable(RENDER_LAYER_DEPLOYMENT_ZONE),
      color_(sf::Color::Green)
{
}

DeploymentZone::~DeploymentZone()
{
}

void DeploymentZone::render(sf::RenderTarget& renderTarget)
{
    sf::RectangleShape rectangle;
    rectangle.setSize({32, 32});
    rectangle.setFillColor(color_);

    for(auto& coordinate : zone_)
    {
        rectangle.setPosition({32.0f * coordinate.getX(), 32.0f * coordinate.getY()});
        renderTarget.draw(rectangle);
    }
}

void DeploymentZone::setPosition(const sf::Vector2f& position)
{
    position_ = position;
}

const sf::Vector2f& DeploymentZone::getPosition() const
{
    return position_;
}

void DeploymentZone::setColor(const sf::Color& color)
{
    color_ = color;
}

void DeploymentZone::addSquare(const Coordinates& coordinate)
{
    zone_.insert(coordinate);
}

void DeploymentZone::removeSquare(const Coordinates& coordinate)
{
    zone_.erase(coordinate);
}

bool DeploymentZone::containsSquare(const Coordinates& coordinate)
{
    return zone_.find(coordinate) != zone_.end();
}

} // namespace qrw
<|endoftext|>


<commit_before>#ifdef HAVE_CMAKE_CONFIG
#include "cmake_config.h"
#elif defined(HAVE_CONFIG_H)
#include "config.h"
#endif

#define HAVE_DUNE_DETAILED_DISCRETIZATIONS 1

#include <iostream>
#include <sstream>
#include <vector>

#include <boost/filesystem.hpp>

#include <dune/common/exceptions.hh>
#include <dune/common/static_assert.hh>
#include <dune/common/timer.hh>
#include <dune/common/dynvector.hh>

#include <dune/grid/io/file/vtk/vtkwriter.hh>

#include <dune/grid/part/leaf.hh>

#include <dune/fem/misc/mpimanager.hh>
#include <dune/fem/space/common/functionspace.hh>

#include <dune/stuff/common/parameter/tree.hh>
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/grid/provider.hh>
#include <dune/stuff/grid/boundaryinfo.hh>
#include <dune/stuff/function/expression.hh>
#include <dune/stuff/la/solver.hh>
#include <dune/stuff/discretefunction/projection/dirichlet.hh>

#include <dune/detailed/discretizations/space/continuouslagrange/fem.hh>
#include <dune/detailed/discretizations/la/containerfactory/eigen.hh>
#include <dune/detailed/discretizations/evaluation/elliptic.hh>
#include <dune/detailed/discretizations/evaluation/product.hh>
#include <dune/detailed/discretizations/localoperator/codim0.hh>
#include <dune/detailed/discretizations/localfunctional/codim0.hh>
#include <dune/detailed/discretizations/assembler/local/codim0.hh>
#include <dune/detailed/discretizations/space/constraints.hh>
#include <dune/detailed/discretizations/assembler/system.hh>
#include <dune/detailed/discretizations/discretefunction/default.hh>

const std::string id = "elliptic.continuousgalerkin";

#ifndef POLORDER
const int polOrder = 1;
#else
const int polOrder = POLORDER;
#endif
dune_static_assert((polOrder > 0), "ERROR: polOrder hast to be positive!");

using namespace Dune::Detailed::Discretizations;

/**
  \brief      Creates a parameter file if it does not exist.

              Nothing is done if the file already exists. If not, a parameter file will be created with all neccessary
              keys and values.
  \param[in]  filename
              (Relative) path to the file.
  **/
void ensureParamFile(const std::string& filename)
{
  // only write param file if there is none
  if (!boost::filesystem::exists(filename)) {
    std::ofstream file;
    file.open(filename);
    file << "[" << id << "]" << std::endl;
    file << "filename = " << id << std::endl;
    file << "grid = "
         << "gridprovider.cube" << std::endl;
    file << "boundaryinfo = "
         << "boundaryinfo.alldirichlet" << std::endl;
    file << "[gridprovider.cube]" << std::endl;
    file << "lowerLeft = [0.0; 0.0; 0.0]" << std::endl;
    file << "upperRight = [1.0; 1.0; 1.0]" << std::endl;
    file << "numElements = [12; 12; 12]" << std::endl;
    file << "[boundaryinfo.idbased]" << std::endl;
    file << "dirichlet = [1; 2; 3]" << std::endl;
    file << "neumann = [4]" << std::endl;
    file << "[diffusion]" << std::endl;
    file << "order = 0" << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 1.0; 1.0]" << std::endl;
    file << "[force]" << std::endl;
    file << "order = 0" << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 1.0; 1.0]" << std::endl;
    file << "[dirichlet]" << std::endl;
    file << "order = 0" << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [0.1*x[0]; 0.0; 0.0]" << std::endl;
    file << "[neumann]" << std::endl;
    file << "order = 0" << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 0.0; 0.0]" << std::endl;
    file << "[solver]" << std::endl;
    file << "type = bicgstab.ilut" << std::endl;
    file << "maxIter = 5000" << std::endl;
    file << "precision = 1e-12" << std::endl;
    file.close();
  } // only write param file if there is none
} // void ensureParamFile()

int main(int argc, char** argv)
{
  try {
    // mpi
    Dune::Fem::MPIManager::initialize(argc, argv);

    // parameter
    const std::string paramFilename = id + ".description";
    ensureParamFile(paramFilename);
    Dune::Stuff::Common::ExtendedParameterTree description(argc, argv, paramFilename);
    description.assertSub(id);

    // logger
    Dune::Stuff::Common::Logger().create(Dune::Stuff::Common::LOG_INFO | Dune::Stuff::Common::LOG_CONSOLE);
    Dune::Stuff::Common::LogStream& info = Dune::Stuff::Common::Logger().info();

    // timer
    Dune::Timer timer;

    info << "setting up grid:" << std::endl;
    typedef Dune::Stuff::GridProviderInterface<> GridProviderType;
    const GridProviderType* gridProvider =
        Dune::Stuff::GridProviders<>::create(description.get(id + ".grid", "gridprovider.cube"), description);
    typedef GridProviderType::GridType GridType;
    const std::shared_ptr<const GridType> grid = gridProvider->grid();
    typedef Dune::grid::Part::Leaf::Const<GridType> GridPartType;
    typedef typename GridPartType::GridViewType GridViewType;
    const GridPartType gridPart(*grid);
    typedef typename Dune::Stuff::GridboundaryInterface<typename GridPartType::GridViewType> BoundaryInfoType;
    const std::shared_ptr<const BoundaryInfoType> boundaryInfo(
        Dune::Stuff::Gridboundaries<typename GridPartType::GridViewType>::create(
            description.get(id + ".boundaryinfo", "boundaryinfo.alldirichlet"), description));
    info << "  took " << timer.elapsed() << " sec, has " << grid->size(0) << " entities" << std::endl;
    info << "visualizing grid... " << std::flush;
    timer.reset();
    gridProvider->visualize(description.get(id + ".boundaryinfo", "boundaryinfo.alldirichlet"),
                            description,
                            description.get(id + ".filename", id) + ".grid");
    info << " done (took " << timer.elapsed() << " sek)" << std::endl;

    const unsigned int DUNE_UNUSED(dimDomain) = GridProviderType::dim;
    const unsigned int DUNE_UNUSED(dimRange) = 1;
    typedef typename GridType::ctype DomainFieldType;
    typedef double RangeFieldType;

    typedef Dune::Stuff::FunctionExpression<DomainFieldType, dimDomain, RangeFieldType, dimRange>
        ExpressionFunctionType;
    const std::shared_ptr<const ExpressionFunctionType> diffusion(
        ExpressionFunctionType::create(description.sub("diffusion")));
    const std::shared_ptr<const ExpressionFunctionType> force(ExpressionFunctionType::create(description.sub("force")));
    const std::shared_ptr<const ExpressionFunctionType> dirichlet(
        ExpressionFunctionType::create(description.sub("dirichlet")));
    const std::shared_ptr<const ExpressionFunctionType> neumann(
        ExpressionFunctionType::create(description.sub("neumann")));

    // info << "initializing discrete function spaces... " << std::flush;
    // timer.reset();
    typedef ContinuousLagrangeSpace::FemWrapper<GridPartType, polOrder, RangeFieldType, dimRange> SpaceType;
    const SpaceType space(gridPart);

    // left hand side
    // * elliptic diffusion operator
    typedef EvaluationElliptic<DomainFieldType, dimDomain, RangeFieldType, dimRange> EllipticEvaluationType;
    typedef LocalOperatorCodim0Integral<EllipticEvaluationType, ExpressionFunctionType> EllipticOperatorType;
    const EllipticOperatorType diffusionOperator(*diffusion);
    // * right hand side
    //   * L2 force functional
    typedef EvaluationProduct<DomainFieldType, dimDomain, RangeFieldType, dimRange> ProductEvaluationType;
    typedef LocalFunctionalCodim0Integral<ProductEvaluationType, ExpressionFunctionType> L2FunctionalType;
    const L2FunctionalType forceFunctional(*force);
    //   * L2 neumann functional
    const L2FunctionalType neumannFunctional(*neumann);

    info << "initializing matrix (of size " << space.mapper().size() << "x" << space.mapper().size()
         << ") and vectors... " << std::flush;
    // timer.reset();
    typedef ContainerFactoryEigen<RangeFieldType> ContainerFactory;
    typedef ContainerFactory::RowMajorSparseMatrixType MatrixType;
    typedef ContainerFactory::DenseVectorType VectorType;
    std::shared_ptr<MatrixType> systemMatrix(ContainerFactory::createRowMajorSparseMatrix(space, space));
    std::shared_ptr<VectorType> forceVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr<VectorType> dirichletVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr<VectorType> neumannVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr<VectorType> rhsVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr<VectorType> solutionVector(ContainerFactory::createDenseVector(space));
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "assembing system... " << std::flush;
    timer.reset();
    // * dirichlet boundary values
    typedef DiscreteFunctionDefault<SpaceType, VectorType> DiscreteFunctionType;
    DiscreteFunctionType dirichletProjection(space, dirichletVector, "dirichlet");
    Dune::Stuff::DiscreteFunction::project(*boundaryInfo, *dirichlet, dirichletProjection);

    // * local matrix assembler
    typedef LocalAssemblerCodim0Matrix<EllipticOperatorType> LocalEllipticOperatorMatrixAssemblerType;
    const LocalEllipticOperatorMatrixAssemblerType diffusionMatrixAssembler(diffusionOperator);
    // * local vector assemblers
    typedef LocalAssemblerCodim0Vector<L2FunctionalType> LocalL2FunctionalVectorAssemblerType;
    //   * force vector
    const LocalL2FunctionalVectorAssemblerType forceVectorAssembler(forceFunctional);
    //   * neumann vector
    const LocalL2FunctionalVectorAssemblerType neumannVectorAssembler(neumannFunctional);
    // * system assembler
    typedef SystemAssembler<SpaceType, SpaceType> SystemAssemblerType;
    SystemAssemblerType systemAssembler(space);
    systemAssembler.addLocalMatrixAssembler(diffusionMatrixAssembler, *systemMatrix);
    systemAssembler.addLocalVectorAssembler(forceVectorAssembler, *forceVector);
    systemAssembler.addLocalVectorAssembler(neumannVectorAssembler, *neumannVector);
    systemAssembler.assemble();
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "applying constraints... " << std::flush;
    timer.reset();
    Constraints::Dirichlet<GridViewType, RangeFieldType> dirichletConstraints(
        *boundaryInfo, space.mapper().maxNumDofs(), space.mapper().maxNumDofs());
    rhsVector->backend() =
        forceVector->backend() + neumannVector->backend() - systemMatrix->backend() * dirichletVector->backend();
    systemAssembler.applyConstraints(dirichletConstraints, *systemMatrix, *rhsVector);
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "solving linear system (of size " << systemMatrix->rows() << "x" << systemMatrix->cols() << ")"
         << std::endl;
    const std::string solverType     = description.get("solver.type", "bicgstab");
    const unsigned int solverMaxIter = description.get("solver.maxIter", 5000);
    const double solverPrecision     = description.get("solver.precision", 1e-12);
    info << "  using '" << solverType << "'... " << std::flush;
    timer.reset();
    typedef typename Dune::Stuff::LA::Solver::Interface<MatrixType, VectorType> SolverType;
    std::shared_ptr<SolverType> solver(Dune::Stuff::LA::Solver::create<MatrixType, VectorType>(solverType));
    const unsigned int failure =
        solver->apply(*systemMatrix, *rhsVector, *solutionVector, solverMaxIter, solverPrecision);
    if (failure)
      DUNE_THROW(Dune::MathError, "\nERROR: linear solver '" << solverType << "' reported a problem!");
    if (solutionVector->size() != space.mapper().size())
      DUNE_THROW(Dune::MathError,
                 "\nERROR: linear solver '" << solverType << "' produced a solution of wrong size (is "
                                            << solutionVector->size()
                                            << ", should be "
                                            << space.mapper().size()
                                            << ")!");
    solutionVector->backend() += dirichletVector->backend();
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    const std::string solutionFilename = description.get(id + ".filename", id) + ".solution";
    const std::string solutionName     = id + ".solution";
    info << "writing solution to '" << solutionFilename;
    if (dimDomain == 1)
      info << ".vtp";
    else
      info << ".vtu";
    info << "'... " << std::flush;
    timer.reset();
    typedef DiscreteFunctionDefaultConst<SpaceType, VectorType> ConstDiscreteFunctionType;
    const std::shared_ptr<const ConstDiscreteFunctionType> solution(
        new ConstDiscreteFunctionType(space, solutionVector, solutionName));
    typedef Dune::VTKWriter<GridViewType> VTKWriterType;
    VTKWriterType vtkWriter(gridPart.gridView());
    vtkWriter.addVertexData(solution);
    vtkWriter.write(solutionFilename);
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // done
    return 0;
  } catch (Dune::Exception& e) {
    std::cerr << "Dune reported error: " << e.what() << std::endl;
  } catch (std::exception& e) {
    std::cerr << e.what() << std::endl;
  } catch (...) {
    std::cerr << "Unknown exception thrown!" << std::endl;
  } // try
} // main
<commit_msg>[examples.elliptic.continuousgalerkin] update<commit_after>#ifdef HAVE_CMAKE_CONFIG
#include "cmake_config.h"
#elif defined(HAVE_CONFIG_H)
#include "config.h"
#endif

#define HAVE_DUNE_DETAILED_DISCRETIZATIONS 1

#include <iostream>
#include <sstream>
#include <vector>

#include <boost/filesystem.hpp>

#include <dune/common/exceptions.hh>
#include <dune/common/static_assert.hh>
#include <dune/common/timer.hh>
#include <dune/common/dynvector.hh>

#include <dune/grid/io/file/vtk/vtkwriter.hh>

#include <dune/grid/part/leaf.hh>

#include <dune/fem/misc/mpimanager.hh>
#include <dune/fem/space/common/functionspace.hh>

#include <dune/stuff/common/parameter/tree.hh>
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/grid/provider.hh>
#include <dune/stuff/grid/boundaryinfo.hh>
#include <dune/stuff/function/expression.hh>
#include <dune/stuff/la/solver.hh>
#include <dune/stuff/discretefunction/projection/dirichlet.hh>

#include <dune/detailed/discretizations/space/continuouslagrange/fem.hh>
#include <dune/detailed/discretizations/la/containerfactory/eigen.hh>
#include <dune/detailed/discretizations/evaluation/elliptic.hh>
#include <dune/detailed/discretizations/evaluation/product.hh>
#include <dune/detailed/discretizations/localoperator/codim0.hh>
#include <dune/detailed/discretizations/localfunctional/codim0.hh>
#include <dune/detailed/discretizations/assembler/local/codim0.hh>
#include <dune/detailed/discretizations/space/constraints.hh>
#include <dune/detailed/discretizations/assembler/system.hh>
#include <dune/detailed/discretizations/discretefunction/default.hh>

const std::string id = "elliptic.continuousgalerkin";

#ifndef POLORDER
const int polOrder = 1;
#else
const int polOrder = POLORDER;
#endif
dune_static_assert((polOrder > 0), "ERROR: polOrder hast to be positive!");

using namespace Dune::Detailed::Discretizations;

/**
  \brief      Creates a parameter file if it does not exist.

              Nothing is done if the file already exists. If not, a parameter file will be created with all neccessary
              keys and values.
  \param[in]  filename
              (Relative) path to the file.
  **/
void ensureParamFile(const std::string& filename)
{
  // only write param file if there is none
  if (!boost::filesystem::exists(filename)) {
    std::ofstream file;
    file.open(filename);
    file << "[" << id << "]" << std::endl;
    file << "filename = " << id << std::endl;
    file << "grid = "
         << "gridprovider.cube" << std::endl;
    file << "boundaryinfo = "
         << "boundaryinfo.alldirichlet" << std::endl;
    file << "[gridprovider.cube]" << std::endl;
    file << "lowerLeft = [0.0; 0.0; 0.0]" << std::endl;
    file << "upperRight = [1.0; 1.0; 1.0]" << std::endl;
    file << "numElements = [12; 12; 12]" << std::endl;
    file << "[boundaryinfo.idbased]" << std::endl;
    file << "dirichlet = [1; 2; 3]" << std::endl;
    file << "neumann = [4]" << std::endl;
    file << "[diffusion]" << std::endl;
    file << "order = 0" << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 1.0; 1.0]" << std::endl;
    file << "[force]" << std::endl;
    file << "order = 0" << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 1.0; 1.0]" << std::endl;
    file << "[dirichlet]" << std::endl;
    file << "order = 0" << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [0.1*x[0]; 0.0; 0.0]" << std::endl;
    file << "[neumann]" << std::endl;
    file << "order = 0" << std::endl;
    file << "variable = x" << std::endl;
    file << "expression = [1.0; 0.0; 0.0]" << std::endl;
    file << "[solver]" << std::endl;
    file << "type = bicgstab.ilut" << std::endl;
    file << "maxIter = 5000" << std::endl;
    file << "precision = 1e-12" << std::endl;
    file.close();
  } // only write param file if there is none
} // void ensureParamFile()

int main(int argc, char** argv)
{
  try {
    // mpi
    Dune::Fem::MPIManager::initialize(argc, argv);

    // parameter
    const std::string paramFilename = id + ".description";
    ensureParamFile(paramFilename);
    Dune::Stuff::Common::ExtendedParameterTree description(argc, argv, paramFilename);
    description.assertSub(id);

    // logger
    Dune::Stuff::Common::Logger().create(Dune::Stuff::Common::LOG_INFO | Dune::Stuff::Common::LOG_CONSOLE);
    Dune::Stuff::Common::LogStream& info = Dune::Stuff::Common::Logger().info();

    // timer
    Dune::Timer timer;

    info << "setting up grid:" << std::endl;
    typedef Dune::Stuff::GridProviderInterface<> GridProviderType;
    const GridProviderType* gridProvider =
        Dune::Stuff::GridProviders<>::create(description.get(id + ".grid", "gridprovider.cube"), description);
    typedef GridProviderType::GridType GridType;
    const std::shared_ptr<const GridType> grid = gridProvider->grid();
    typedef Dune::grid::Part::Leaf::Const<GridType> GridPartType;
    typedef typename GridPartType::GridViewType GridViewType;
    const GridPartType gridPart(*grid);
    typedef typename Dune::Stuff::GridboundaryInterface<typename GridPartType::GridViewType> BoundaryInfoType;
    const std::shared_ptr<const BoundaryInfoType> boundaryInfo(
        Dune::Stuff::Gridboundaries<typename GridPartType::GridViewType>::create(
            description.get(id + ".boundaryinfo", "boundaryinfo.alldirichlet"), description));
    info << "  took " << timer.elapsed() << " sec, has " << grid->size(0) << " entities" << std::endl;
    info << "visualizing grid... " << std::flush;
    timer.reset();
    gridProvider->visualize(description.get(id + ".boundaryinfo", "boundaryinfo.alldirichlet"),
                            description,
                            description.get(id + ".filename", id) + ".grid");
    info << " done (took " << timer.elapsed() << " sek)" << std::endl;

    const unsigned int DUNE_UNUSED(dimDomain) = GridProviderType::dim;
    const unsigned int DUNE_UNUSED(dimRange) = 1;
    typedef typename GridType::ctype DomainFieldType;
    typedef double RangeFieldType;

    typedef Dune::Stuff::FunctionExpression<DomainFieldType, dimDomain, RangeFieldType, dimRange>
        ExpressionFunctionType;
    const std::shared_ptr<const ExpressionFunctionType> diffusion(
        ExpressionFunctionType::create(description.sub("diffusion")));
    const std::shared_ptr<const ExpressionFunctionType> force(ExpressionFunctionType::create(description.sub("force")));
    const std::shared_ptr<const ExpressionFunctionType> dirichlet(
        ExpressionFunctionType::create(description.sub("dirichlet")));
    const std::shared_ptr<const ExpressionFunctionType> neumann(
        ExpressionFunctionType::create(description.sub("neumann")));

    // info << "initializing discrete function spaces... " << std::flush;
    // timer.reset();
    typedef ContinuousLagrangeSpace::FemWrapper<GridPartType, polOrder, RangeFieldType, dimRange> SpaceType;
    const SpaceType space(gridPart);

    // left hand side
    // * elliptic diffusion operator
    typedef LocalOperatorCodim0Integral<Evaluation::Elliptic, ExpressionFunctionType> EllipticOperatorType;
    const EllipticOperatorType diffusionOperator(*diffusion);
    // * right hand side
    //   * L2 force functional
    typedef LocalFunctionalCodim0Integral<Evaluation::Product, ExpressionFunctionType> L2FunctionalType;
    const L2FunctionalType forceFunctional(*force);
    //   * L2 neumann functional
    const L2FunctionalType neumannFunctional(*neumann);

    info << "initializing matrix (of size " << space.mapper().size() << "x" << space.mapper().size()
         << ") and vectors... " << std::flush;
    // timer.reset();
    typedef ContainerFactoryEigen<RangeFieldType> ContainerFactory;
    typedef ContainerFactory::RowMajorSparseMatrixType MatrixType;
    typedef ContainerFactory::DenseVectorType VectorType;
    std::shared_ptr<MatrixType> systemMatrix(ContainerFactory::createRowMajorSparseMatrix(space, space));
    std::shared_ptr<VectorType> forceVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr<VectorType> dirichletVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr<VectorType> neumannVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr<VectorType> rhsVector(ContainerFactory::createDenseVector(space));
    std::shared_ptr<VectorType> solutionVector(ContainerFactory::createDenseVector(space));
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "assembing system... " << std::flush;
    timer.reset();
    // * dirichlet boundary values
    typedef DiscreteFunctionDefault<SpaceType, VectorType> DiscreteFunctionType;
    DiscreteFunctionType dirichletProjection(space, dirichletVector, "dirichlet");
    Dune::Stuff::DiscreteFunction::project(*boundaryInfo, *dirichlet, dirichletProjection);

    // * local matrix assembler
    typedef LocalAssemblerCodim0Matrix<EllipticOperatorType> LocalEllipticOperatorMatrixAssemblerType;
    const LocalEllipticOperatorMatrixAssemblerType diffusionMatrixAssembler(diffusionOperator);
    // * local vector assemblers
    typedef LocalAssemblerCodim0Vector<L2FunctionalType> LocalL2FunctionalVectorAssemblerType;
    //   * force vector
    const LocalL2FunctionalVectorAssemblerType forceVectorAssembler(forceFunctional);
    //   * neumann vector
    const LocalL2FunctionalVectorAssemblerType neumannVectorAssembler(neumannFunctional);
    // * system assembler
    typedef SystemAssembler<SpaceType, SpaceType> SystemAssemblerType;
    SystemAssemblerType systemAssembler(space);
    systemAssembler.addLocalMatrixAssembler(diffusionMatrixAssembler, *systemMatrix);
    systemAssembler.addLocalVectorAssembler(forceVectorAssembler, *forceVector);
    systemAssembler.addLocalVectorAssembler(neumannVectorAssembler, *neumannVector);
    systemAssembler.assemble();
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "applying constraints... " << std::flush;
    timer.reset();
    Constraints::Dirichlet<GridViewType, RangeFieldType> dirichletConstraints(
        *boundaryInfo, space.mapper().maxNumDofs(), space.mapper().maxNumDofs());
    rhsVector->backend() =
        forceVector->backend() + neumannVector->backend() - systemMatrix->backend() * dirichletVector->backend();
    systemAssembler.applyConstraints(dirichletConstraints, *systemMatrix, *rhsVector);
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "solving linear system (of size " << systemMatrix->rows() << "x" << systemMatrix->cols() << ")"
         << std::endl;
    const std::string solverType     = description.get("solver.type", "bicgstab");
    const unsigned int solverMaxIter = description.get("solver.maxIter", 5000);
    const double solverPrecision     = description.get("solver.precision", 1e-12);
    info << "  using '" << solverType << "'... " << std::flush;
    timer.reset();
    typedef typename Dune::Stuff::LA::Solver::Interface<MatrixType, VectorType> SolverType;
    std::shared_ptr<SolverType> solver(Dune::Stuff::LA::Solver::create<MatrixType, VectorType>(solverType));
    const unsigned int failure =
        solver->apply(*systemMatrix, *rhsVector, *solutionVector, solverMaxIter, solverPrecision);
    if (failure)
      DUNE_THROW(Dune::MathError, "\nERROR: linear solver '" << solverType << "' reported a problem!");
    if (solutionVector->size() != space.mapper().size())
      DUNE_THROW(Dune::MathError,
                 "\nERROR: linear solver '" << solverType << "' produced a solution of wrong size (is "
                                            << solutionVector->size()
                                            << ", should be "
                                            << space.mapper().size()
                                            << ")!");
    solutionVector->backend() += dirichletVector->backend();
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    const std::string solutionFilename = description.get(id + ".filename", id) + ".solution";
    const std::string solutionName     = id + ".solution";
    info << "writing solution to '" << solutionFilename;
    if (dimDomain == 1)
      info << ".vtp";
    else
      info << ".vtu";
    info << "'... " << std::flush;
    timer.reset();
    typedef DiscreteFunctionDefaultConst<SpaceType, VectorType> ConstDiscreteFunctionType;
    const std::shared_ptr<const ConstDiscreteFunctionType> solution(
        new ConstDiscreteFunctionType(space, solutionVector, solutionName));
    typedef Dune::VTKWriter<GridViewType> VTKWriterType;
    VTKWriterType vtkWriter(gridPart.gridView());
    vtkWriter.addVertexData(solution);
    vtkWriter.write(solutionFilename);
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    // done
    return 0;
  } catch (Dune::Exception& e) {
    std::cerr << "Dune reported error: " << e.what() << std::endl;
  } catch (std::exception& e) {
    std::cerr << e.what() << std::endl;
  } catch (...) {
    std::cerr << "Unknown exception thrown!" << std::endl;
  } // try
} // main
<|endoftext|>


<commit_before>#include "point.hpp"

#include <ostream>

namespace algorithms {

    bool operator<(const Point &a, const Point &b) {
        return a.x < b.x || (a.x == b.x && a.y < b.y);
    }

    bool operator==(const Point &a, const Point &b) {
        return a.x == b.x && a.y == b.y;
    }

    std::ostream &operator<<(std::ostream &os, const Point &p) {
        os << "(" << p.x << ", " << p.y << ")";
        return os;
    }

    bool compare_points_by_y(const Point &a, const Point &b) {
        return a.y < b.y;
    }
}
<commit_msg>Removed unused helper function<commit_after>#include "point.hpp"

namespace algorithms {

    bool operator<(const Point &a, const Point &b) {
        return a.x < b.x || (a.x == b.x && a.y < b.y);
    }

    bool operator==(const Point &a, const Point &b) {
        return a.x == b.x && a.y == b.y;
    }

    std::ostream &operator<<(std::ostream &os, const Point &p) {
        os << "(" << p.x << ", " << p.y << ")";
        return os;
    }

}
<|endoftext|>