text:
/*=============================================================================
    Copyright (c) 2001-2013 Joel de Guzman

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include <boost/detail/lightweight_test.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/at.hpp>

#include <string>
#include <iostream>
#include "test.hpp"

int
main()
{
    using namespace boost::spirit;
    using namespace boost::spirit::x3::ascii;
    using boost::spirit::x3::lit;
    using boost::spirit::x3::expect;
    using spirit_test::test;
    using spirit_test::test_attr;
    using boost::spirit::x3::expectation_failure;

    {
        try
        {
            BOOST_TEST((test("aa", char_ >> expect[char_])));
            BOOST_TEST((test("aaa", char_ >> expect[char_ >> char_('a')])));
            BOOST_TEST((test("xi", char_('x') >> expect[char_('i')])));
            BOOST_TEST((!test("xi", char_('y') >> expect[char_('o')]))); // should not throw!
            BOOST_TEST((test("xin", char_('x') >> expect[char_('i') >> char_('n')])));
            BOOST_TEST((!test("xi", char_('x') >> expect[char_('o')])));
        }
        catch (expectation_failure<char const*> const& x)
        {
            std::cout << "expected: " << x.which();
            std::cout << " got: \"" << x.where() << '"' << std::endl;
        }
    }

    {
        try
        {
            BOOST_TEST((test("aa", char_ > char_)));
            BOOST_TEST((test("aaa", char_ > char_ > char_('a'))));
            BOOST_TEST((test("xi", char_('x') > char_('i'))));
            BOOST_TEST((!test("xi", char_('y') > char_('o')))); // should not throw!
            BOOST_TEST((test("xin", char_('x') > char_('i') > char_('n'))));
            BOOST_TEST((!test("xi", char_('x') > char_('o'))));
        }
        catch (expectation_failure<char const*> const& x)
        {
            std::cout << "expected: " << x.which();
            std::cout << " got: \"" << x.where() << '"' << std::endl;
        }
    }

    {
        try
        {
            BOOST_TEST((!test("ay:a", char_ > char_('x') >> ':' > 'a')));
        }
        catch (expectation_failure<char const*> const& x)
        {
            std::cout << "expected: " << x.which();
            std::cout << " got: \"" << x.where() << '"' << std::endl;
        }
    }

    { // Test that attributes with > (sequences) work just like >> (sequences)

        using boost::fusion::vector;
        using boost::fusion::at_c;

        {
            vector<char, char, char> attr;
            BOOST_TEST((test_attr(" a\n  b\n  c",
                char_ > char_ > char_, attr, space)));
            BOOST_TEST((at_c<0>(attr) == 'a'));
            BOOST_TEST((at_c<1>(attr) == 'b'));
            BOOST_TEST((at_c<2>(attr) == 'c'));
        }

        {
            vector<char, char, char> attr;
            BOOST_TEST((test_attr(" a\n  b\n  c",
                char_ > char_ >> char_, attr, space)));
            BOOST_TEST((at_c<0>(attr) == 'a'));
            BOOST_TEST((at_c<1>(attr) == 'b'));
            BOOST_TEST((at_c<2>(attr) == 'c'));
        }

        {
            vector<char, char, char> attr;
            BOOST_TEST((test_attr(" a, b, c",
                char_ >> ',' > char_ >> ',' > char_, attr, space)));
            BOOST_TEST((at_c<0>(attr) == 'a'));
            BOOST_TEST((at_c<1>(attr) == 'b'));
            BOOST_TEST((at_c<2>(attr) == 'c'));
        }
    }

    {
        try
        {
            BOOST_TEST((test(" a a", char_ > char_, space)));
            BOOST_TEST((test(" x i", char_('x') > char_('i'), space)));
            BOOST_TEST((!test(" x i", char_('x') > char_('o'), space)));
        }
        catch (expectation_failure<char const*> const& x)
        {
            std::cout << "expected: " << x.which();
            std::cout << " got: \"" << x.where() << '"' << std::endl;
        }
    }

    {
        try
        {
            BOOST_TEST((test("bar", expect[lit("foo")])));
        }
        catch (expectation_failure<char const*> const& x)
        {
            std::cout << "expected: " << x.which();
            std::cout << " got: \"" << x.where() << '"' << std::endl;
        }
    }

    //~ {
        //~ try
        //~ {
            //~ BOOST_TEST((test("aA", no_case[char_('a') > 'a'])));
            //~ BOOST_TEST((test("BEGIN END", no_case[lit("begin") > "end"], space)));
            //~ BOOST_TEST((!test("BEGIN END", no_case[lit("begin") > "nend"], space)));
        //~ }
        //~ catch (expectation_failure<char const*> const& x)
        //~ {
            //~ std::cout << "expected: " << x.which();
            //~ std::cout << " got: \"" << x.where() << '"' << std::endl;
        //~ }
    //~ }

    //~ {
        //~ using boost::spirit::x3::rule;
        //~ using boost::spirit::x3::eps;
        //~ rule<const wchar_t*, void(int)> r;
        //~ r = eps > eps(_r1);
    //~ }

    { // test various what results

        //~ using boost::spirit::x3::compile;
        //~ BOOST_TEST((x3::what(compile<x3::domain>('a')) == "'a'"));
        //~ BOOST_TEST((x3::what(compile<x3::domain>("hello")) == "\"hello\""));
        //~ BOOST_TEST((x3::what(compile<x3::domain>(x3::space)) == "space"));
        //~ BOOST_TEST((x3::what(compile<x3::domain>(x3::bool_)) == "boolean"));
        //~ BOOST_TEST((x3::what(compile<x3::domain>(x3::true_)) == "true"));
        //~ BOOST_TEST((x3::what(compile<x3::domain>(x3::false_)) == "false"));
        //~ BOOST_TEST((x3::what(compile<x3::domain>(x3::int_)) == "integer"));
        //~ BOOST_TEST((x3::what(compile<x3::domain>(x3::hex)) == "hexadecimal integer"));
        //~ BOOST_TEST((x3::what(compile<x3::domain>(x3::double_)) == "real number"));
    }

    return boost::report_errors();
}

ext: cpp

max_stars_repo_name: cooparation/caffe-android

max_issues_repo_name: cooparation/caffe-android

max_forks_repo_name: cooparation/caffe-android


text:
/*
   Copyright 2022 The Silkworm Authors

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#ifndef SILKWORM_RPC_SERVER_CONTEXT_POOL_HPP_
#define SILKWORM_RPC_SERVER_CONTEXT_POOL_HPP_

#include <cstddef>
#include <ostream>
#include <list>
#include <memory>
#include <mutex>
#include <vector>

#include <boost/asio/io_context.hpp>
#include <grpcpp/grpcpp.h>

#include <silkworm/rpc/completion_runner.hpp>

namespace silkworm::rpc {

struct ServerContext {
    std::shared_ptr<boost::asio::io_context> io_context;
    std::unique_ptr<grpc::ServerCompletionQueue> grpc_queue;
    std::unique_ptr<CompletionRunner> grpc_runner;
};

std::ostream& operator<<(std::ostream& out, const ServerContext& c);

class ServerContextPool {
  public:
    explicit ServerContextPool(std::size_t pool_size);
    ~ServerContextPool();

    ServerContextPool(const ServerContextPool&) = delete;
    ServerContextPool& operator=(const ServerContextPool&) = delete;

    void add_context(std::unique_ptr<grpc::ServerCompletionQueue> queue) noexcept;
    void run();
    void stop();

    ServerContext const& next_context();
    boost::asio::io_context& next_io_context();

  private:
    //! The pool of execution contexts.
    std::vector<ServerContext> contexts_;

    //! The work-tracking executors that keep the running contexts.
    std::list<boost::asio::execution::any_executor<>> work_;

    //! The index for obtaining next context to use (round-robin).
    std::size_t next_index_;

    //! Mutual exclusion to synchronize run/stop operations.
    std::mutex mutex_;

    //! Flag indicating if pool has been stopped.
    bool stopped_{false};
};

} // namespace silkworm::rpc

#endif // SILKWORM_RPC_SERVER_CONTEXT_POOL_HPP_

ext: hpp

max_stars_repo_name: elmato/silkworm

max_issues_repo_name: elmato/silkworm

max_forks_repo_name: elmato/silkworm


text:
/*
Copyright 2014-2015 Glen Joseph Fernandes
(glenjofe@gmail.com)

Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_ALIGN_DETAIL_MAX_ALIGN_HPP
#define BOOST_ALIGN_DETAIL_MAX_ALIGN_HPP

#include <boost/align/detail/max_size.hpp>
#include <boost/align/alignment_of.hpp>

namespace boost {
namespace alignment {
namespace detail {

template<class A, class B>
struct max_align
    : max_size<alignment_of<A>::value, alignment_of<B>::value> { };

} /* detail */
} /* alignment */
} /* boost */

#endif


text:
//
//  Copyright Toon Knapen, Karl Meerbergen
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//

#include "random.hpp"

#include <boost/numeric/bindings/traits/transpose.hpp>
#include <boost/numeric/bindings/traits/ublas_vector.hpp>
#include <boost/numeric/bindings/traits/ublas_matrix.hpp>
#include <boost/numeric/bindings/traits/ublas_symmetric.hpp>
#include <boost/numeric/bindings/traits/ublas_hermitian.hpp>
#include <boost/numeric/bindings/blas/blas3.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
#include <boost/numeric/ublas/symmetric.hpp>
#include <boost/numeric/ublas/hermitian.hpp>
#include <boost/numeric/ublas/triangular.hpp>
#include <boost/numeric/ublas/io.hpp>

#include <iostream>
#include <complex>

// Randomize a matrix
template <typename M>
void randomize(M& m) {
   typedef typename M::size_type  size_type ;
   typedef typename M::value_type value_type ;

   size_type size1 = m.size1() ;
   size_type size2 = m.size2() ;

   for (size_type i=0; i<size2; ++i) {
      for (size_type j=0; j<size1; ++j) {
         m(j,i) = random_value< value_type >() ;
      }
   }
} // randomize()

template <typename T>
struct RealDiagonal {
   template <typename M>
   void operator() (M& m) const {}
};

template <typename T>
struct RealDiagonal< std::complex<T> > {
   template <typename M>
   void operator() (M& m) const {
      for (typename M::size_type i=0; i<m.size1(); ++i) {
         m(i,i) = m(i,i).real();
      }
   }
};

template <typename M>
boost::numeric::ublas::triangular_adaptor<const M, boost::numeric::ublas::unit_upper> unit_upper_part(const M& m) {
   return boost::numeric::ublas::triangular_adaptor<const M, boost::numeric::ublas::unit_upper> (m);
}

template <typename M>
boost::numeric::ublas::triangular_adaptor<const M, boost::numeric::ublas::upper> upper_part(const M& m) {
   return boost::numeric::ublas::triangular_adaptor<const M, boost::numeric::ublas::upper> (m);
}

template <typename M>
boost::numeric::ublas::triangular_adaptor<const M, boost::numeric::ublas::lower> lower_part(const M& m) {
   return boost::numeric::ublas::triangular_adaptor<const M, boost::numeric::ublas::lower> (m);
}

// Run over all matrix types and aply a functor to it.
template <typename F>
int do_matrix_types(const F& f) {
   using namespace boost::numeric::ublas ;

   typedef typename F::value_type value_type ;

   {
      matrix<value_type,column_major> m( f.size1(), f.size2() );
      if (f(m)) return 255;
   }
   {
      typedef matrix<value_type,column_major> matrix_type ;
      matrix_type m( 2*f.size1(), 2*f.size2() );
      matrix_range<matrix_type> m_r( m, range(1,1+f.size1()), range(2,2+f.size2()) );
      if (f(m_r)) return 255 ;
   }

   return 0;
} // do_matrix_types()

// Functor to select syrk/herk calls given the two matrix_types
template <typename M1>
struct Syrk2 {
   typedef typename M1::value_type                                                         value_type ;
   typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major>  ref_matrix_type ;
   typedef typename boost::numeric::bindings::traits::type_traits< value_type >::real_type real_type ;
   typedef typename ref_matrix_type::size_type                                             size_type ;

   Syrk2(const M1& a,
        const ref_matrix_type& a_ref)
   : a_( a ), a_ref_( a_ref )
   , c_ref_( a_ref_.size1(), a_ref_.size1() )
   {
      randomize( c_ref_ );
      RealDiagonal<value_type>() (c_ref_); // Must have real diagonal for herk.
   }

   template <typename M>
   int operator() (M& c) const {
      using namespace boost::numeric::ublas ;

      real_type alpha = 2.0 ;
      real_type beta = -3.0 ;

      c.assign( c_ref_ );
      boost::numeric::bindings::blas::syrk( 'U', 'N', value_type(alpha), a_, value_type(beta), c ) ;
      if ( norm_frobenius( upper_part( c - (beta*c_ref_ + alpha * prod( a_ref_, trans( a_ref_ ) ) ) ) )
          > std::numeric_limits< real_type >::epsilon() * norm_frobenius( upper_part(c) ) ) return 255;

      c.assign( c_ref_ );
      symmetric_adaptor<M, upper> c_s( c );
      boost::numeric::bindings::blas::syrk( 'U', 'N', value_type(alpha), a_, value_type(beta), c_s ) ;
      if ( norm_frobenius( upper_part( c_s - (beta*c_ref_ + alpha * prod( a_ref_, trans( a_ref_ ) ) ) ) )
          > std::numeric_limits< real_type >::epsilon() * norm_frobenius( upper_part(c_s) ) ) return 255;

      c.assign( c_ref_ );
      boost::numeric::bindings::blas::herk( 'U', 'N', alpha, a_, beta, c ) ;
      if ( norm_frobenius( upper_part( c - (beta*c_ref_ + alpha * prod( a_ref_, herm( a_ref_ ) ) ) ) )
          > std::numeric_limits< real_type >::epsilon() * norm_frobenius( upper_part(c) ) ) return 255;

      c.assign( c_ref_ );
      hermitian_adaptor<M, upper> c_h( c );
      boost::numeric::bindings::blas::herk( 'U', 'N', alpha, a_, beta, c_h ) ;
      if ( norm_frobenius( upper_part( c_h - (beta*c_ref_ + alpha * prod( a_ref_, herm( a_ref_ ) ) ) ) )
          > std::numeric_limits< real_type >::epsilon() * norm_frobenius( upper_part(c_h) ) ) return 255;

      return 0;
   }

   size_type size1() const {return c_ref_.size1() ;}
   size_type size2() const {return c_ref_.size2() ;}

   const M1& a_ ;
   const ref_matrix_type& a_ref_;
   ref_matrix_type  c_ref_;
}; // Syrk2

template <typename T>
struct Syrk1 {
   typedef T                                                                               value_type ;
   typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major>  ref_matrix_type ;
   typedef typename boost::numeric::bindings::traits::type_traits< value_type >::real_type real_type ;
   typedef typename ref_matrix_type::size_type                                             size_type ;

   Syrk1()
   : a_ref_( 4, 7 )
   {
      randomize( a_ref_ );
   }

   template <typename M>
   int operator() (M& a) const {
      typedef Syrk2<M> functor_type ;
      a.assign( a_ref_ );
      return do_matrix_types( functor_type(a, a_ref_) );
   }

   size_type size1() const {return a_ref_.size1();}
   size_type size2() const {return a_ref_.size2();}

   ref_matrix_type a_ref_;
}; // Syrk1

// Functor to select gemm calls given the three matrix_types
template <typename M1, typename M2>
struct Gemm3 {
   typedef typename M1::value_type                                                         value_type ;
   typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major>  ref_matrix_type ;
   typedef typename boost::numeric::bindings::traits::type_traits< value_type >::real_type real_type ;
   typedef typename ref_matrix_type::size_type                                             size_type ;

   Gemm3(const M1& a, const M2& b,
        const ref_matrix_type& a_ref, const ref_matrix_type& b_ref)
   : a_( a ), b_( b )
   , a_ref_( a_ref ), b_ref_( b_ref ), c_ref_( a_ref_.size1(), b_ref_.size2() )
   {
      randomize( c_ref_ );
   }

   template <typename M>
   int operator() (M& c) const {
      c.assign( c_ref_ );

      value_type alpha = 2.0 ;
      value_type beta = -3.0 ;

      boost::numeric::bindings::blas::gemm( 'N', 'N', alpha, a_, b_, beta, c ) ;
      double safety_factor (1.5);
      if ( norm_frobenius( c - (beta*c_ref_ + alpha * prod( a_ref_, b_ref_ ) ) )
          > safety_factor*std::numeric_limits< real_type >::epsilon() * norm_frobenius( c ) ) return 255;

      return 0;
   }

   size_type size1() const {return c_ref_.size1() ;}
   size_type size2() const {return c_ref_.size2() ;}

   const M1& a_ ;
   const M2& b_ ;
   const ref_matrix_type& a_ref_, b_ref_;
   ref_matrix_type  c_ref_;
}; // Gemm3

template <typename M1>
struct Gemm2 {
   typedef typename M1::value_type                                                         value_type ;
   typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major>  ref_matrix_type ;
   typedef typename boost::numeric::bindings::traits::type_traits< value_type >::real_type real_type ;
   typedef typename ref_matrix_type::size_type                                             size_type ;

   Gemm2(const M1& a, const ref_matrix_type& a_ref)
   : a_( a )
   , a_ref_( a_ref )
   , b_ref_( a_ref.size2(), 7 )
   {
      randomize( b_ref_ );
   }

   template <typename M>
   int operator() (M& b) const {
      typedef Gemm3<M1,M> functor_type ;
      b.assign( b_ref_ );
      return do_matrix_types( functor_type(a_, b, a_ref_, b_ref_) );
   }

   size_type size1() const {return b_ref_.size1();}
   size_type size2() const {return b_ref_.size2();}

   const M1&              a_ ;
   const ref_matrix_type& a_ref_;
   ref_matrix_type        b_ref_;
}; // Gemm2

template <typename T>
struct Gemm1 {
   typedef T                                                                               value_type ;
   typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major>  ref_matrix_type ;
   typedef typename boost::numeric::bindings::traits::type_traits< value_type >::real_type real_type ;
   typedef typename ref_matrix_type::size_type                                             size_type ;

   Gemm1()
   : a_ref_( 4, 7 )
   {
      randomize( a_ref_ );
   }

   template <typename M>
   int operator() (M& a) const {
      typedef Gemm2<M> functor_type ;
      a.assign( a_ref_ );
      return do_matrix_types( functor_type(a, a_ref_) );
   }

   size_type size1() const {return a_ref_.size1();}
   size_type size2() const {return a_ref_.size2();}

   ref_matrix_type a_ref_;
}; // Gemm1

// Functor to select syrk/herk calls given the two matrix_types
template <typename M1>
struct Trsm2 {
   typedef typename M1::value_type                                                         value_type ;
   typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major>  ref_matrix_type ;
   typedef typename boost::numeric::bindings::traits::type_traits< value_type >::real_type real_type ;
   typedef typename ref_matrix_type::size_type                                             size_type ;

   Trsm2(M1& c,
        const ref_matrix_type& b_ref, const ref_matrix_type& c_ref )
   : c_( c ), c_ref_( c_ref ), b_ref_( b_ref )
   , a_ref_( b_ref_.size1(), c_ref_.size2() )
   {
      randomize( a_ref_ ) ;
   }

   template <typename M>
   int operator() (M& a) const {
      using namespace boost::numeric::ublas ;

      real_type alpha = 2.0 ;

      a.assign( a_ref_ );
      boost::numeric::bindings::blas::trsm( 'L', 'U', 'N', 'N', value_type(alpha), b_ref_, a ) ;
      if ( norm_frobenius( alpha * a_ref_ - prod( upper_part(b_ref_), a ) )
          > std::numeric_limits< real_type >::epsilon() * norm_frobenius( upper_part(b_ref_) ) * norm_frobenius( a) ) return 255;

      a.assign( a_ref_ );
      boost::numeric::bindings::blas::trsm( 'R', 'U', 'N', 'N', value_type(alpha), c_, a ) ;
      if ( norm_frobenius( alpha * a_ref_ - prod( a, upper_part(c_) ) )
          > std::numeric_limits< real_type >::epsilon() * norm_frobenius( upper_part(c_) ) * norm_frobenius( a ) ) return 255;

      a.assign( a_ref_ );
      boost::numeric::bindings::blas::trsm( 'R', 'L', 'N', 'N', value_type(alpha), c_, a ) ;
      if ( norm_frobenius( alpha * a_ref_ - prod( a, lower_part(c_) ) )
          > std::numeric_limits< real_type >::epsilon() * norm_frobenius( lower_part(c_) ) * norm_frobenius( a ) ) return 255;

      a.assign( a_ref_ );
      boost::numeric::bindings::blas::trsm( 'L', 'U', 'T', 'N', value_type(alpha), b_ref_, a ) ;
      if ( norm_frobenius( alpha * a_ref_ - prod( trans(upper_part(b_ref_)), a ) )
          > std::numeric_limits< real_type >::epsilon() * norm_frobenius( upper_part(b_ref_) ) * norm_frobenius( a) ) return 255;

      a.assign( a_ref_ );
      boost::numeric::bindings::blas::trsm( 'L', 'U', 'N', 'U', value_type(alpha), b_ref_, a ) ;
      if ( norm_frobenius( alpha * a_ref_ - prod( unit_upper_part(b_ref_), a ) )
          > std::numeric_limits< real_type >::epsilon() * norm_frobenius( unit_upper_part(b_ref_) ) * norm_frobenius( a) ) return 255;

      return 0;
   }

   size_type size1() const {return a_ref_.size1() ;}
   size_type size2() const {return a_ref_.size2() ;}

   const M1& c_ ;
   const ref_matrix_type& c_ref_;
   const ref_matrix_type& b_ref_;
   ref_matrix_type        a_ref_;
} ; // Trsm2

template <typename T>
struct Trsm1 {
   typedef T                                                                               value_type ;
   typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major>  ref_matrix_type ;
   typedef typename boost::numeric::bindings::traits::type_traits< value_type >::real_type real_type ;
   typedef typename ref_matrix_type::size_type                                             size_type ;

   Trsm1()
   : b_( 4, 4 )
   , c_( 7, 7 )
   {
      randomize( b_ );
      randomize( c_ );
      for ( std::size_t i=0; i<b_.size1(); ++i ) if ( b_(i,i)==value_type(0.0) ) b_(i,i) = value_type(1.0) ;
      for ( std::size_t i=0; i<c_.size1(); ++i ) if ( c_(i,i)==value_type(0.0) ) c_(i,i) = value_type(1.0) ;
   }

   template <typename M>
   int operator() (M& c) const {
      typedef Trsm2<M> functor_type ;
      return do_matrix_types( functor_type(c, b_, c_) );
   }

   size_type size1() const {return c_.size1();}
   size_type size2() const {return c_.size2();}

   ref_matrix_type b_;
   ref_matrix_type c_;
} ; // Trsm1

template <typename T>
int do_value_type() {
   // Gemm test
   std::cout << "  gemm\n";
   if (do_matrix_types( Gemm1<T>() )) return 255 ;

   // Syrk and herk test
   std::cout << "  herk\n";
   if (do_matrix_types( Syrk1<T>() )) return 255 ;

   // Trsm test
   std::cout << "  trsm\n";
   if (do_matrix_types( Trsm1<T>() )) return 255 ;

   return 0 ;
} // do_value_type()

int main() {
   // Test for various value_types
   std::cout << "float\n";
   if (do_value_type<float>()) return 255 ;
   std::cout << "double\n";
   if (do_value_type<double>()) return 255 ;
   std::cout << "complex<float>\n";
   if (do_value_type<std::complex<float> >()) return 255 ;
   std::cout << "complex<double>\n";
   if (do_value_type<std::complex<double> >()) return 255 ;

   std::cout << "Regression test succeeded\n" ;

   return 0 ;
}

max_stars_repo_name: diku-dk/PROX

max_issues_repo_name: diku-dk/PROX

max_forks_repo_name: diku-dk/PROX


text:
#pragma once
#include <generatorAPI.hpp>

#include "mysql_connection.h"

#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>

#include <deque>
#include <utility>
#include <boost/regex.hpp>

template <typename Container> // we can make this generic for any container
struct container_hash {
    std::size_t operator()(Container const& c) const {
        return boost::hash_range(c.begin(), c.end());
    }
};

namespace markov {
	using MarkovDeque = std::deque<std::string>;
	template<typename T>
	void shiftDeque(std::deque<T>&, T&);
	class markovBackend: public generatorAPI { // We store most info inside SQL or class
		public:
			void init(std::vector<std::string>);
			void trainBegin(std::vector<std::shared_ptr<std::ifstream>>) {};
			boost::any train(std::shared_ptr<std::ifstream>);
			boost::any merge(std::vector<boost::any>&);
			void out(boost::any&, std::shared_ptr<std::ostream>);

			boost::any load(std::string);
			void save(std::string, boost::any&);

		protected:
			void trainPart(std::string, const std::unique_ptr<sql::Connection>&, const std::unique_ptr<sql::PreparedStatement>&);
			void trainFinal(std::string, const std::unique_ptr<sql::Connection>&, const std::unique_ptr<sql::PreparedStatement>&, MarkovDeque&);
			void trainInsert(std::string, const std::unique_ptr<sql::Connection>&, const std::unique_ptr<sql::PreparedStatement>&, MarkovDeque&);

			void addIdx(const std::unique_ptr<sql::Connection>&);

			std::unique_ptr<sql::Connection> mysql_connect();

			std::string outGet(const std::unique_ptr<sql::Connection>&, const std::unique_ptr<sql::PreparedStatement>&, MarkovDeque&);

			std::string iter;
			std::string prefixmiddle;
			unsigned int N;
			bool splitstr;
			unsigned long long int maxgen;
			bool rndstart;
			boost::regex separator;

			boost::sregex_token_iterator xInvalidTokenIt;
			boost::sregex_iterator xInvalidIt;

			std::string mysql_endpoint;
			std::string mysql_user;
			std::string mysql_passwd;
			std::string mysql_database;
			std::string mysql_table;
			unsigned int mysql_index;
			bool mysql_transactions;

			sql::Driver *driver;
			std::string mysql_insert; // Template for INSERT
			std::string mysql_query; // Template for strings query
	};
}


text:
//
//  Scheduler.cpp
//
//
//  Created by Ben Lengerich on 1/27/16.
//
//

#include "Scheduler.hpp"

#include <Eigen/Dense>
#include <stdexcept>
#include <iostream>
#include <memory>
#include <mutex>
#include <node.h>
#include <stdio.h>
#include <thread>
#include <typeinfo>
#include <unistd.h>
#include <unordered_map>
#include <uv.h>

#ifdef BAZEL
#include "Algorithms/Algorithm.hpp"
#include "Algorithms/AlgorithmOptions.hpp"
#include "Algorithms/BrentSearch.hpp"
#include "Algorithms/GridSearch.hpp"
#include "Algorithms/IterativeUpdate.hpp"
#include "Algorithms/ProximalGradientDescent.hpp"
#include "Algorithms/HypoTestPlaceHolder.h"
#include "Models/AdaMultiLasso.hpp"
#include "Models/GFlasso.h"
#include "Models/lasso.hpp"
#include "Models/LinearRegression.hpp"
#include "Models/Model.hpp"
#include "Models/ModelOptions.hpp"
#include "Models/MultiPopLasso.hpp"
#include "Models/TreeLasso.hpp"
#include "Models/LinearMixedModel.hpp"
#include "Models/SparseLMM.h"
#include "Stats/FisherTest.h"
#include "Stats/Chi2Test.h"
#include "Stats/WaldTest.h"
#include "Graph/NeighborSelection.hpp"
#include "Graph/GraphicalLasso.hpp"
#include "Scheduler/Job.hpp"
#else
#include "../Algorithms/Algorithm.hpp"
#include "../Algorithms/AlgorithmOptions.hpp"
#include "../Algorithms/BrentSearch.hpp"
#include "../Algorithms/GridSearch.hpp"
#include "../Algorithms/IterativeUpdate.hpp"
#include "../Algorithms/ProximalGradientDescent.hpp"
#include "../Algorithms/HypoTestPlaceHolder.h"
#include "../Models/AdaMultiLasso.hpp"
#include "../Models/GFlasso.h"
#include "../Models/lasso.hpp"
#include "../Models/LinearRegression.hpp"
#include "../Models/Model.hpp"
#include "../Models/ModelOptions.hpp"
#include "../Models/MultiPopLasso.hpp"
#include "../Models/LinearMixedModel.hpp"
#include "../Models/SparseLMM.h"
#include "../Models/TreeLasso.hpp"
#include "../Stats/FisherTest.h"
#include "../Stats/Chi2Test.h"
#include "../Stats/WaldTest.h"
#include "../Graph/NeighborSelection.hpp"
#include "../Graph/GraphicalLasso.hpp"
#include "../Scheduler/Job.hpp"
#endif

using namespace std;

//////////////////////////////////////////
// Constructors
//////////////////////////////////////////

Scheduler::Scheduler()
: next_algorithm_id(1)
, next_model_id(1)
, next_job_id(1) {
	algorithms_map = std::unordered_map<algorithm_id_t, shared_ptr<Algorithm>>();
	models_map = std::unordered_map<model_id_t, shared_ptr<Model>>();
	jobs_map = std::unordered_map<job_id_t, shared_ptr<Job_t>>();
}

Scheduler& Scheduler::operator=(Scheduler const& s) {
    return Scheduler::Instance();
}

Scheduler& Scheduler::Instance() {
	static Scheduler s_instance;
	return s_instance;
}

/////////////////////////////////////////////////////////
// Public Functions
/////////////////////////////////////////////////////////

algorithm_id_t Scheduler::newAlgorithm(const AlgorithmOptions_t& options) {
	const algorithm_id_t id = getNewAlgorithmId();
	// Determine the type of algorithm to create.
	if (ValidAlgorithmId(id)) {
		switch(options.type) {
			case algorithm_type::brent_search:
				algorithms_map[id] = shared_ptr<BrentSearch>(new BrentSearch(options.options));
				break;
			case algorithm_type::grid_search:
				algorithms_map[id] = shared_ptr<GridSearch>(new GridSearch(options.options));
				break;
			case algorithm_type::iterative_update:
				algorithms_map[id] = shared_ptr<IterativeUpdate>(new IterativeUpdate(options.options));
				break;
			case algorithm_type::proximal_gradient_descent:
				algorithms_map[id] = shared_ptr<ProximalGradientDescent>(new ProximalGradientDescent(options.options));
				break;
			case algorithm_type::hypo_test:
				algorithms_map[id] = shared_ptr<HypoTestPlaceHolder>(new HypoTestPlaceHolder(options.options));
				break;
			case algorithm_type::neighbor_selection:
				algorithms_map[id] = shared_ptr<NeighborSelection>(new NeighborSelection(options.options));
				break;
            case algorithm_type::graphical_lasso:
				algorithms_map[id] = shared_ptr<GraphicalLasso>(new GraphicalLasso(options.options));
				break;
			default:
				return 0;
		}
	}

	return id;
}

model_id_t Scheduler::newModel(const ModelOptions_t& options) {
	const model_id_t id = getNewModelId();
	if (ValidModelId(id)) {
		switch(options.type) {
			case ada_multi_lasso: {
				models_map[id] = shared_ptr<AdaMultiLasso>(new AdaMultiLasso(options.options));
				break;
			}
			case gf_lasso: {
				models_map[id] = shared_ptr<Gflasso>(new Gflasso(options.options));
				break;
			}
			case linear_regression: {
				models_map[id] = shared_ptr<LinearRegression>(new LinearRegression(options.options));
				break;
			}
			case multi_pop_lasso: {
				models_map[id] = shared_ptr<MultiPopLasso>(new MultiPopLasso(options.options));
				break;
			}
			case tree_lasso: {
				models_map[id] = shared_ptr<TreeLasso>(new TreeLasso(options.options));
				break;
			}
			case fisher_test: {
				models_map[id] = shared_ptr<FisherTest>(new FisherTest(options.options));
				break;
			}
			case chi2_test: {
				models_map[id] = shared_ptr<Chi2Test>(new Chi2Test(options.options));
				break;
			}
			case wald_test: {
				models_map[id] = shared_ptr<WaldTest>(new WaldTest(options.options));
				break;
			}
			case lmm: {
				models_map[id] = shared_ptr<LinearMixedModel>(new LinearMixedModel(options.options));
				break;
			}
			case slmm: {
				models_map[id] = shared_ptr<SparseLMM>(new SparseLMM(options.options));
				break;
			}
			default:
				return 0;
		}
	}

	return id;
}

bool Scheduler::imputation(const job_id_t job_id) {
    if (JobIdUsed(job_id) && getJob(job_id)->model) {
        getJob(job_id)->model->imputation();
        return true;
    }
    return false;
}

bool Scheduler::setMetaData(const job_id_t job_id, const string& filename, vector<string>& marker_ids) {
    if (JobIdUsed(job_id)) {
        shared_ptr<Job_t> job = getJob(job_id);
        job->filename = filename;
        job->marker_ids = marker_ids;
    }
    return false;
}

bool Scheduler::setX(const job_id_t job_id, const Eigen::MatrixXf& X) {
	if (JobIdUsed(job_id) && getJob(job_id)->model) {
		getJob(job_id)->model->setX(X);
		return true;
	}
	return false;
}

bool Scheduler::setY(const job_id_t job_id, const Eigen::MatrixXf& Y) {
	if (JobIdUsed(job_id) && getJob(job_id)->model) {
		getJob(job_id)->model->setY(Y);
		return true;
	}
	return false;
}

// TODO: merge setX and setY into this function?
bool Scheduler::setModelAttributeMatrix(const job_id_t job_id, const string& str, Eigen::MatrixXf* Z) {
	try {
		if (JobIdUsed(job_id) && getJob(job_id)->model) {
			getJob(job_id)->model->setAttributeMatrix(str, Z);
			return true;
		}
		return false;
	} catch (const exception & e) {
		rethrow_exception(current_exception());
		return false;
	}
}

job_id_t Scheduler::newJob(const JobOptions_t& options) {
	Job_t* my_job = new Job_t();
	const job_id_t job_id = getNewJobId();
	if (ValidJobId(job_id)) {
		my_job->job_id = job_id;
		try {
			algorithm_id_t algorithm_id = newAlgorithm(options.alg_opts);
			my_job->algorithm = getAlgorithm(algorithm_id);
		} catch (const exception& e) {
			throw runtime_error("Error creating algorithm");
			return 0;
		}
		try {
			model_id_t model_id = newModel(options.model_opts);
			my_job->model = getModel(model_id);
			jobs_map[my_job->job_id] = shared_ptr<Job_t>(my_job);
			return job_id;
		} catch (const exception& e) {
			throw runtime_error("Error creating model");
			return 0;
		}
	} else {
		throw runtime_error("could not get a new job id (queue may be full)");
	}

	delete my_job;
	return 0;
}

bool Scheduler::startJob(const job_id_t job_id, void (*completion)(uv_work_t*, int)) {
	if (!ValidJobId(job_id)) {
		throw runtime_error("Job id must correspond to a job that has been created.");
		return false;
	}
	shared_ptr<Job_t> job = getJob(job_id);

	if (!job.get()) {
		throw runtime_error("Job must not be null.");
		return false;
	} else if (!job->algorithm || !job->model) {
		throw runtime_error("Job must have an algorithm and a model.");
		return false;
	} else if (job->algorithm->getIsRunning()) {
		throw runtime_error("Job is already running.");
		return false;
	}
	try {
		job->algorithm->assertReadyToRun();
		job->model->assertReadyToRun();
		job->request.data = job.get();
		uv_queue_work(uv_default_loop(), &(job->request), trainAlgorithmThread, completion);
		return true;
	} catch (const exception& ex) {
		rethrow_exception(current_exception());
		return false;
	}
}

// Runs in libuv thread spawned by startJob
void trainAlgorithmThread(uv_work_t* req) {
	Job_t* job = static_cast<Job_t*>(req->data);
	if (!job) {
		throw runtime_error("Job must not be null");
		return;
	}

	job->thread_id = std::this_thread::get_id();
	// TODO: as more algorithm/model types are created, add them here.
	try {
		if (!job->algorithm || !job->model) {
			throw runtime_error("Job must have an algorithm and a model");
		}
		job->algorithm->assertReadyToRun();
		job->model->assertReadyToRun();
		// Object slicing makes this annoying
		if (shared_ptr<BrentSearch> alg = dynamic_pointer_cast<BrentSearch>(job->algorithm)) {
			alg->setUpRun();
			if (shared_ptr<AdaMultiLasso> model = dynamic_pointer_cast<AdaMultiLasso>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<Gflasso> model = dynamic_pointer_cast<Gflasso>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<LinearRegression> model = dynamic_pointer_cast<LinearRegression>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<MultiPopLasso> model = dynamic_pointer_cast<MultiPopLasso>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<SparseLMM> model = dynamic_pointer_cast<SparseLMM>(job->model)) {
		        alg->sub_run(model);
		    } else if (shared_ptr<TreeLasso> model = dynamic_pointer_cast<TreeLasso>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<LinearMixedModel> model = dynamic_pointer_cast<LinearMixedModel>(job->model)) {
				alg->sub_run(model);
			} else {
		        throw runtime_error("Requested model type not implemented for the requested algorithm");
		    }
		    alg->finishRun();
		} else if (shared_ptr<GridSearch> alg = dynamic_pointer_cast<GridSearch>(job->algorithm)) {
			alg->setUpRun();
		    if (shared_ptr<AdaMultiLasso> model = dynamic_pointer_cast<AdaMultiLasso>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<Gflasso> model = dynamic_pointer_cast<Gflasso>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<LinearRegression> model = dynamic_pointer_cast<LinearRegression>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<MultiPopLasso> model = dynamic_pointer_cast<MultiPopLasso>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<SparseLMM> model = dynamic_pointer_cast<SparseLMM>(job->model)) {
		        alg->sub_run(model);
		    } else if (shared_ptr<TreeLasso> model = dynamic_pointer_cast<TreeLasso>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<LinearMixedModel> model = dynamic_pointer_cast<LinearMixedModel>(job->model)) {
				alg->run(model);
			} else {
		        throw runtime_error("Requested model type not implemented for the requested algorithm");
		    }
		    alg->finishRun();
		} else if (shared_ptr<IterativeUpdate> alg = dynamic_pointer_cast<IterativeUpdate>(job->algorithm)) {
			alg->setUpRun();
			if (shared_ptr<AdaMultiLasso> model = dynamic_pointer_cast<AdaMultiLasso>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<Gflasso> model = dynamic_pointer_cast<Gflasso>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<LinearRegression> model = dynamic_pointer_cast<LinearRegression>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<MultiPopLasso> model = dynamic_pointer_cast<MultiPopLasso>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<SparseLMM> model = dynamic_pointer_cast<SparseLMM>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<TreeLasso> model = dynamic_pointer_cast<TreeLasso>(job->model)) {
		        alg->run(model);
		    } else {
		        throw runtime_error("Requested model type not implemented for the requested algorithm");
		    }
		    alg->finishRun();
		} else if (shared_ptr<ProximalGradientDescent> alg = dynamic_pointer_cast<ProximalGradientDescent>(job->algorithm)) {
			alg->setUpRun();
			if (shared_ptr<AdaMultiLasso> model = dynamic_pointer_cast<AdaMultiLasso>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<Gflasso> model = dynamic_pointer_cast<Gflasso>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<LinearRegression> model = dynamic_pointer_cast<LinearRegression>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<MultiPopLasso> model = dynamic_pointer_cast<MultiPopLasso>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<SparseLMM> model = dynamic_pointer_cast<SparseLMM>(job->model)) {
		        alg->run(model);
		    } else if (shared_ptr<TreeLasso> model = dynamic_pointer_cast<TreeLasso>(job->model)) {
		        alg->run(model);
		    } else {
		        throw runtime_error("Requested model type not implemented for the requested algorithm");
		    }
		    alg->finishRun();
		} else if (shared_ptr<HypoTestPlaceHolder> alg = dynamic_pointer_cast<HypoTestPlaceHolder>(job->algorithm)){
			alg->setUpRun();
			if (shared_ptr<FisherTest> model = dynamic_pointer_cast<FisherTest>(job->model)) {
				alg->run(model);
			} else if (shared_ptr<Chi2Test> model = dynamic_pointer_cast<Chi2Test>(job->model)) {
				alg->run(model);
			} else if (shared_ptr<WaldTest> model = dynamic_pointer_cast<WaldTest>(job->model)) {
				alg->run(model);
			} else {
				throw runtime_error("Requested model type not implemented for the requested algorithm");
			}
			alg->finishRun();
		} else if (shared_ptr<NeighborSelection> alg = dynamic_pointer_cast<NeighborSelection>(job->algorithm)) {
			alg->setUpRun();
			if (shared_ptr<LinearRegression> model = dynamic_pointer_cast<LinearRegression>(job->model)) {
				alg->run(model);
			} else {
				throw runtime_error("Requested model type not implemented for the requested algorithm");
			}
			alg->finishRun();
		} else if (shared_ptr<GraphicalLasso> alg = dynamic_pointer_cast<GraphicalLasso>(job->algorithm)) {
			alg->setUpRun();
			if (shared_ptr<LinearRegression> model = dynamic_pointer_cast<LinearRegression>(job->model)) {
				alg->run(model);
			} else {
				throw runtime_error("Requested model type not implemented for the requested algorithm");
			}
			alg->finishRun();
		} else {
			throw runtime_error("Requested algorithm type not implemented");
		}
	} catch (const exception& ex) {
		job->exception = current_exception();	// Must save the exception so that it can be passed between threads.
	}
}

float Scheduler::checkJobProgress(const job_id_t job_id) {
	if (JobIdUsed(job_id) && getJob(job_id)->algorithm) {
		return getJob(job_id)->algorithm->getProgress();
	}
	return -1;
}

bool Scheduler::cancelJob(const job_id_t job_id) {
	if (JobIdUsed(job_id) && getJob(job_id)->algorithm) {
		getJob(job_id)->algorithm->stop();
		return true;
	}
	return false;
}

bool Scheduler::deleteAlgorithm(const algorithm_id_t algorithm_id) {
	if (getAlgorithm(algorithm_id) && !getAlgorithm(algorithm_id)->getIsRunning()) {
		getAlgorithm(algorithm_id)->mtx.lock();
		algorithms_map[algorithm_id].reset();
		algorithms_map.erase(algorithm_id);
		return true;
	} else {
		return false;
	}
}

bool Scheduler::deleteModel(const model_id_t model_id) {
	if (getModel(model_id)) {
		/*getModel(model_id)->mtx.lock();*/
		models_map[model_id].reset();
		models_map.erase(model_id);
		return true;
	} else {
		return false;
	}
}

bool Scheduler::deleteJob(const job_id_t job_id) {
	if (JobIdUsed(job_id) && cancelJob(job_id)) {
		// Make sure the job is not currently running.
		getJob(job_id)->algorithm->mtx.lock();
		jobs_map[job_id].reset();
		jobs_map.erase(job_id);
		return true;
	}
	return false;
}

shared_ptr<Algorithm> Scheduler::getAlgorithm(const algorithm_id_t algorithm_id) {
	if (AlgorithmIdUsed(algorithm_id)) {
		return algorithms_map[algorithm_id];
	}
	throw runtime_error("Algorithm ID does not match any algorithms.");
	return shared_ptr<Algorithm>(nullptr);
}

shared_ptr<Model> Scheduler::getModel(const model_id_t model_id) {
	if (ModelIdUsed(model_id)) {
		return models_map[model_id];
	}
	throw runtime_error("Model ID does not match any models.");
	return shared_ptr<Model>(nullptr);
}

shared_ptr<Job_t> Scheduler::getJob(const job_id_t job_id) {
	if (JobIdUsed(job_id)) {
		return jobs_map[job_id];
	}
	throw runtime_error("Job ID does not match any jobs.");
	return shared_ptr<Job_t>(nullptr);
}

MatrixXf Scheduler::getJobResult(const job_id_t job_id) {
	if (JobIdUsed(job_id)) {
		shared_ptr<Job_t> job = getJob(job_id);
		if (shared_ptr<AdaMultiLasso> model = dynamic_pointer_cast<AdaMultiLasso>(job->model)) {
	        return model->getBeta();
	    } else if (shared_ptr<Gflasso> model = dynamic_pointer_cast<Gflasso>(job->model)) {
	        return model->getBeta();
	    } else if (shared_ptr<LinearRegression> model = dynamic_pointer_cast<LinearRegression>(job->model)) {
	        return model->getBeta();
	    } else if (shared_ptr<MultiPopLasso> model = dynamic_pointer_cast<MultiPopLasso>(job->model)) {
	        return model->getBeta();
	    } else if (shared_ptr<SparseLMM> model = dynamic_pointer_cast<SparseLMM>(job->model)) {
	        return model->getBeta();
	    } else if (shared_ptr<TreeLasso> model = dynamic_pointer_cast<TreeLasso>(job->model)) {
	        return model->getBeta();
	    } else if (shared_ptr<LinearMixedModel> model = dynamic_pointer_cast<LinearMixedModel>(job->model)) {
			return model->getBeta();
		} else if (shared_ptr<FisherTest> model = dynamic_pointer_cast<FisherTest>(job->model)) {
			return model->getBeta();
		} else if (shared_ptr<Chi2Test> model = dynamic_pointer_cast<Chi2Test>(job->model)) {
			return model->getBeta();
		} else if (shared_ptr<WaldTest> model = dynamic_pointer_cast<WaldTest>(job->model)) {
			return model->getBeta();
		} else {
	    	return model->getBeta();
	    }
	} else {
		return MatrixXf();
	}
}

////////////////////////////////////////////////////////
// Private Functions
////////////////////////////////////////////////////////

model_id_t Scheduler::getNewModelId() {
	model_id_t candidate_model_id = next_model_id;
	for (unsigned int i = 1; i < kMaxModelId; i++) {
		candidate_model_id = (candidate_model_id + 1) % kMaxModelId + 1;
		if (!ModelIdUsed(candidate_model_id)) {
			model_id_t retval = next_model_id;
			next_model_id = candidate_model_id;
			return retval;
		}
	}
	return 0;
}

algorithm_id_t Scheduler::getNewAlgorithmId() {
	algorithm_id_t candidate_algorithm_id = next_algorithm_id;
	for (unsigned int i = 1; i < kMaxAlgorithmId; i++) {
		candidate_algorithm_id = (candidate_algorithm_id + 1) % kMaxAlgorithmId + 1;
		if (!AlgorithmIdUsed(candidate_algorithm_id)) {
			algorithm_id_t retval = next_algorithm_id;
			next_algorithm_id = candidate_algorithm_id;
			return retval;
		}
	}
	return 0;
}

job_id_t Scheduler::getNewJobId() {
	job_id_t candidate_job_id = next_job_id;
	for (unsigned int i = 1; i < kMaxJobId; i++) {
		candidate_job_id = (candidate_job_id + i) % kMaxJobId + 1;
		if (!JobIdUsed(candidate_job_id)) {
			job_id_t retval = next_job_id;
			next_job_id = candidate_job_id;
			return retval;
		}
	}
	return 0;
}

bool Scheduler::ValidAlgorithmId(const algorithm_id_t id) {
	return (id > 0 && id <= kMaxAlgorithmId);
}

bool Scheduler::ValidModelId(const model_id_t id) {
	return (id > 0 && id <= kMaxModelId);
}

bool Scheduler::ValidJobId(const job_id_t id) {
	return (id > 0 && id <= kMaxJobId);
}

bool Scheduler::AlgorithmIdUsed(const algorithm_id_t id) {
	return (ValidAlgorithmId(id) && algorithms_map[id] && algorithms_map[id].get());
}

bool Scheduler::ModelIdUsed(const model_id_t id) {
	return (ValidModelId(id) && models_map[id] && models_map[id].get());
}

bool Scheduler::JobIdUsed(const job_id_t id) {
	return (ValidJobId(id) && jobs_map[id] && jobs_map[id].get());
}


text:
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <boost/process/config.hpp>

#if defined(BOOST_POSIX_API)
#  include <stdlib.h>
#  include <unistd.h>
#elif defined(BOOST_WINDOWS_API)
#  include <windows.h>
#else
#  error "Unsupported platform."
#endif

#include <boost/process/self.hpp>
#include <boost/process/environment.hpp>
#include <boost/test/unit_test.hpp>

namespace bp = ::boost::process;
namespace but = ::boost::unit_test;

class launcher
{
public:
    bp::self &operator()(bp::self::id_type id)
    {
        return bp::self::get_instance();
    }
};

static void test_id()
{
    bp::self &p = bp::self::get_instance();

#if defined(BOOST_POSIX_API)
    BOOST_REQUIRE(p.get_id() == ::getpid());
#elif defined(BOOST_WINDOWS_API)
    BOOST_REQUIRE(p.get_id() == ::GetCurrentProcessId());
#endif
}

static void test_get_environment()
{
    bp::self &p = bp::self::get_instance();

    bp::environment env1 = p.get_environment();
    BOOST_CHECK(env1.find("THIS_SHOULD_NOT_BE_DEFINED") == env1.end());

#if defined(BOOST_POSIX_API)
    BOOST_REQUIRE(::setenv("THIS_SHOULD_BE_DEFINED", "some-value", 1) == 0);
#elif defined(BOOST_WINDOWS_API)
    BOOST_REQUIRE(::SetEnvironmentVariableA("THIS_SHOULD_BE_DEFINED", "some-value") != 0);
#endif

    bp::environment env2 = p.get_environment();
    bp::environment::const_iterator it = env2.find("THIS_SHOULD_BE_DEFINED");
    BOOST_CHECK(it != env2.end());
    BOOST_CHECK_EQUAL(it->second, "some-value");
}

but::test_suite *init_unit_test_suite(int argc, char *argv[])
{
    but::test_suite *test = BOOST_TEST_SUITE("self test suite");

    test->add(BOOST_TEST_CASE(&test_id));
    test->add(BOOST_TEST_CASE(&test_get_environment));

    return test;
}

max_stars_repo_name: Flusspferd/flusspferd

max_issues_repo_name: STEllAR-GROUP/octopus

max_forks_repo_name: STEllAR-GROUP/octopus


text:
#include "SummaryNode3DCollector.hpp"
#include <assert.h>
#include <boost/detail/limits.hpp>
#include "application/output/recordsets/ResultRecordset.hpp"
#include "domain/algorithms/messages/ModelStateUpdateMessage.hpp"
#include "domain/analyses/NumericalModel.hpp"
#include "domain/collections/NodeSet.hpp"

namespace aaoc = axis::application::output::collectors;
namespace aaocs = axis::application::output::collectors::summarizers;
namespace aaor = axis::application::output::recordsets;
namespace ada = axis::domain::analyses;
namespace adam = axis::domain::algorithms::messages;
namespace adc = axis::domain::collections;
namespace ade = axis::domain::elements;
namespace asmm = axis::services::messaging;
namespace afb = axis::foundation::blas;

aaocs::SummaryNode3DCollector::SummaryNode3DCollector( const axis::String& targetSetName,
                                                       SummaryType summaryType ) :
targetSetName_(targetSetName), summaryType_(summaryType)
{
  for (int i = 0; i < 3; i++) state_[i] = true;
  vectorSize_ = 3;
}
aaocs::SummaryNode3DCollector::SummaryNode3DCollector(const axis::String& targetSetName,
                                                      SummaryType summaryType,
                                                      aaoc::XDirectionState xState,
                                                      aaoc::YDirectionState yState,
                                                      aaoc::ZDirectionState zState) :
targetSetName_(targetSetName), summaryType_(summaryType)
{
  state_[0] = (xState == aaoc::kXEnabled);
  state_[1] = (yState == aaoc::kYEnabled);
  state_[2] = (zState == aaoc::kZEnabled);
  int count = 0;
  for (int i = 0; i < 3; i++) count += state_[i]? 1 : 0;
  vectorSize_ = count;
}

aaocs::SummaryNode3DCollector::~SummaryNode3DCollector( void )
{
  // nothing to do here
}

void aaocs::SummaryNode3DCollector::Collect( const asmm::ResultMessage& message,
                                           aaor::ResultRecordset& recordset,
                                           const ada::NumericalModel& numericalModel )
{
  adc::NodeSet& set = targetSetName_.empty()? numericalModel.Nodes() :
                                              numericalModel.GetNodeSet(targetSetName_);
  size_type count = set.Count();

  StartCollect();
  for (size_type idx = 0; idx < count; ++idx)
  {
    const ade::Node& node = set.GetByPosition(idx);
    for (int i = 0; i < 3; i++)
    {
      if (state_[i])
      {
        real v = CollectValue(message, node, i, numericalModel);
        switch (summaryType_)
        {
        case kAverage:
          values_[i] += v;
          break;
        case kMaximum:
          if (v > values_[i]) values_[i] = v;
          break;
        case kMinimum:
          if (v < values_[i]) values_[i] = v;
          break;
        default:
          assert(!_T("Unexpected summary type!"));
          break;
        }
      }
    }
  }
  if (summaryType_ == kAverage)
  {
    for (int i = 0; i < 3; i++)
    {
      if (state_[i]) values_[i] /= (real)count;
    }
  }
  Summarize(recordset);
}

bool aaocs::SummaryNode3DCollector::IsOfInterest( const asmm::ResultMessage& message ) const
{
  return adam::ModelStateUpdateMessage::IsOfKind(message);
}

void aaocs::SummaryNode3DCollector::StartCollect( void )
{
  for (int i = 0; i < 3; i++)
  {
    switch (summaryType_)
    {
    case kAverage:
      values_[i] = 0;
      break;
    case kMaximum:
      values_[i] = std::numeric_limits<real>::min();
      break;
    case kMinimum:
      values_[i] = std::numeric_limits<real>::max();
      break;
    default:
      assert(!_T("Unexpected summary type!"));
      break;
    }
  }
}

void aaocs::SummaryNode3DCollector::Summarize( aaor::ResultRecordset& recordset )
{
  afb::ColumnVector vector(vectorSize_);
  int relativeIdx = 0;
  for (int i = 0; i < 3; i++)
  {
    if (state_[i])
    {
      vector(relativeIdx) = values_[i];
      relativeIdx++;
    }
  }
  recordset.WriteData(vector);
}

axis::String aaocs::SummaryNode3DCollector::GetFriendlyDescription( void ) const
{
  axis::String desc;
  switch (summaryType_)
  {
  case kAverage:
    desc = _T("Average ");
    break;
  case kMaximum:
    desc = _T("Maximum ");
    break;
  case kMinimum:
    desc = _T("Minimum ");
    break;
  default:
    assert(!_T("Unexpected summary type!"));
    break;
  }
  if (vectorSize_ != 3)
  {
    axis::String directionStr;
    for (int i = 0; i < 3; i++)
    {
      if (state_[i])
      {
        if (!directionStr.empty()) directionStr += _T(", ");
        switch (i)
        {
        case 0: directionStr += _T("X"); break;
        case 1: directionStr += _T("Y"); break;
        case 2: directionStr += _T("Z"); break;
        }
      }
    }
    desc += directionStr + _T(" ");
  }

  desc += GetVariableName(vectorSize_ != 1);
  if (targetSetName_.empty())
  {
    desc += _T(" on all nodes");
  }
  else
  {
    desc += _T(" on node set '") + targetSetName_ + _T("'");
  }
  return desc;
}

max_stars_repo_name: renato-yuzup/axis-fem

max_issues_repo_name: renato-yuzup/axis-fem

max_forks_repo_name: renato-yuzup/axis-fem


text: #include <boost/mpl/set/aux_/insert_range_impl.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
/*
 * Copyright (C) 2011-2016 Daniel Scharrer
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the author(s) be held liable for any damages
 * arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    appreciated but is not required.
 * 2. Altered source versions must be plainly marked as such, and must not be
 *    misrepresented as being the original software.
 * 3. This notice may not be removed or altered from any source distribution.
 */

#include "stream/block.hpp"

#include <cstring>
#include <string>
#include <istream>
#include <algorithm>

#include <boost/cstdint.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/restrict.hpp>
#include <boost/iostreams/filter/zlib.hpp>
#include <boost/iostreams/char_traits.hpp>
#include <boost/iostreams/concepts.hpp>
#include <boost/iostreams/read.hpp>
#include <boost/make_shared.hpp>

#include "release.hpp"
#include "crypto/crc32.hpp"
#include "setup/version.hpp"
#include "stream/lzma.hpp"
#include "util/endian.hpp"
#include "util/enum.hpp"
#include "util/load.hpp"
#include "util/log.hpp"
#include "util/math.hpp"

namespace io = boost::iostreams;

namespace stream {

namespace {

enum block_compression {
	Stored,
	Zlib,
	LZMA1,
};

/*!
 * A filter that reads a block of 4096-byte chunks where each chunk is preceeded by
 * a CRC32 checksum. The last chunk can be shorter than 4096 bytes.
 *
 * If chunk checksum is wrong a block_error is thrown before any data of that
 * chunk is returned.
 *
 * block_error is also thrown if there is trailing data: 0 < (total size % (4096 + 4)) < 5
 */
class inno_block_filter : public boost::iostreams::multichar_input_filter {

private:

	typedef boost::iostreams::multichar_input_filter base_type;

public:

	typedef base_type::char_type char_type;
	typedef base_type::category category;

	inno_block_filter() : pos(0), length(0) { }

	template <typename Source>
	bool read_chunk(Source & src) {

		char temp[sizeof(boost::uint32_t)];
		std::streamsize temp_size = std::streamsize(sizeof(temp));
		std::streamsize nread = boost::iostreams::read(src, temp, temp_size);
		if(nread == EOF) {
			return false;
		} else if(size_t(nread) != sizeof(temp)) {
			throw block_error("unexpected block end");
		}
		boost::uint32_t block_crc32 = util::little_endian::load<boost::uint32_t>(temp);

		length = size_t(boost::iostreams::read(src, buffer, std::streamsize(sizeof(buffer))));
		if(length == size_t(EOF)) {
			throw block_error("unexpected block end");
		}

		crypto::crc32 actual;
		actual.init();
		actual.update(buffer, length);
		if(actual.finalize() != block_crc32) {
			throw block_error("block CRC32 mismatch");
		}

		pos = 0;

		return true;
	}

	template <typename Source>
	std::streamsize read(Source & src, char * dest, std::streamsize n) {

		std::streamsize read = 0;
		while(n) {

			if(pos == length && !read_chunk(src)) {
				return read ? read : EOF;
			}

			std::streamsize size = std::min(n, std::streamsize(length - pos));

			std::copy(buffer + pos, buffer + pos + size, dest + read);

			pos += size_t(size), n -= size, read += size;
		}

		return read;
	}

private:

	size_t pos; //! Current read position in the buffer.
	size_t length; //! Length of the buffer. This is always 4096 except for the last chunk.
	char buffer[4096];

};

} // anonymous namespace

} // namespace stream

NAMED_ENUM(stream::block_compression)

NAMES(stream::block_compression, "Compression",
	"stored",
	"zlib",
	"lzma1",
)

namespace stream {

block_reader::pointer block_reader::get(std::istream & base, const setup::version & version) {

	USE_ENUM_NAMES(block_compression)

	boost::uint32_t expected_checksum = util::load<boost::uint32_t>(base);
	crypto::crc32 actual_checksum;
	actual_checksum.init();

	boost::uint32_t stored_size;
	block_compression compression;

	if(version >= INNO_VERSION(4, 0, 9)) {

		stored_size = actual_checksum.load<boost::uint32_t>(base);
		boost::uint8_t compressed = actual_checksum.load<boost::uint8_t>(base);

		compression = compressed ? (version >= INNO_VERSION(4, 1, 6) ? LZMA1 : Zlib) : Stored;

	} else {

		boost::uint32_t compressed_size = actual_checksum.load<boost::uint32_t>(base);
		boost::uint32_t uncompressed_size = actual_checksum.load<boost::uint32_t>(base);

		if(compressed_size == boost::uint32_t(-1)) {
			stored_size = uncompressed_size, compression = Stored;
		} else {
			stored_size = compressed_size, compression = Zlib;
		}

		// Add the size of a CRC32 checksum for each 4KiB subblock.
		stored_size += boost::uint32_t(util::ceildiv<boost::uint64_t>(stored_size, 4096) * 4);
	}

	if(actual_checksum.finalize() != expected_checksum) {
		throw block_error("block header CRC32 mismatch");
	}

	debug("[block] size: " << stored_size << "  compression: " << compression);

	util::unique_ptr<io::filtering_istream>::type fis(new io::filtering_istream);

	switch(compression) {
		case Stored: break;
		case Zlib: fis->push(io::zlib_decompressor(), 8192); break;
	#if INNOEXTRACT_HAVE_LZMA
		case LZMA1: fis->push(inno_lzma1_decompressor(), 8192); break;
	#else
		case LZMA1: throw block_error("LZMA decompression not supported by this "
			                  + std::string(innoextract_name) + " build");
	#endif
	}

	fis->push(inno_block_filter(), 4096);

	fis->push(io::restrict(base, 0, stored_size));

	fis->exceptions(std::ios_base::badbit | std::ios_base::failbit);

	return pointer(fis.release());
}

} // namespace stream

max_stars_repo_name: lool/innoextract

max_issues_repo_name: lool/innoextract

max_forks_repo_name: lool/innoextract


text:
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE utils

#include <chrono>
#include <boost/test/unit_test.hpp>
#include <http_parser/utils/cvt.hpp>

using namespace std::literals;

BOOST_AUTO_TEST_SUITE(utils)

BOOST_AUTO_TEST_CASE(to_int_10)
{
	using http_parser::to_int;
	BOOST_TEST(to_int(""sv) == 0);
	BOOST_TEST(to_int("0"sv) == 0);
	BOOST_TEST(to_int("1"sv) == 1);
	BOOST_TEST(to_int("10"sv) == 10);
	BOOST_TEST(to_int("99999999"sv) == 99999999);

	BOOST_TEST(to_int("-1"sv) == -1);
	BOOST_TEST(to_int("-"sv) == 0);
	BOOST_TEST(to_int("-99999999"sv) == -99999999);

	BOOST_TEST(to_int("Af30"sv, 16) == 0xaf30);
	BOOST_TEST(to_int("-a"sv, 16) == -0x0a);
}

BOOST_AUTO_TEST_CASE(to_str_16)
{
	using http_parser::to_str16;
	using http_parser::to_str16c;
	BOOST_TEST(to_str16c<std::string>(0x100A) == "100a"s);
	BOOST_TEST(to_str16c<std::string>(-0xABCD) == "-abcd"s);
	BOOST_TEST(to_str16c<std::string>(0x00) == "0"s);

	BOOST_CHECK(to_str16c<std::wstring>(-0xABCD) == L"-abcd"s);
	BOOST_CHECK(to_str16c<std::wstring>(-0xABCD) == L"-abcd"s);

	std::string to;
	BOOST_TEST(to_str16((std::uint16_t)11, to, true) == "000b");
	to.clear();
	BOOST_TEST(to_str16((std::uint8_t)11, to, true) == "0b");
}

BOOST_AUTO_TEST_CASE(is_hex)
{
	using http_parser::is_hex_digit;
	BOOST_TEST(is_hex_digit('-') == true);

	BOOST_TEST(is_hex_digit('0') == true);
	BOOST_TEST(is_hex_digit('9') == true);
	BOOST_TEST(is_hex_digit('a') == true);
	BOOST_TEST(is_hex_digit('f') == true);
	BOOST_TEST(is_hex_digit('A') == true);
	BOOST_TEST(is_hex_digit('F') == true);

	BOOST_TEST(is_hex_digit('g') == false);
	BOOST_TEST(is_hex_digit('G') == false);
	BOOST_TEST(is_hex_digit(';') == false);
	BOOST_TEST(is_hex_digit('z') == false);
}

BOOST_AUTO_TEST_CASE(to_url_form)
{
	using http_parser::format_to_url;
	std::string to;
	BOOST_TEST(format_to_url(to, "a?\n"sv) == "a%3f%0a"sv);
	to.clear();
	BOOST_TEST(format_to_url(to, "ъ"sv) == "%d1%8a"sv);
}

BOOST_AUTO_TEST_CASE(from_url_form)
{
	using http_parser::format_from_url;
	std::string to;
	BOOST_TEST(format_from_url(to, "a%3f%0a"sv) == "a?\n");
	to.clear();
	BOOST_TEST(format_from_url(to, "%d1%8a"sv) == "ъ");
}

BOOST_AUTO_TEST_SUITE_END() // utils


text:
/*******************************************************************************
 *         Copyright 2003 & onward LASMEA UMR 6602 CNRS/Univ. Clermont II
 *         Copyright 2009 & onward LRI    UMR 8623 CNRS/Univ Paris Sud XI
 *
 *          Distributed under the Boost Software License, Version 1.0.
 *                 See accompanying file LICENSE.txt or copy at
 *                     http://www.boost.org/LICENSE_1_0.txt
 ******************************************************************************/
#ifndef NT2_SDK_TIMING_IMPL_NONE_HPP_INCLUDED
#define NT2_SDK_TIMING_IMPL_NONE_HPP_INCLUDED

#if !defined(NT2_TIMING_DETECTED)

#define NT2_TIMING_DETECTED
#include <ctime>
#include <boost/cstdint.hpp>

namespace nt2
{
  namespace details
  {
    inline double now()
    {
      return std::clock()/double(CLOCKS_PER_SEC);
    }
  }
}
#endif

#endif


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

#ifndef _RPC_SocketHandler
#define _RPC_SocketHandler
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

class SocketHandler : public std::enable_shared_from_this<SocketHandler> {
private:
  tcp::socket socket;
  std::unique_ptr<boost::asio::streambuf> data = std::unique_ptr<boost::asio::streambuf>(new boost::asio::streambuf());
  void do_read();
  void do_write(std::string response);

public:
  SocketHandler(tcp::socket socket) : socket(std::move(socket)) { }
  void Start() {
    do_read();
  }
};

#endif // !_RPC_SocketHandler

max_stars_repo_name: Dreae/sm-ext-rpc

max_issues_repo_name: Dreae/sm-ext-rpc

max_forks_repo_name: Dreae/sm-ext-rpc


text:
#include "icecream.hpp"

#include <vector>
#include <list>
#include <map>
#include <sstream>
#include <cstddef>
#include <limits>

#if defined (CPP_17)
#include <optional>
#include <variant>
#endif

#define CATCH_CONFIG_MAIN
#include "catch.hpp"

auto test_empty_ic() -> void
{
    IC();
}

struct NonPrintable
{};

template <typename T>
struct MyIterable
{
    std::vector<T> v;

    auto begin() const -> decltype(v.begin())
    {
        return v.begin();
    }

    auto end() const -> decltype(v.end())
    {
        return v.end();
    }
};

class MyClass
{
public:
    MyClass() = delete;
    MyClass(const MyClass &other) = delete;
    MyClass(MyClass &&other) = delete;
    MyClass& operator=(const MyClass &other) = delete;
    MyClass& operator=(MyClass &&other) = delete;

    explicit MyClass(int i_)
        : i {i_}
    {}

    int i;

    friend auto operator<<(std::ostream& os, MyClass const& self) -> std::ostream&
    {
     os << "<MyClass " << self.i << ">";
     return os;
    }
};

auto sum(int i0, int i1) -> int
{
    return i0 + i1;
}

// -------------------------------------------------- Test base
TEST_CASE("base")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    auto i0 = int {7};
    auto d0 = double {3.14};
    auto v0 = std::vector<int> {1, 2, 3, 4, 5};
    MyClass mc {20};

    {
        icecream::ic.disable();
        IC(i0);
        REQUIRE(sstr.str() == "");
        sstr.str("");
        icecream::ic.enable();
    }

    {
        test_empty_ic();
        REQUIRE_THAT(sstr.str(), Catch::StartsWith("ic| test.cpp:21 in"));
        REQUIRE_THAT(sstr.str(), Catch::Contains("test_empty_ic("));
        sstr.str("");
    }

    {
        IC(i0);
        REQUIRE(sstr.str() == "ic| i0: 7\n");
        sstr.str("");
    }

    {
        IC(i0, d0);
        REQUIRE(sstr.str() == "ic| i0: 7, d0: 3.14\n");
        sstr.str("");
    }

    {
        IC(i0, d0, 10, 30);
        REQUIRE(sstr.str() == "ic| i0: 7, d0: 3.14, 10: 10, 30: 30\n");
        sstr.str("");
    }

    {
        IC((sum(40, 2)), i0   , (((sum(3, 5)))));
        REQUIRE(sstr.str() == "ic| (sum(40, 2)): 42, i0: 7, (((sum(3, 5)))): 8\n");
        sstr.str("");
    }

    {
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: [1, 2, 3, 4, 5]\n");
        sstr.str("");
    }

    {
        IC(mc);
        REQUIRE(sstr.str() == "ic| mc: <MyClass 20>\n");
        sstr.str("");
    }
}

// -------------------------------------------------- Test return
TEST_CASE("return")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    {
        auto v0 = IC(7);
        REQUIRE(std::is_same<decltype(v0), int>::value);
        REQUIRE(v0 == 7);
    }

    {
        auto v0 = 'r';
        auto v1 = IC(v0);
        REQUIRE(std::is_same<decltype(v1), char>::value);
        REQUIRE(v1 == 'r');
    }

    {
        auto v0 = IC(7, 3.14);
        REQUIRE(std::is_same<decltype(v0), std::tuple<int, double>>::value);
        REQUIRE(v0 == std::make_tuple(7, 3.14));
    }

    {
        REQUIRE(std::is_same<decltype(IC()), void>::value);
    }

}

// -------------------------------------------------- Test optional

#include <boost/optional.hpp>
#include <boost/optional/optional_io.hpp>

TEST_CASE("boost_optional")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    auto b0 = boost::optional<double> {20.0};
    auto b1 = boost::optional<double> {};

    IC(b0);
    // The boost implementation of operator<<(ostream, optional<T>) will print an extra
    // space before the optional content.
    REQUIRE(sstr.str() == "ic| b0:  20\n");
    sstr.str("");

    IC(b1);
    REQUIRE(sstr.str() == "ic| b1: --\n");
    sstr.str("");
}

#if defined(CPP_17)
auto operator<<(std::ostream& os, std::optional<MyClass> const& value) -> std::ostream&
{
    os << "||opt MyClass|| ";
    if (value.has_value())
    {
        os << *value;
    }
    else
    {
        os << "nullopt";
    }
    return os;
}

TEST_CASE("std_optional")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    auto s0 = std::optional<int> {10};
    auto s1 = std::optional<int> {};
    auto s2 = std::optional<MyClass> {1};

    IC(s0);
    REQUIRE(sstr.str() == "ic| s0: 10\n");
    sstr.str("");

    IC(s1);
    REQUIRE(sstr.str() == "ic| s1: nullopt\n");
    sstr.str("");

    IC(s2);
    REQUIRE(sstr.str() == "ic| s2: ||opt MyClass|| <MyClass 1>\n");
    sstr.str("");
}
#endif

// -------------------------------------------------- Test variant

#include <boost/variant2/variant.hpp>

TEST_CASE("boost_variant2")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    {
        auto v0 = boost::variant2::variant<int, double, char> {6.28};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: 6.28\n");
        sstr.str("");
    }

}

#if defined(CPP_17)
TEST_CASE("std_variant")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    {
        auto v0 = std::variant<int, double, char> {3.14};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: 3.14\n");
        sstr.str("");
    }
}
#endif

// -------------------------------------------------- Test tuples

#include <utility>
namespace std
{
auto operator<<(std::ostream& os, std::pair<std::string, char> const& value) -> std::ostream&
{
    os << "{" << value.first << ", " << value.second << "}";
    return os;
}
}

TEST_CASE("tuples")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    {
        auto s0 = std::pair<int, char> {5, 'a'};
        IC(s0);
        REQUIRE(sstr.str() == "ic| s0: (5, 'a')\n");
        sstr.str("");
    }

    {
        auto s0 = std::make_pair(std::string{"oi"}, 'b');
        IC(s0);
        REQUIRE(sstr.str() == "ic| s0: {oi, b}\n"); // will use the function above
        sstr.str("");
    }

    {
        auto s0 = std::pair<int, double> {10, 3.14};
        IC(s0);
        REQUIRE(sstr.str() == "ic| s0: (10, 3.14)\n");
        sstr.str("");
    }

    {
        auto s0 = std::make_tuple(1, 2.2, 'b', "bla");
        IC(s0);
        REQUIRE(sstr.str() == "ic| s0: (1, 2.2, 'b', \"bla\")\n");
        sstr.str("");
    }
}

// -------------------------------------------------- Test arrays
TEST_CASE("arrays")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    {
        int v0[] = {1, 2, 3};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: [1, 2, 3]\n");
        sstr.str("");
    }

    {
        char v0[] = {'1', '2', '3'};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: ['1', '2', '3']\n");
        sstr.str("");
    }

    {
        char v0[] = "abc";
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: ['a', 'b', 'c', '\\0']\n");
        sstr.str("");
    }
}

// -------------------------------------------------- Test iterable

auto operator<<(std::ostream& os, MyIterable<NonPrintable> const&) -> std::ostream&
{
     os << "B<A>";
     return os;
}

TEST_CASE("iterable")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    {
        auto v0 = std::list<int> {10, 20, 30};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: [10, 20, 30]\n");
        sstr.str("");
    }

    {
        auto v0 = std::vector<float> {1.1, 1.2};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: [1.1, 1.2]\n");
        sstr.str("");
    }

    {
        int v0[] = {1, 2, 3};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: [1, 2, 3]\n");
        sstr.str("");
    }

    {
        auto v0 = MyIterable<NonPrintable> {};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: B<A>\n");
        sstr.str("");
    }
}

// -------------------------------------------------- Test pointer like
#include <boost/smart_ptr.hpp>

TEST_CASE("pointer_like")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    {
        auto v0 = std::unique_ptr<int> {new int {10}};
        IC(v0);
        REQUIRE_THAT(sstr.str(), Catch::Matches("ic\\| v0: (0x)*[0-9a-fA-F]+\n"));
        sstr.str("");
    }

    {
        auto v0 = std::make_shared<int>(7);
        IC(v0);
        REQUIRE_THAT(sstr.str(), Catch::Matches("ic\\| v0: (0x)*[0-9a-fA-F]+\n"));
        sstr.str("");
    }

    {
        auto v0 = boost::make_shared<int>(33);
        IC(v0);
        REQUIRE_THAT(sstr.str(), Catch::Matches("ic\\| v0: (0x)*[0-9a-fA-F]+\n"));
        sstr.str("");
    }

    {
        boost::scoped_ptr<int> v0 {new int {33}};
        IC(v0);
        REQUIRE_THAT(sstr.str(), Catch::Matches("ic\\| v0: (0x)*[0-9a-fA-F]+\n"));
        sstr.str("");
    }

    {
        int* v0 = new int {40};
        IC(v0);
        REQUIRE_THAT(sstr.str(), Catch::Matches("ic\\| v0: (0x)*[0-9a-fA-F]+\n"));
        sstr.str("");
        delete v0;
    }

    {
        float* v0 = nullptr;
        IC(v0);
        REQUIRE_THAT(sstr.str(), Catch::Matches("ic\\| v0: (0x)*0+\n"));
        sstr.str("");
    }

    {
        auto v0 = std::unique_ptr<double> {};
        IC(v0);
        REQUIRE_THAT(sstr.str(), Catch::Matches("ic\\| v0: (0x)*0+\n"));
        sstr.str("");
    }

    {
        auto v0 = std::make_shared<int>(7);
        auto v1 = std::weak_ptr<int> {v0};
        IC(v1);
        REQUIRE_THAT(sstr.str(), Catch::Matches("ic\\| v1: (0x)*[0-9a-fA-F]+\n"));
        sstr.str("");

        v0.reset();
        IC(v1);
        REQUIRE(sstr.str() == "ic| v1: expired\n");
        sstr.str("");
    }

}

// -------------------------------------------------- Test prefix
TEST_CASE("prefix")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    {
        icecream::ic.prefix("pref -> ");
        IC(1, 2);
        REQUIRE(sstr.str() == "pref -> 1: 1, 2: 2\n");
        sstr.str("");
    }

    {
        icecream::ic.prefix([](){return "icecream -- ";});
        IC(1, 2);
        REQUIRE(sstr.str() == "icecream -- 1: 1, 2: 2\n");
        sstr.str("");
    }

    {
        icecream::ic.prefix("ic ", []{return 5;}, "| ");
        IC(1, 2);
        REQUIRE(sstr.str() == "ic 5| 1: 1, 2: 2\n");
        sstr.str("");
    }

    {
        icecream::ic.prefix("ic| ");
        IC(1, 2);
        REQUIRE(sstr.str() == "ic| 1: 1, 2: 2\n");
        sstr.str("");
    }
}

// -------------------------------------------------- Test character
TEST_CASE("character")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    {
        auto v0 = char {'a'};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: 'a'\n");
        sstr.str("");
    }
#if !defined(__APPLE__)
    {
        auto v0 = wchar_t {L'a'};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: 'a'\n");
        sstr.str("");
    }

#if defined(__cpp_char8_t)
    {
        auto v0 = char8_t {u8'a'};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: 'a'\n");
        sstr.str("");
    }
#endif

    {
        auto v0 = char16_t {u'a'};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: 'a'\n");
        sstr.str("");
    }

    {
        auto v0 = char32_t {U'a'};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: 'a'\n");
        sstr.str("");
    }

    {
        auto v0 = char16_t {u'\0'};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: '\\0'\n");
        sstr.str("");
    }

    {
        auto v0 = char32_t {u'\t'};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: '\\t'\n");
        sstr.str("");
    }
#endif
}

// -------------------------------------------------- Test std::string
TEST_CASE("std_string")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    {
        auto v0 = std::string {"str 1"};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: \"str 1\"\n");
        sstr.str("");
    }
#if !defined(__APPLE__)
    {
        auto v0 = std::wstring {L"wstr 1"};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: \"wstr 1\"\n");
        sstr.str("");
    }

    {
        auto v0 = std::u16string {u"u16str 1"};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: \"u16str 1\"\n");
        sstr.str("");
    }

    {
        auto v0 = std::u32string {U"u32str 1"};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: \"u32str 1\"\n");
        sstr.str("");
    }
#endif
}

// -------------------------------------------------- Test std::string_view
#if defined (CPP_17)
TEST_CASE("std_string_view")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    {
        auto v0 = std::string_view {"str 1"};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: \"str 1\"\n");
        sstr.str("");
    }
#if !defined(__APPLE__)
    {
        auto v0 = std::wstring_view {L"wstr 1"};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: \"wstr 1\"\n");
        sstr.str("");
    }

    {
        auto v0 = std::u16string_view {u"u16str 1"};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: \"u16str 1\"\n");
        sstr.str("");
    }

    {
        auto v0 = std::u32string_view {U"u32str 1"};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: \"u32str 1\"\n");
        sstr.str("");
    }
#endif
}
#endif

// -------------------------------------------------- Test C string
TEST_CASE("c_string")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    icecream::ic.show_c_string(true);

    {
        char const* v0 = "Icecream test";
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: \"Icecream test\"\n");
        sstr.str("");
    }

    {
        char const* const v0 = "Icecream test";
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: \"Icecream test\"\n");
        sstr.str("");
    }

    {
        char v0[] = "string 2";
        char* const v1 = v0;
        IC(v1);
        REQUIRE(sstr.str() == "ic| v1: \"string 2\"\n");
        sstr.str("");
    }

    {
        char const* v0 = "Icecream test";
        char const*& v1 = v0;
        IC(v1);
        REQUIRE(sstr.str() == "ic| v1: \"Icecream test\"\n");
        sstr.str("");
    }

    {
        char const* const v0 = "string 5";
        icecream::ic.show_c_string(false);
        IC(v0);
        REQUIRE_THAT(sstr.str(), Catch::Matches("ic\\| v0: (0x)*[0-9a-fA-F]+\n"));
        sstr.str("");
        icecream::ic.show_c_string(true);
    }
#if !defined(__APPLE__)
    {
        wchar_t const* v0 = L"wchar_t test";
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: \"wchar_t test\"\n");
        sstr.str("");
    }

    {
        char16_t const* v0 = u"char16_t test";
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: \"char16_t test\"\n");
        sstr.str("");
    }

    {
        char16_t const* v0 = u"char16_t test";
        icecream::ic.show_c_string(false);
        IC(v0);
        REQUIRE_THAT(sstr.str(), Catch::Matches("ic\\| v0: (0x)*[0-9a-fA-F]+\n"));
        sstr.str("");
        icecream::ic.show_c_string(true);
    }

    {
        char32_t const* const v0 = U"char32_t test";
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: \"char32_t test\"\n");
        sstr.str("");
    }
#endif
}

// -------------------------------------------------- Test line wrap

TEST_CASE("line_wrap")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    icecream::ic.line_wrap_width(20);

    {
        auto v0 = std::vector<float> {1.1, 1.2};
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: [1.1, 1.2]\n");
        sstr.str("");
    }

    {
        auto v0 = std::list<int> {10, 20, 30, 40, 50, 60};
        auto const result =
            "ic| v0: [\n"
            "        10,\n"
            "        20,\n"
            "        30,\n"
            "        40,\n"
            "        50,\n"
            "        60\n"
            "    ]\n";
        IC(v0);
        REQUIRE(sstr.str() == result);
        sstr.str("");
    }

    {
        auto v0 = std::vector<std::vector<int>> {{1, 2}, {10, 20, 30, 40, 50, 60}, {3, 4}};
        auto const result =
            "ic| v0: [\n"
            "        [1, 2],\n"
            "        [\n"
            "            10,\n"
            "            20,\n"
            "            30,\n"
            "            40,\n"
            "            50,\n"
            "            60\n"
            "        ],\n"
            "        [3, 4]\n"
            "    ]\n";
        IC(v0);
        REQUIRE(sstr.str() == result);
        sstr.str("");
    }

    {
        icecream::ic.prefix("pref -> ");
        auto v0 = std::vector<float> {1.1, 1.2};
        auto v1 = std::vector<int> {11, 12};
        auto const result =
            "pref -> v0: [\n"
            "        1.1,\n"
            "        1.2\n"
            "    ]\n"
            "    v1: [11, 12]\n";
        IC(v0, v1);
        REQUIRE(sstr.str() == result);
        sstr.str("");
        icecream::ic.prefix("ic| ");
    }

    icecream::ic.line_wrap_width(70);
}

// -------------------------------------------------- Test exception

#include <boost/exception/all.hpp>

class exception
    : public virtual std::exception
    , public virtual boost::exception
{
public:
    exception()
        : std::exception()
        , boost::exception()
    {}

    virtual char const* what() const noexcept
    {
        return "what info";
    }
};

using StringInfo = boost::error_info<struct StringTag, std::string>;
using IntInfo = boost::error_info<struct IntTag, int>;

TEST_CASE("exception")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    {
        auto v0 = std::runtime_error("ble");
        IC(v0);
        REQUIRE(sstr.str() == "ic| v0: ble\n");
        sstr.str("");
    }

    {
        try
        {
            BOOST_THROW_EXCEPTION(exception {} << IntInfo {10});
        }
        catch (exception& e)
        {
            e << StringInfo {"bla_string"};
            IC(e);
            REQUIRE_THAT(sstr.str(),
                Catch::Contains("IntTag")
                && Catch::Contains("] = 10")
                && Catch::Contains("StringTag")
                && Catch::Contains("] = bla_string")
                && Catch::Contains("ic| e: what info")
            );
        }
    }
}

#if defined(ICECREAM_DUMP_STRUCT_CLANG)
#include <cwctype>
#include <cstdint>

template <typename T>
auto lowest() -> T
{
    return std::numeric_limits<T>::lowest();
}

template <typename T>
auto str_lowest() -> std::string
{
    return std::to_string(std::numeric_limits<T>::lowest());
}

template <typename T>
auto max() -> T
{
    return std::numeric_limits<T>::max();
}

template <typename T>
auto str_max() -> std::string
{
    return std::to_string(std::numeric_limits<T>::max());
}

TEST_CASE("dump_string")
{
    auto sstr = std::stringstream {};
    icecream::ic.stream().rdbuf(sstr.rdbuf());

    {
        struct S0
        {
            bool v_bool0;
            bool v_bool1;
            char v_char;
            signed char v_schar;
            unsigned char v_uchar;
        #if !defined(__APPLE__)
            wchar_t v_wchart;
            wchar_t const* v_pwchar;
            char16_t v_char16_t;
            char16_t const* v_pchar16_t;
            char32_t v_char32_t;
            char32_t const* v_pchar32_t;
        #endif
            char const* v_pchar;
        };
        auto v0 = S0 {
            false,         // v_bool0
            true,          // v_bool1
            'z',           // v_char
            -20,           // v_schar;
            200,           // v_uchar;
        #if !defined(__APPLE__)
            L'w',          // v_wchart
            L"wchar test", // v_pwchart
            u'r',          // v_char16_t
            u"pchar16",    // v_pchar16_t
            U'R',          // v_char32_t
            U"pchar32",    // v_pchar32_t
        #endif
            "test",        // v_pchar
        };
        auto const result =
            "ic| v0: {\n"
            "        v_bool0: 0,\n"
            "        v_bool1: 1,\n"
            "        v_char: 'z',\n"
            "        v_schar: -20,\n"
            "        v_uchar: 200,\n"
        #if !defined(__APPLE__)
            "        v_wchart: 'w',\n"
            "        v_pwchar: \"wchar test\",\n"
            "        v_char16_t: 'r',\n"
            "        v_pchar16_t: \"pchar16\",\n"
            "        v_char32_t: 'R',\n"
            "        v_pchar32_t: \"pchar32\",\n"
        #endif
            "        v_pchar: \"test\"\n"
            "    }\n";
        IC(v0);
        REQUIRE(sstr.str() == result);
        sstr.str("");
    }

    {
        struct S0
        {
            signed char v_sigchar;
            short v_short;
            int v_int;
            long v_long;
            long long v_longlong;
            std::intmax_t v_intmax_t;
            std::ptrdiff_t v_ptrdiff_t;
        };
        auto v0 = S0 {
            lowest<signed char>(),    // v_sigchar
            lowest<short>(),          // v_short
            lowest<int>(),            // v_int
            lowest<long>(),           // v_long
            lowest<long long>(),      // v_longlong
            lowest<std::intmax_t>(),  // v_intmax_t
            lowest<std::ptrdiff_t>(), // v_ptrdiff_t
        };
        auto const result =
            "ic| v0: {\n"
            "        v_sigchar: " + str_lowest<signed char>() + ",\n"
            "        v_short: " + str_lowest<short>() + ",\n"
            "        v_int: " + str_lowest<int>() + ",\n"
            "        v_long: " + str_lowest<long>() + ",\n"
            "        v_longlong: " + str_lowest<long long>() + ",\n"
            "        v_intmax_t: " + str_lowest<std::intmax_t>() + ",\n"
            "        v_ptrdiff_t: " + str_lowest<std::ptrdiff_t>() + "\n"
            "    }\n";
        IC(v0);
        REQUIRE(sstr.str() == result);
        sstr.str("");
    }

    {
        struct S0
        {
            unsigned char v_unsigchar;
            unsigned short v_unsigshort;
            unsigned int v_unsigint;
            unsigned long v_unsiglong;
            unsigned long long v_unsiglonglong;
            std::uintmax_t v_uintmax_t;
            std::size_t v_size_t;
        };
        auto v0 = S0 {
            max<unsigned char>(),      // v_unsigchar
            max<unsigned short>(),     // v_unsigshort
            max<unsigned int>(),       // v_unsigint
            max<unsigned long>(),      // v_unsiglong
            max<unsigned long long>(), // v_unsiglonglong
            max<std::uintmax_t>(),     // v_uintmax_t
            max<std::size_t>(),        // v_size_t
        };
        auto const result =
            "ic| v0: {\n"
            "        v_unsigchar: " + str_max<unsigned char>() + ",\n"
            "        v_unsigshort: " + str_max<unsigned short>() + ",\n"
            "        v_unsigint: " + str_max<unsigned int>() + ",\n"
            "        v_unsiglong: " + str_max<unsigned long>() + ",\n"
            "        v_unsiglonglong: " + str_max<unsigned long long>() + ",\n"
            "        v_uintmax_t: " + str_max<std::uintmax_t>() + ",\n"
            "        v_size_t: " + str_max<std::size_t>() + "\n"
            "    }\n";
        IC(v0);
        REQUIRE(sstr.str() == result);
        sstr.str("");
    }

    {
        struct S0
        {
            float v_float;
            double v_double;
            long double v_longdouble;
        };
        auto v0 = S0 {
            -60.6,  // v_float
            -70.7,  // v_double
            100.1   // v_longdouble
        };
        auto const result = "ic| v0: {v_float: -60.6, v_double: -70.7, v_longdouble: 100.1}\n";
        IC(v0);
        REQUIRE(sstr.str() == result);
        sstr.str("");
    }

    {
        using MyFloat = float;
        using MyDouble = double;
        struct S0
        {
            MyFloat v_float0;
            double v_double0;
            MyFloat v_float1;
            MyDouble v_double1;
            double v_double2;
            float v_float2;
            long double v_longdouble;
        };
        auto v0 = S0 {
            -60.6,  // v_float0
            -70.7,  // v_double0
            60.6,   // v_float1
            70.7,   // v_double1
            3.14,   // v_double2
            10.01,  // v_float2
            200.002 // v_longdouble
        };
        auto const result =
            "ic\\| v0: \\{\n"
            "        v_float0: [0-9e\\-+.]+ <NOT RELIABLE, see issue #6 on github>,\n"
            "        v_double0: -70\\.7,\n"
            "        v_float1: [0-9e\\-+.]+ <NOT RELIABLE, see issue #6 on github>,\n"
            "        v_double1: 70\\.7 <NOT RELIABLE, see issue #6 on github>,\n"
            "        v_double2: 3\\.14,\n"
            "        v_float2: 10\\.01,\n"
            "        v_longdouble: 200\\.002\n"
            "    \\}\n";

        IC(v0);
        REQUIRE_THAT(sstr.str(), Catch::Matches(result));
        sstr.str("");
    }

    {
        using MyFloat = float;
        struct S0
        {
            bool v_bool[10];

            short const v_sint[2];
            short unsigned v_usint[2];
            int const v_int[3];
            unsigned int v_uint[2];
            long int v_lint[2];
            unsigned long int v_ulint[2];
            long long int v_llint[2];
            unsigned long const long int v_ullint[2];
            signed char v_schar[2];
            unsigned char v_uchar[2];

            char v_char[4];
        #if !defined(__APPLE__)
            wchar_t v_wchar[6];
            char16_t v_char16[3];
            char32_t v_char32[4];
        #endif

            float v_float[2];
            MyFloat mfloat[2];
            double v_double[3];
            long double v_ldouble[3];

            int* v_pint[3];
        };
        auto v0 = S0 {
            {true, true, false, true, false, false, false, true, true, true},  // v_sint
            {lowest<short int>(), max<short int>()},                           // v_sint
            {lowest<unsigned short int>(), max<unsigned short int>()},         // v_usint
            {lowest<int>(), max<int>(), 3},                                    // v_int
            {lowest<unsigned int>(), max<unsigned int>()},                     // v_uint
            {lowest<long int>(), max<long int>()},                             // v_lint
            {lowest<unsigned long int>(), max<unsigned long int>()},           // v_ulint
            {lowest<long long int>(), max<long long int>()},                   // v_llint
            {lowest<unsigned long long int>(), max<unsigned long long int>()}, // v_ullint
            {lowest<signed char>(), max<signed char>()},                       // v_schar
            {lowest<unsigned char>(), max<unsigned char>()},                   // v_uchar

            {'c', 'h', 'a', 'r'},                                              // v_char
        #if !defined(__APPLE__)
            L"wchar",                                                          // v_wchar
            {u'1', u'2', u'3'},                                                // v_char16
            {U'3', U'a', U'b', U'c'},                                          // v_char32
        #endif

            {1.1, 1.2},                                                        // v_float
            {2.1, 2.2},                                                        // mfloat
            {3.1, 3.2, 3.3},                                                   // v_double
            {103.1, 103.2, 103.3},                                             // v_ldouble

            {(int*)0x70, (int*)0x71, (int*)0x72},                              // v_pint
        };
        IC(v0);
        auto const result =
            "ic| v0: {\n"
            "        v_bool: [1, 1, 0, 1, 0, 0, 0, 1, 1, 1],\n"
            "        v_sint: [" + str_lowest<short int>() + ", " + str_max<short int>() + "],\n"
            "        v_usint: [" + str_lowest<unsigned short int>() + ", " + str_max<unsigned short int>() + "],\n"
            "        v_int: [" + str_lowest<int>() + ", " + str_max<int>() + ", 3],\n"
            "        v_uint: [" + str_lowest<unsigned int>() + ", " + str_max<unsigned int>() + "],\n"
            "        v_lint: [" + str_lowest<long int>() + ", " + str_max<long int>() + "],\n"
            "        v_ulint: [" + str_lowest<unsigned long int>() + ", " + str_max<unsigned long int>() + "],\n"
            "        v_llint: [" + str_lowest<long long int>() + ", " + str_max<long long int>() + "],\n"
            "        v_ullint: [" + str_lowest<unsigned long long int>() + ", " + str_max<unsigned long long int>() + "],\n"
            "        v_schar: [" + str_lowest<signed char>() + ", " + str_max<signed char>() + "],\n"
            "        v_uchar: [" + str_lowest<unsigned char>() + ", " + str_max<unsigned char>() + "],\n"
            "        v_char: ['c', 'h', 'a', 'r'],\n"
        #if !defined(__APPLE__)
            "        v_wchar: ['w', 'c', 'h', 'a', 'r', '\\0'],\n"
            "        v_char16: ['1', '2', '3'],\n"
            "        v_char32: ['3', 'a', 'b', 'c'],\n"
        #endif
            "        v_float: [1.1, 1.2],\n"
            "        mfloat: <type aliased array, see issue #7 on github>,\n"
            "        v_double: [3.1, 3.2, 3.3],\n"
            "        v_ldouble: [103.1, 103.2, 103.3],\n"
            "        v_pint: [0x70, 0x71, 0x72]\n"
            "    }\n";
        REQUIRE(sstr.str() == result);
        sstr.str("");
    }

    {
        struct S0
        {
            int * const* ** *const* *const * i;
            const double* d;
        };
        auto v0 = S0 {
            nullptr,
            (double*)0x56,
        };
        IC(v0);
        auto const result = "ic\\| v0: \\{i: (0x)*0+, d: (0x)*56\\}\n";
        REQUIRE_THAT(sstr.str(), Catch::Matches(result));
        sstr.str("");
    }

    {
        struct S0
        {
            double double0;

            struct S1
            {
                char ch1;
                int i1;
            } s1;

            struct S2
            {
                char ch2;

                struct S3
                {
                    float float3;
                    int int3;
                } s1;

                int i2;
            } s2;
        };

        auto v0 = S0 {60.6, {'a', 1}, {'b', {3.14, 7}, 9}};
        IC(v0);
        auto const result =
            "ic| v0: {\n"
            "        double0: 60.6,\n"
            "        s1: {ch1: 'a', i1: 1},\n"
            "        s2: {ch2: 'b', s1: {float3: 3.14, int3: 7}, i2: 9}\n"
            "    }\n";
        REQUIRE(sstr.str() == result);
        sstr.str("");
    }

    {
        enum EN
        {
            ZERO,
            UM,
            DOIS,
            TRES
        };

        struct S0
        {
            EN en;
        };

        auto v0 = S0 {DOIS};
        IC(v0);
        auto const result =
            "ic| v0: {en: <enum member, see issue #7 on github>}\n";

        REQUIRE(sstr.str() == result);
        sstr.str("");
    }

    {
        enum EN
        {
            ZERO,
            UM,
            DOIS,
            TRES
        };

        struct S1
        {
            int i0;
            int i1;
        };

        struct S0
        {
            S1 v_s1[2];
            EN v_en[3];
        };
        auto v0 = S0 {{{10, 11}, {21, 22}}, {TRES, ZERO, UM}};
        IC(v0);
        auto const result =
            "ic| v0: {\n"
            "        v_s1: <array of structs, see issue #7 on github>,\n"
            "        v_en: <array of enums, see issue #7 on github>\n"
            "    }\n";
        REQUIRE(sstr.str() == result);
        sstr.str("");
    }

    {
        struct S0
        {
            std::int8_t v_int8[2];
            std::int16_t v_int16[2];
            std::int32_t v_int32[2];
            std::int64_t v_int64[2];

            std::uint8_t v_uint8[2];
            std::uint16_t v_uint16[2];
            std::uint32_t v_uint32[2];
            std::uint64_t v_uint64[2];

            std::size_t v_size[2];
            std::ptrdiff_t v_ptrdiff[2];
        };
        auto v0 = S0 {
            {lowest<std::int8_t>(), max<std::int8_t>()},        // v_int8
            {lowest<std::int16_t>(), max<std::int16_t>()},      // v_int16
            {lowest<std::int32_t>(), max<std::int32_t>()},      // v_int32
            {lowest<std::int64_t>(), max<std::int64_t>()},      // v_int64
            {lowest<std::uint8_t>(), max<std::uint8_t>()},      // v_uint8
            {lowest<std::uint16_t>(), max<std::uint16_t>()},    // v_uint16
            {lowest<std::uint32_t>(), max<std::uint32_t>()},    // v_uint32
            {lowest<std::uint64_t>(), max<std::uint64_t>()},    // v_uint64
            {lowest<std::size_t>(), max<std::size_t>()},        // v_size
            {lowest<std::ptrdiff_t>(), max<std::ptrdiff_t>()},  // v_ptrdiff
        };
        IC(v0);
        auto const result =
            "ic| v0: {\n"
            "        v_int8: [" + str_lowest<std::int8_t>() + ", " + str_max<std::int8_t>() + "],\n"
            "        v_int16: [" + str_lowest<std::int16_t>() + ", " + str_max<std::int16_t>() + "],\n"
            "        v_int32: [" + str_lowest<std::int32_t>() + ", " + str_max<std::int32_t>() + "],\n"
            "        v_int64: [" + str_lowest<std::int64_t>() + ", " + str_max<std::int64_t>() + "],\n"
            "        v_uint8: [" + str_lowest<std::uint8_t>() + ", " + str_max<std::uint8_t>() + "],\n"
            "        v_uint16: [" + str_lowest<std::uint16_t>() + ", " + str_max<std::uint16_t>() + "],\n"
            "        v_uint32: [" + str_lowest<std::uint32_t>() + ", " + str_max<std::uint32_t>() + "],\n"
            "        v_uint64: [" + str_lowest<std::uint64_t>() + ", " + str_max<std::uint64_t>() + "],\n"
            "        v_size: [" + str_lowest<std::size_t>() + ", " + str_max<std::size_t>() + "],\n"
            "        v_ptrdiff: [" + str_lowest<std::ptrdiff_t>() + ", " + str_max<std::ptrdiff_t>() + "]\n"
            "    }\n";
        REQUIRE(sstr.str() == result);
        sstr.str("");
    }
}
#endif

max_stars_repo_name: renatoGarcia/icecream-cpp

max_issues_repo_name: renatoGarcia/icecream-cpp

max_forks_repo_name: renatoGarcia/icecream-cpp