// fp_traits.hpp

#ifndef BOOST_MATH_FP_TRAITS_HPP
#define BOOST_MATH_FP_TRAITS_HPP

// Copyright (c) 2006 Johan Rade

// 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)

/*
To support old compilers, care has been taken to avoid partial template
specialization and meta function forwarding.
With these techniques, the code could be simplified.
*/

#if defined(__vms) && defined(__DECCXX) && !__IEEE_FLOAT
// The VAX floating point formats are used (for float and double)
#   define BOOST_FPCLASSIFY_VAX_FORMAT
#endif

#include <cstring>

#include <boost/assert.hpp>
#include <boost/cstdint.hpp>
#include <boost/detail/endian.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_floating_point.hpp>

#ifdef BOOST_NO_STDC_NAMESPACE
  namespace std{ using ::memcpy; }
#endif

#ifndef FP_NORMAL

#define FP_ZERO        0
#define FP_NORMAL      1
#define FP_INFINITE    2
#define FP_NAN         3
#define FP_SUBNORMAL   4

#else

#define BOOST_HAS_FPCLASSIFY

#ifndef fpclassify
#  if (defined(__GLIBCPP__) || defined(__GLIBCXX__)) \
         && defined(_GLIBCXX_USE_C99_MATH) \
         && !(defined(_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC) \
         && (_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC != 0))
#     ifdef _STLP_VENDOR_CSTD
#        define BOOST_FPCLASSIFY_PREFIX ::_STLP_VENDOR_CSTD::
#     else
#        define BOOST_FPCLASSIFY_PREFIX ::std::
#     endif
#  else
#     undef BOOST_HAS_FPCLASSIFY
#     define BOOST_FPCLASSIFY_PREFIX
#  endif
#elif (defined(__HP_aCC) && !defined(__hppa))
// aCC 6 appears to do "#define fpclassify fpclassify" which messes us up a bit!
#  define BOOST_FPCLASSIFY_PREFIX ::
#else
#  define BOOST_FPCLASSIFY_PREFIX
#endif

#ifdef __MINGW32__
#  undef BOOST_HAS_FPCLASSIFY
#endif

#endif

//------------------------------------------------------------------------------

namespace boost {
namespace math {
namespace detail {

//------------------------------------------------------------------------------

/*
The following classes are used to tag the different methods that are used
for floating point classification
*/

struct native_tag {};
template <bool has_limits>
struct generic_tag {};
struct ieee_tag {};
struct ieee_copy_all_bits_tag : public ieee_tag {};
struct ieee_copy_leading_bits_tag : public ieee_tag {};

#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
//
// These helper functions are used only when numeric_limits<>
// members are not compile time constants:
//
inline bool is_generic_tag_false(const generic_tag<false>&)
{
   return true;
}
inline bool is_generic_tag_false(...)
{
   return false;
}
#endif

//------------------------------------------------------------------------------

/*
Most processors support three different floating point precisions:
single precision (32 bits), double precision (64 bits)
and extended double precision (80 - 128 bits, depending on the processor)

Note that the C++ type long double can be implemented
both as double precision and extended double precision.
*/

struct unknown_precision{};
struct single_precision {};
struct double_precision {};
struct extended_double_precision {};

// native_tag version --------------------------------------------------------------

template<class T> struct fp_traits_native
{
    typedef native_tag method;
};

// generic_tag version -------------------------------------------------------------

template<class T, class U> struct fp_traits_non_native
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
   typedef generic_tag<std::numeric_limits<T>::is_specialized> method;
#else
   typedef generic_tag<false> method;
#endif
};

// ieee_tag versions ---------------------------------------------------------------

/*
These specializations of fp_traits_non_native contain information needed
to "parse" the binary representation of a floating point number.

Typedef members:

  bits -- the target type when copying the leading bytes of a floating
      point number. It is a typedef for uint32_t or uint64_t.

  method -- tells us whether all bytes are copied or not.
      It is a typedef for ieee_copy_all_bits_tag or ieee_copy_leading_bits_tag.

Static data members:

  sign, exponent, flag, significand -- bit masks that give the meaning of the
  bits in the leading bytes.

Static function members:

  get_bits(), set_bits() -- provide access to the leading bytes.

*/

// ieee_tag version, float (32 bits) -----------------------------------------------

#ifndef BOOST_FPCLASSIFY_VAX_FORMAT

template<> struct fp_traits_non_native<float, single_precision>
{
    typedef ieee_copy_all_bits_tag method;

    BOOST_STATIC_CONSTANT(uint32_t, sign        = 0x80000000u);
    BOOST_STATIC_CONSTANT(uint32_t, exponent    = 0x7f800000);
    BOOST_STATIC_CONSTANT(uint32_t, flag        = 0x00000000);
    BOOST_STATIC_CONSTANT(uint32_t, significand = 0x007fffff);

    typedef uint32_t bits;
    static void get_bits(float x, uint32_t& a) { std::memcpy(&a, &x, 4); }
    static void set_bits(float& x, uint32_t a) { std::memcpy(&x, &a, 4); }
};

// ieee_tag version, double (64 bits) ----------------------------------------------

#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) \
   || defined(__BORLANDC__) || defined(__CODEGEAR__)

template<> struct fp_traits_non_native<double, double_precision>
{
    typedef ieee_copy_leading_bits_tag method;

    BOOST_STATIC_CONSTANT(uint32_t, sign        = 0x80000000u);
    BOOST_STATIC_CONSTANT(uint32_t, exponent    = 0x7ff00000);
    BOOST_STATIC_CONSTANT(uint32_t, flag        = 0);
    BOOST_STATIC_CONSTANT(uint32_t, significand = 0x000fffff);

    typedef uint32_t bits;

    static void get_bits(double x, uint32_t& a)
    {
        std::memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
    }

    static void set_bits(double& x, uint32_t a)
    {
        std::memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
    }

private:

#if defined(BOOST_BIG_ENDIAN)
    BOOST_STATIC_CONSTANT(int, offset_ = 0);
#elif defined(BOOST_LITTLE_ENDIAN)
    BOOST_STATIC_CONSTANT(int, offset_ = 4);
#else
    BOOST_STATIC_ASSERT(false);
#endif
};

//..............................................................................

#else

template<> struct fp_traits_non_native<double, double_precision>
{
    typedef ieee_copy_all_bits_tag method;

    static const uint64_t sign     = ((uint64_t)0x80000000u) << 32;
    static const uint64_t exponent = ((uint64_t)0x7ff00000) << 32;
    static const uint64_t flag     = 0;
    static const uint64_t significand
        = (((uint64_t)0x000fffff) << 32) + ((uint64_t)0xffffffffu);

    typedef uint64_t bits;
    static void get_bits(double x, uint64_t& a) { std::memcpy(&a, &x, 8); }
    static void set_bits(double& x, uint64_t a) { std::memcpy(&x, &a, 8); }
};

#endif

#endif	// #ifndef BOOST_FPCLASSIFY_VAX_FORMAT

// long double (64 bits) -------------------------------------------------------

#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)\
   || defined(__BORLANDC__) || defined(__CODEGEAR__)

template<> struct fp_traits_non_native<long double, double_precision>
{
    typedef ieee_copy_leading_bits_tag method;

    BOOST_STATIC_CONSTANT(uint32_t, sign        = 0x80000000u);
    BOOST_STATIC_CONSTANT(uint32_t, exponent    = 0x7ff00000);
    BOOST_STATIC_CONSTANT(uint32_t, flag        = 0);
    BOOST_STATIC_CONSTANT(uint32_t, significand = 0x000fffff);

    typedef uint32_t bits;

    static void get_bits(long double x, uint32_t& a)
    {
        std::memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
    }

    static void set_bits(long double& x, uint32_t a)
    {
        std::memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
    }

private:

#if defined(BOOST_BIG_ENDIAN)
    BOOST_STATIC_CONSTANT(int, offset_ = 0);
#elif defined(BOOST_LITTLE_ENDIAN)
    BOOST_STATIC_CONSTANT(int, offset_ = 4);
#else
    BOOST_STATIC_ASSERT(false);
#endif
};

//..............................................................................

#else

template<> struct fp_traits_non_native<long double, double_precision>
{
    typedef ieee_copy_all_bits_tag method;

    static const uint64_t sign     = (uint64_t)0x80000000u << 32;
    static const uint64_t exponent = (uint64_t)0x7ff00000 << 32;
    static const uint64_t flag     = 0;
    static const uint64_t significand
        = ((uint64_t)0x000fffff << 32) + (uint64_t)0xffffffffu;

    typedef uint64_t bits;
    static void get_bits(long double x, uint64_t& a) { std::memcpy(&a, &x, 8); }
    static void set_bits(long double& x, uint64_t a) { std::memcpy(&x, &a, 8); }
};

#endif

// long double (>64 bits), x86 and x64 -----------------------------------------

#if defined(__i386) || defined(__i386__) || defined(_M_IX86) \
    || defined(__amd64) || defined(__amd64__)  || defined(_M_AMD64) \
    || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)

// Intel extended double precision format (80 bits)

template<>
struct fp_traits_non_native<long double, extended_double_precision>
{
    typedef ieee_copy_leading_bits_tag method;

    BOOST_STATIC_CONSTANT(uint32_t, sign        = 0x80000000u);
    BOOST_STATIC_CONSTANT(uint32_t, exponent    = 0x7fff0000);
    BOOST_STATIC_CONSTANT(uint32_t, flag        = 0x00008000);
    BOOST_STATIC_CONSTANT(uint32_t, significand = 0x00007fff);

    typedef uint32_t bits;

    static void get_bits(long double x, uint32_t& a)
    {
        std::memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + 6, 4);
    }

    static void set_bits(long double& x, uint32_t a)
    {
        std::memcpy(reinterpret_cast<unsigned char*>(&x) + 6, &a, 4);
    }
};

// long double (>64 bits), Itanium ---------------------------------------------

#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)

// The floating point format is unknown at compile time
// No template specialization is provided.
// The generic_tag definition is used.

// The Itanium supports both
// the Intel extended double precision format (80 bits) and
// the IEEE extended double precision format with 15 exponent bits (128 bits).

// long double (>64 bits), PowerPC ---------------------------------------------

#elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) \
    || defined(__ppc) || defined(__ppc__) || defined(__PPC__)

// PowerPC extended double precision format (128 bits)

template<>
struct fp_traits_non_native<long double, extended_double_precision>
{
    typedef ieee_copy_leading_bits_tag method;

    BOOST_STATIC_CONSTANT(uint32_t, sign        = 0x80000000u);
    BOOST_STATIC_CONSTANT(uint32_t, exponent    = 0x7ff00000);
    BOOST_STATIC_CONSTANT(uint32_t, flag        = 0x00000000);
    BOOST_STATIC_CONSTANT(uint32_t, significand = 0x000fffff);

    typedef uint32_t bits;

    static void get_bits(long double x, uint32_t& a)
    {
        std::memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
    }

    static void set_bits(long double& x, uint32_t a)
    {
        std::memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
    }

private:

#if defined(BOOST_BIG_ENDIAN)
    BOOST_STATIC_CONSTANT(int, offset_ = 0);
#elif defined(BOOST_LITTLE_ENDIAN)
    BOOST_STATIC_CONSTANT(int, offset_ = 12);
#else
    BOOST_STATIC_ASSERT(false);
#endif
};

// long double (>64 bits), Motorola 68K ----------------------------------------

#elif defined(__m68k) || defined(__m68k__) \
    || defined(__mc68000) || defined(__mc68000__) \

// Motorola extended double precision format (96 bits)

// It is the same format as the Intel extended double precision format,
// except that 1) it is big-endian, 2) the 3rd and 4th byte are padding, and
// 3) the flag bit is not set for infinity

template<>
struct fp_traits_non_native<long double, extended_double_precision>
{
    typedef ieee_copy_leading_bits_tag method;

    BOOST_STATIC_CONSTANT(uint32_t, sign        = 0x80000000u);
    BOOST_STATIC_CONSTANT(uint32_t, exponent    = 0x7fff0000);
    BOOST_STATIC_CONSTANT(uint32_t, flag        = 0x00008000);
    BOOST_STATIC_CONSTANT(uint32_t, significand = 0x00007fff);

    // copy 1st, 2nd, 5th and 6th byte. 3rd and 4th byte are padding.

    typedef uint32_t bits;

    static void get_bits(long double x, uint32_t& a)
    {
        std::memcpy(&a, &x, 2);
        std::memcpy(reinterpret_cast<unsigned char*>(&a) + 2,
               reinterpret_cast<const unsigned char*>(&x) + 4, 2);
    }

    static void set_bits(long double& x, uint32_t a)
    {
        std::memcpy(&x, &a, 2);
        std::memcpy(reinterpret_cast<unsigned char*>(&x) + 4,
               reinterpret_cast<const unsigned char*>(&a) + 2, 2);
    }
};

// long double (>64 bits), All other processors --------------------------------

#else

// IEEE extended double precision format with 15 exponent bits (128 bits)

template<>
struct fp_traits_non_native<long double, extended_double_precision>
{
    typedef ieee_copy_leading_bits_tag method;

    BOOST_STATIC_CONSTANT(uint32_t, sign        = 0x80000000u);
    BOOST_STATIC_CONSTANT(uint32_t, exponent    = 0x7fff0000);
    BOOST_STATIC_CONSTANT(uint32_t, flag        = 0x00000000);
    BOOST_STATIC_CONSTANT(uint32_t, significand = 0x0000ffff);

    typedef uint32_t bits;

    static void get_bits(long double x, uint32_t& a)
    {
        std::memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
    }

    static void set_bits(long double& x, uint32_t a)
    {
        std::memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
    }

private:

#if defined(BOOST_BIG_ENDIAN)
    BOOST_STATIC_CONSTANT(int, offset_ = 0);
#elif defined(BOOST_LITTLE_ENDIAN)
    BOOST_STATIC_CONSTANT(int, offset_ = 12);
#else
    BOOST_STATIC_ASSERT(false);
#endif
};

#endif

//------------------------------------------------------------------------------

// size_to_precision is a type switch for converting a C++ floating point type
// to the corresponding precision type.

template<int n, bool fp> struct size_to_precision
{
   typedef unknown_precision type;
};

template<> struct size_to_precision<4, true>
{
    typedef single_precision type;
};

template<> struct size_to_precision<8, true>
{
    typedef double_precision type;
};

template<> struct size_to_precision<10, true>
{
    typedef extended_double_precision type;
};

template<> struct size_to_precision<12, true>
{
    typedef extended_double_precision type;
};

template<> struct size_to_precision<16, true>
{
    typedef extended_double_precision type;
};

//------------------------------------------------------------------------------
//
// Figure out whether to use native classification functions based on
// whether T is a built in floating point type or not:
//
template <class T>
struct select_native
{
    typedef BOOST_DEDUCED_TYPENAME size_to_precision<sizeof(T), ::boost::is_floating_point<T>::value>::type precision;
    typedef fp_traits_non_native<T, precision> type;
};
template<>
struct select_native<float>
{
    typedef fp_traits_native<float> type;
};
template<>
struct select_native<double>
{
    typedef fp_traits_native<double> type;
};
template<>
struct select_native<long double>
{
    typedef fp_traits_native<long double> type;
};

//------------------------------------------------------------------------------

// fp_traits is a type switch that selects the right fp_traits_non_native

#if (defined(BOOST_MATH_USE_C99) && !(defined(__GNUC__) && (__GNUC__ < 4))) \
   && !defined(__hpux) \
   && !defined(__DECCXX)\
   && !defined(__osf__)
#  define BOOST_MATH_USE_STD_FPCLASSIFY
#endif

template<class T> struct fp_traits
{
#ifdef BOOST_MATH_USE_STD_FPCLASSIFY
    typedef typename select_native<T>::type type;
#else
    typedef BOOST_DEDUCED_TYPENAME size_to_precision<sizeof(T), ::boost::is_floating_point<T>::value>::type precision;
    typedef fp_traits_non_native<T, precision> type;
#endif
};

//------------------------------------------------------------------------------

}   // namespace detail
}   // namespace math
}   // namespace boost

#endif


#include <iostream>
#include <boost/date_time/gregorian/gregorian.hpp>

using namespace std;
using namespace boost::gregorian;

int main(){
    // There's three ways to print date:
    //      1. to_simple_string(date);          YYYY-mm-DD
    //      2. to_iso_string(date);             YYYYMMDD
    //      3. to_iso_extended_string(date);    YYYY-MM-DD
    date d(2008,11,20);
    cout << " Standard output format : " << d << endl;
    cout << "to_simple_string format : " << to_simple_string(d) << endl;
    cout << "   to_iso_string format : " << to_iso_string(d) << endl;
    cout << "to_iso_extended_string  : " << to_iso_extended_string(d) << endl;
    return 0;
}


/*
//@HEADER
// ************************************************************************
//
// tutorial1.cc
//                     		  Pressio
//                             Copyright 2019
//    National Technology & Engineering Solutions of Sandia, LLC (NTESS)
//
// Under the terms of Contract DE-NA0003525 with NTESS, the
// U.S. Government retains certain rights in this software.
//
// Pressio is licensed under BSD-3-Clause terms of use:
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact Francesco Rizzi (fnrizzi@sandia.gov)
//
// ************************************************************************
//@HEADER
*/

#include "pressio_containers.hpp"
#include <Eigen/Core>

int main(int argc, char *argv[])
{
  std::cout << "Running tutorial 1\n";

  /*
    Pressio makes use of container wrappers to wrap arbitrary data types.
    These wrappers are thin layers.

    Pressio has predefined knowledge about data structures
    from specific libraries, e.g. Trilinos, Eigen, Kokkos.
    Over time, this support will be extended.
    If your application uses vector/matrix/multivector classes of one
    of these libraries, you can easily use pressio as follows.

    Suppose that you have an application that is based on Eigen.
    Therefore, a (dynamic) vector object "a" in your application looks like:

    Eigen::VectorXd a;

    Now, suppose now that you need to use some functionality in pressio.
    To do so, you need to wrap your object with a pressio container.
    e.g. ::pressio::containers::Vector<Eigen::VectorXd> aW(a);

    If the type you are wrapping is one of the already supported by pressio,
    then you have seamless access to all pressio functionalities, since pressio
    behind the scenes knows how to do algebra with these objects and in fact
    leverages the native algebra functionalities of the target library.
    If the type you are wrapping is NOT already known to pressio,
    then you can still wrap it, but in order to instantiate and use pressio
    functionalities you need to provide functionalities to tell pressio
    how to do operations with your data types.
    See tutorials{3,5} for examples showing using arbitrary types.
  */

  // this is dynamic double array in Eigen
  Eigen::VectorXd a(5);
  a.setConstant(2.2);

  // the corresponding pressio wrapper can be created as follows
  // Note that here pressio makes a deep copy of the object.
  // This is because the target ROM algorithms are all implemented
  // such that pressio owns the data and queries the full-order application
  // to computed things.
  ::pressio::containers::Vector<Eigen::VectorXd> aW(a);

  // we can verify that a deep copy is made
  for (auto i=0; i<aW.extent(0); ++i)
    std::cout << "aW(i) = " << aW(i)
	      << " expected = " << 2.2
	      << std::endl;

  // note that above we used the "extent" method
  // extent(k) works for all pressio container wrappers
  // - extent(k1) for 1d objects,
  // - extent(k1,k2) for 2d objects

  return 0;
}


//---------------------------------------------------------------------------//
// Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
// See http://boostorg.github.com/compute for more information.
//---------------------------------------------------------------------------//

#define BOOST_TEST_MODULE TestPermutationIterator
#include <boost/test/unit_test.hpp>

#include <iterator>

#include <boost/type_traits.hpp>
#include <boost/static_assert.hpp>

#include <boost/compute/types.hpp>
#include <boost/compute/algorithm/copy.hpp>
#include <boost/compute/container/vector.hpp>
#include <boost/compute/iterator/buffer_iterator.hpp>
#include <boost/compute/iterator/permutation_iterator.hpp>

#include "check_macros.hpp"
#include "context_setup.hpp"

BOOST_AUTO_TEST_CASE(value_type)
{
    using boost::compute::float4_;

    BOOST_STATIC_ASSERT((
        boost::is_same<
            boost::compute::permutation_iterator<
                boost::compute::buffer_iterator<float>,
                boost::compute::buffer_iterator<int>
            >::value_type,
            float
        >::value
    ));
    BOOST_STATIC_ASSERT((
        boost::is_same<
            boost::compute::permutation_iterator<
                boost::compute::buffer_iterator<float4_>,
                boost::compute::buffer_iterator<short>
            >::value_type,
            float4_
        >::value
    ));
}

BOOST_AUTO_TEST_CASE(base_type)
{
    BOOST_STATIC_ASSERT((
        boost::is_same<
            boost::compute::permutation_iterator<
                boost::compute::buffer_iterator<int>,
                boost::compute::buffer_iterator<int>
            >::base_type,
            boost::compute::buffer_iterator<int>
        >::value
    ));
}

BOOST_AUTO_TEST_CASE(copy)
{
    int input_data[] = { 3, 4, 2, 1, 5 };
    boost::compute::vector<int> input(input_data, input_data + 5, queue);

    int map_data[] = { 3, 2, 0, 1, 4 };
    boost::compute::vector<int> map(map_data, map_data + 5, queue);

    boost::compute::vector<int> output(5, context);
    boost::compute::copy(
        boost::compute::make_permutation_iterator(input.begin(), map.begin()),
        boost::compute::make_permutation_iterator(input.end(), map.end()),
        output.begin(),
        queue
    );
    CHECK_RANGE_EQUAL(int, 5, output, (1, 2, 3, 4, 5));
}

BOOST_AUTO_TEST_CASE(reverse_range_doctest)
{
    int values_data[] = { 10, 20, 30, 40 };
    int indices_data[] = { 3, 2, 1, 0 };

    boost::compute::vector<int> values(values_data, values_data + 4, queue);
    boost::compute::vector<int> indices(indices_data, indices_data + 4, queue);

    boost::compute::vector<int> result(4, context);

//! [reverse_range]
// values =  { 10, 20, 30, 40 }
// indices = { 3, 2, 1, 0 }

boost::compute::copy(
    boost::compute::make_permutation_iterator(values.begin(), indices.begin()),
    boost::compute::make_permutation_iterator(values.end(), indices.end()),
    result.begin(),
    queue
);

// result == { 40, 30, 20, 10 }
//! [reverse_range]

    CHECK_RANGE_EQUAL(int, 4, result, (40, 30, 20, 10));
}

BOOST_AUTO_TEST_SUITE_END()


//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, Indiana University,
// Bloomington, IN 47405.
//
// Permission to modify the code and to distribute the code is
// granted, provided the text of this NOTICE is retained, a notice if
// the code was modified is included with the above COPYRIGHT NOTICE
// and with the COPYRIGHT NOTICE in the LICENSE file, and that the
// LICENSE file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#include <boost/config.hpp>
#include <iostream>
#include <fstream>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/breadth_first_search.hpp>
using namespace boost;

template < typename Graph, typename VertexNameMap, typename TransDelayMap > void
build_router_network(Graph & g, VertexNameMap name_map,
                     TransDelayMap delay_map)
{
  typename graph_traits < Graph >::vertex_descriptor a, b, c, d, e;
  a = add_vertex(g);
  name_map[a] = 'a';
  b = add_vertex(g);
  name_map[b] = 'b';
  c = add_vertex(g);
  name_map[c] = 'c';
  d = add_vertex(g);
  name_map[d] = 'd';
  e = add_vertex(g);
  name_map[e] = 'e';

  typename graph_traits < Graph >::edge_descriptor ed;
  bool inserted;

  tie(ed, inserted) = add_edge(a, b, g);
  delay_map[ed] = 1.2;
  tie(ed, inserted) = add_edge(a, d, g);
  delay_map[ed] = 4.5;
  tie(ed, inserted) = add_edge(b, d, g);
  delay_map[ed] = 1.8;
  tie(ed, inserted) = add_edge(c, a, g);
  delay_map[ed] = 2.6;
  tie(ed, inserted) = add_edge(c, e, g);
  delay_map[ed] = 5.2;
  tie(ed, inserted) = add_edge(d, c, g);
  delay_map[ed] = 0.4;
  tie(ed, inserted) = add_edge(d, e, g);
  delay_map[ed] = 3.3;

}

template < typename VertexNameMap > class bfs_name_printer:public default_bfs_visitor {
                                // inherit default (empty) event point actions
public:
bfs_name_printer(VertexNameMap n_map):m_name_map(n_map) {
  }
  template < typename Vertex, typename Graph >
    void discover_vertex(Vertex u, const Graph &) const
  {
    std::cout << get(m_name_map, u) << ' ';
  }
private:
    VertexNameMap m_name_map;
};

int
main()
{
  typedef adjacency_list < listS, vecS, directedS,
    property < vertex_name_t, char >,
    property < edge_weight_t, double > > graph_t;
  graph_t g;

  property_map < graph_t, vertex_name_t >::type name_map =
    get(vertex_name, g);
  property_map < graph_t, edge_weight_t >::type delay_map =
    get(edge_weight, g);

  build_router_network(g, name_map, delay_map);

  typedef property_map < graph_t, vertex_name_t >::type VertexNameMap;
  graph_traits < graph_t >::vertex_descriptor a = *vertices(g).first;
  bfs_name_printer < VertexNameMap > vis(name_map);
  std::cout << "BFS vertex discover order: ";
  breadth_first_search(g, a, visitor(vis));
  std::cout << std::endl;

}


// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html

//[n1962_sum
#include <boost/contract.hpp>
#include <cassert>

int sum(int count, int* array) {
    int result;
    boost::contract::check c = boost::contract::function()
        .precondition([&] {
            BOOST_CONTRACT_ASSERT(count % 4 == 0);
        })
    ;

    result = 0;
    for(int i = 0; i < count; ++i) result += array[i];
    return result;
}

int main() {
    int a[4] = {1, 2, 3, 4};
    assert(sum(4, a) == 10);
    return 0;
}
//]


/* test_constructors.cpp - Test Adept's selection of constructors in a range of scenarios

    Copyright (C) 2017 European Centre for Medium-Range Weather Forecasts

    Author: Robin Hogan <r.j.hogan@ecmwf.int>

  Copying and distribution of this file, with or without modification,
  are permitted in any medium without royalty provided the copyright
  notice and this notice are preserved.  This file is offered as-is,
  without any warranty.
*/

#include <iostream>

#define ADEPT_BOUNDS_CHECKING 1
#define ADEPT_VERBOSE_FUNCTIONS
#define ADEPT_NO_ALIAS_CHECKING

#include <adept_arrays.h>

using namespace adept;

Vector square(const Vector& v) {
  std::cout << "  inside function\n";
  return v*v;
}

void square_in_place(Vector& v) {
  std::cout << "  inside function\n";
  v *= v;
}

Vector square_copy(Vector v) {
  std::cout << "  inside function\n";
  v *= -1.0;
  return v*v;
}

#define COMMA ,

#define EVAL_CONSTRUCT(MSG,X,COMMAND) std::cout << "--------------------------------------------------------------------\n" \
  << MSG << "\n" \
  << #COMMAND << "\n"; \
  COMMAND; \
  std::cout << #X << " = " << X << "\n"

#define EVAL(MSG,X,COMMAND) std::cout << "--------------------------------------------------------------------\n" \
  << MSG << "\n" \
  << #X << " = " << X << "\n" \
  << #COMMAND << "\n"; \
  COMMAND; \
  std::cout << #X << " = " << X << "\n"

 #define EVAL2(MSG,X,COMMAND,Y) std::cout << "--------------------------------------------------------------------\n" \
  << MSG << "\n" \
  << #X << " = " << X << "\n" \
  << #COMMAND << "\n"; \
  COMMAND;					\
  std::cout << #X << " = " << X << "\n" \
            << #Y << " = " << Y << "\n"

#define EVAL_FAIL(MSG,X,COMMAND) std::cout << "--------------------------------------------------------------------\n" \
  << MSG << "\n" \
  << #COMMAND << "\n" \
  << "DOES NOT COMPILE (INCORRECT BEHAVIOUR)\n"

#define EVAL2_FAIL(MSG,X,COMMAND,Y) std::cout << "--------------------------------------------------------------------\n" \
  << MSG << "\n" \
  << #COMMAND << "\n" \
  << "DOES NOT COMPILE (INCORRECT BEHAVIOUR)\n"

#define VERDICT98(MSG) std::cout << "Verdict for C++98: " << MSG << "\n"
#define VERDICT11(MSG) std::cout << "Verdict for C++11: " << MSG << "\n"

#define HEADING(MSG) std::cout << "####################################################################\n" \
  << MSG << "\n"

int
main() {

  Vector v(2), w(2), v_data(2), v_const_data(2);
  v_data << 2, 3;
  v_const_data << 5, 7;
  v = v_data;
  const Vector v_const = v_const_data;

  adept::Stack stack;
  stack.new_recording();

  {
  HEADING("COPY CONSTRUCTORS");
  EVAL2("Passing Vector as argument to Vector copy constructor",
	v, const Vector v2(v), v2);
  VERDICT98("correct");
  VERDICT11("should perform deep copy");

  EVAL2("Passing Vector as argument to const Vector copy constructor",
	v, const Vector v_const(v), v_const);
  VERDICT98("correct");
  VERDICT11("should perform deep copy");

  EVAL2("Passing const Vector as argument to const Vector copy constructor",
	v_const, const Vector v_const2(v_const), v_const2);
  VERDICT98("correct");
  VERDICT11("should perform deep copy");

  EVAL2("Passing const Vector as argument to Vector copy constructor",
	v_const, Vector v3(v_const), v3);
  VERDICT98("should not compile");
  VERDICT11("should perform deep copy");
  }

#ifdef ADEPT_CXX11_FEATURES
  HEADING("INITIALIZER LISTS");
  EVAL_CONSTRUCT("Construct Vector from initializer list of ints",
	v1, Vector v1 = {1 COMMA 2 COMMA 3});
  EVAL_CONSTRUCT("Construct Vector from initializer list of doubles",
	v1d, Vector v1d = {1.0 COMMA 2.0 COMMA 3.0});
  EVAL_CONSTRUCT("Construct Matrix from initializer list",
		 M, Matrix M = { {1 COMMA 2} COMMA {3} } );
  EVAL_CONSTRUCT("Construct Array3D from initializer list",
		 A3, Array3D A3 = { { {1 COMMA 2} COMMA {3} } COMMA { { 4 } } } );
  EVAL_CONSTRUCT("Construct FixedVector from initializer list",
		 fv1, Vector3 fv1 = {1 COMMA 2});
  EVAL_CONSTRUCT("Construct FixedMatrix from initializer list",
		 fM, Matrix33 fM = { {1 COMMA 2} COMMA {3} } );
  EVAL_CONSTRUCT("Construct FixedArray3D from initializer list",
		 fA3, FixedArray<double COMMA false COMMA 3 COMMA 3 COMMA 3> fA3 = { { {1 COMMA 2} COMMA {3} } COMMA { { 4 } } } );
#endif

  HEADING("ASSIGNMENT OPERATOR");
  EVAL2("Passing Vector to assignment operator",
	v, w = v, w);
  EVAL2("Passing const Vector to assignment operator",
	v_const, w = v_const, w);
  EVAL2("Passing Vector rvalue to assignment operator",
	v, w = v(stride(1,0,-1)), w);
  EVAL2("Passing const-Vector rvalue to assignment operator",
	v_const, w = v_const(stride(1,0,-1)), w);
  EVAL2("Passing Expression to assignment operator",
	v, w = v+v, w);

  HEADING("PASSING Vector TO FUNCTIONS");
  EVAL2("Passing Vector as argument to function taking const Vector&",
       v, w = square(v), w);
  VERDICT98("too many copies");
  VERDICT11("could replace last copy with a move");
  EVAL("Passing Vector as argument to function taking Vector&",
       v, square_in_place(v));
  VERDICT98("correct");

  v = v_data;
  EVAL2("Passing Vector as argument to function taking Vector",
       v, w = square_copy(v), w);
  VERDICT98("too many copies, unexpected change of argument");
  VERDICT11("should do deep copy on input, replace last copy with a move");

  /*

    // Behaves same as passing non-const Vector, which is correct

  // Passing const Vector
  EVAL2("Passing const Vector as argument to function taking const Vector&",
       v_const, w = square(v_const), w);
  // The following should not compile:
  //  EVAL("Passing const Vector as argument to function taking Vector&",
  //       v_const, square_in_place(v_const));
  EVAL2("Passing const Vector as argument to function taking Vector",
       v_const, w = square_copy(v_const), w);

  */

  HEADING("LINKING");
  w.clear();
  EVAL2("Linking to Vector",
	v, w >>= v, w);

  /*
  w.clear();
  // This should not compile
  EVAL2("Linking to const Vector",
	v_const, w >>= v_const, w);
  */
  w.clear();
  EVAL2("Linking to Vector rvalue",
	v, w >>= v(stride(1,0,-1)), w);

  /*
  // This should not compile
  w.clear();
  EVAL2("Linking to const-Vector rvalue",
	v_const, w >>= v_const(stride(1,0,-1)), w);
  */
  /*
    // This should not compile
  w.clear();
  EVAL2("Linking to Expression",
	v, w >>= v+v, w);
  VERDICT98("this doesn't make much sense");
  */

  HEADING("PASSING Vector TO FUNCTIONS");
  EVAL2("Passing Vector as argument to function taking const Vector&",
       v, w = square(v), w);
  VERDICT98("too many copies");
  VERDICT11("could replace last copy with a move");
  EVAL("Passing Vector as argument to function taking Vector&",
       v, square_in_place(v));
  VERDICT98("correct");

  v = v_data;
  EVAL2("Passing Vector as argument to function taking Vector",
       v, w = square_copy(v), w);
  VERDICT98("too many copies, unexpected change of argument");
  VERDICT11("should do deep copy on input, replace last copy with a move");

  HEADING("PASSING Vector RVALUE TO FUNCTIONS");
  EVAL2("Passing Vector rvalue as argument to function taking const Vector&",
	v, w = square(v(stride(1,0,-1))), w);
  VERDICT98("correct");
  EVAL_FAIL("Passing Vector rvalue as argument to function taking Vector&",
       v, square_in_place(v(stride(1,0,-1))));
  VERDICT98("Vector subset functions could return references?");

  v = v_data;
  EVAL2("Passing Vector rvalue as argument to function taking Vector",
	     v, w = square_copy(v(stride(1,0,-1))), w);
  VERDICT98("Vector subset functions could return references?");
  VERDICT11("Should use move function");

  HEADING("PASSING const Vector RVALUES TO FUNCTIONS");
  EVAL2("Passing const-Vector rvalue as argument to function taking const Vector&",
	v_const, w = square(v_const(stride(1,0,-1))), w);
  VERDICT98("correct");
  // This should not compile
  //  EVAL("Passing const-Vector rvalue as argument to function taking Vector&",
  //       v_const, square_in_place(v_const(stride(1,0,-1))));
  //  VERDICT98("Vector subset functions could return references?");
  EVAL2("Passing const-Vector rvalue as argument to function taking Vector",
	     v_const, w = square_copy(v_const(stride(1,0,-1))), w);
  VERDICT98("correct");
  //  VERDICT11("Should use move function");

  HEADING("PASSING Expression TO FUNCTIONS");
  EVAL2("Passing Expression as argument to function taking const Vector&",
       v, w = square(v+v), w);
  VERDICT98("Unclear why copy-assignment + constructor needed");
  // This should not compile:
  //  EVAL("Passing Expression as argument to function taking Vector&",
  //       v, square_in_place(v+v));
  v = v_data;
  EVAL2("Passing Expression as argument to function taking Vector",
       v, w = square_copy(v+v), w);
  VERDICT98("Unclear why copy-assignment + constructor needed");

  return 0;
}


// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 20015 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

// This unit test cannot be easily written to work with EIGEN_DEFAULT_TO_ROW_MAJOR
#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
#undef EIGEN_DEFAULT_TO_ROW_MAJOR
#endif

static long int nb_temporaries;

inline void on_temporary_creation() {
  // here's a great place to set a breakpoint when debugging failures in this test!
  nb_temporaries++;
}

#define EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN { on_temporary_creation(); }

#include "main.h"
#include <Eigen/SparseCore>

#define VERIFY_EVALUATION_COUNT(XPR,N) {\
    nb_temporaries = 0; \
    CALL_SUBTEST( XPR ); \
    if(nb_temporaries!=N) std::cerr << "nb_temporaries == " << nb_temporaries << "\n"; \
    VERIFY( (#XPR) && nb_temporaries==N ); \
  }

template<typename PlainObjectType> void check_const_correctness(const PlainObjectType&)
{
  // verify that ref-to-const don't have LvalueBit
  typedef typename internal::add_const<PlainObjectType>::type ConstPlainObjectType;
  VERIFY( !(internal::traits<Ref<ConstPlainObjectType> >::Flags & LvalueBit) );
  VERIFY( !(internal::traits<Ref<ConstPlainObjectType, Aligned> >::Flags & LvalueBit) );
  VERIFY( !(Ref<ConstPlainObjectType>::Flags & LvalueBit) );
  VERIFY( !(Ref<ConstPlainObjectType, Aligned>::Flags & LvalueBit) );
}

template<typename B>
EIGEN_DONT_INLINE void call_ref_1(Ref<SparseMatrix<float> > a, const B &b) { VERIFY_IS_EQUAL(a.toDense(),b.toDense()); }

template<typename B>
EIGEN_DONT_INLINE void call_ref_2(const Ref<const SparseMatrix<float> >& a, const B &b) { VERIFY_IS_EQUAL(a.toDense(),b.toDense()); }

template<typename B>
EIGEN_DONT_INLINE void call_ref_3(const Ref<const SparseMatrix<float>, StandardCompressedFormat>& a, const B &b) {
  VERIFY(a.isCompressed());
  VERIFY_IS_EQUAL(a.toDense(),b.toDense());
}

template<typename B>
EIGEN_DONT_INLINE void call_ref_4(Ref<SparseVector<float> > a, const B &b) { VERIFY_IS_EQUAL(a.toDense(),b.toDense()); }

template<typename B>
EIGEN_DONT_INLINE void call_ref_5(const Ref<const SparseVector<float> >& a, const B &b) { VERIFY_IS_EQUAL(a.toDense(),b.toDense()); }

void call_ref()
{
  SparseMatrix<float>               A = MatrixXf::Random(10,10).sparseView(0.5,1);
  SparseMatrix<float,RowMajor>      B = MatrixXf::Random(10,10).sparseView(0.5,1);
  SparseMatrix<float>               C = MatrixXf::Random(10,10).sparseView(0.5,1);
  C.reserve(VectorXi::Constant(C.outerSize(), 2));
  const SparseMatrix<float>&        Ac(A);
  Block<SparseMatrix<float> >       Ab(A,0,1, 3,3);
  const Block<SparseMatrix<float> > Abc(A,0,1,3,3);
  SparseVector<float>               vc =  VectorXf::Random(10).sparseView(0.5,1);
  SparseVector<float,RowMajor>      vr =  VectorXf::Random(10).sparseView(0.5,1);
  SparseMatrix<float> AA = A*A;

  VERIFY_EVALUATION_COUNT( call_ref_1(A, A),  0);
//   VERIFY_EVALUATION_COUNT( call_ref_1(Ac, Ac),  0); // does not compile on purpose
  VERIFY_EVALUATION_COUNT( call_ref_2(A, A),  0);
  VERIFY_EVALUATION_COUNT( call_ref_3(A, A),  0);
  VERIFY_EVALUATION_COUNT( call_ref_2(A.transpose(), A.transpose()),  1);
  VERIFY_EVALUATION_COUNT( call_ref_3(A.transpose(), A.transpose()),  1);
  VERIFY_EVALUATION_COUNT( call_ref_2(Ac,Ac), 0);
  VERIFY_EVALUATION_COUNT( call_ref_3(Ac,Ac), 0);
  VERIFY_EVALUATION_COUNT( call_ref_2(A+A,2*Ac), 1);
  VERIFY_EVALUATION_COUNT( call_ref_3(A+A,2*Ac), 1);
  VERIFY_EVALUATION_COUNT( call_ref_2(B, B),  1);
  VERIFY_EVALUATION_COUNT( call_ref_3(B, B),  1);
  VERIFY_EVALUATION_COUNT( call_ref_2(B.transpose(), B.transpose()),  0);
  VERIFY_EVALUATION_COUNT( call_ref_3(B.transpose(), B.transpose()),  0);
  VERIFY_EVALUATION_COUNT( call_ref_2(A*A, AA),  3);
  VERIFY_EVALUATION_COUNT( call_ref_3(A*A, AA),  3);

  VERIFY(!C.isCompressed());
  VERIFY_EVALUATION_COUNT( call_ref_3(C, C),  1);

  Ref<SparseMatrix<float> > Ar(A);
  VERIFY_IS_APPROX(Ar+Ar, A+A);
  VERIFY_EVALUATION_COUNT( call_ref_1(Ar, A),  0);
  VERIFY_EVALUATION_COUNT( call_ref_2(Ar, A),  0);

  Ref<SparseMatrix<float,RowMajor> > Br(B);
  VERIFY_EVALUATION_COUNT( call_ref_1(Br.transpose(), Br.transpose()),  0);
  VERIFY_EVALUATION_COUNT( call_ref_2(Br, Br),  1);
  VERIFY_EVALUATION_COUNT( call_ref_2(Br.transpose(), Br.transpose()),  0);

  Ref<const SparseMatrix<float> > Arc(A);
//   VERIFY_EVALUATION_COUNT( call_ref_1(Arc, Arc),  0); // does not compile on purpose
  VERIFY_EVALUATION_COUNT( call_ref_2(Arc, Arc),  0);

  VERIFY_EVALUATION_COUNT( call_ref_2(A.middleCols(1,3), A.middleCols(1,3)),  0);

  VERIFY_EVALUATION_COUNT( call_ref_2(A.col(2), A.col(2)),  0);
  VERIFY_EVALUATION_COUNT( call_ref_2(vc, vc),  0);
  VERIFY_EVALUATION_COUNT( call_ref_2(vr.transpose(), vr.transpose()),  0);
  VERIFY_EVALUATION_COUNT( call_ref_2(vr, vr.transpose()),  0);

  VERIFY_EVALUATION_COUNT( call_ref_2(A.block(1,1,3,3), A.block(1,1,3,3)),  1); // should be 0 (allocate starts/nnz only)

  VERIFY_EVALUATION_COUNT( call_ref_4(vc, vc),  0);
  VERIFY_EVALUATION_COUNT( call_ref_4(vr, vr.transpose()),  0);
  VERIFY_EVALUATION_COUNT( call_ref_5(vc, vc),  0);
  VERIFY_EVALUATION_COUNT( call_ref_5(vr, vr.transpose()),  0);
  VERIFY_EVALUATION_COUNT( call_ref_4(A.col(2), A.col(2)),  0);
  VERIFY_EVALUATION_COUNT( call_ref_5(A.col(2), A.col(2)),  0);
  // VERIFY_EVALUATION_COUNT( call_ref_4(A.row(2), A.row(2).transpose()),  1); // does not compile on purpose
  VERIFY_EVALUATION_COUNT( call_ref_5(A.row(2), A.row(2).transpose()),  1);
}

void test_sparse_ref()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( check_const_correctness(SparseMatrix<float>()) );
    CALL_SUBTEST_1( check_const_correctness(SparseMatrix<double,RowMajor>()) );
    CALL_SUBTEST_2( call_ref() );

    CALL_SUBTEST_3( check_const_correctness(SparseVector<float>()) );
    CALL_SUBTEST_3( check_const_correctness(SparseVector<double,RowMajor>()) );
  }
}


//  Copyright (c) 2010 Peter Schueller
//  Copyright (c) 2001-2010 Hartmut Kaiser
//
//  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/config/warning_disable.hpp>
#include <boost/detail/lightweight_test.hpp>

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

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

std::vector<double> parse(std::istream& input)
{
  // iterate over stream input
  typedef std::istreambuf_iterator<char> base_iterator_type;
  base_iterator_type in_begin(input);

  // convert input iterator to forward iterator, usable by spirit parser
  typedef boost::spirit::multi_pass<base_iterator_type> forward_iterator_type;
  forward_iterator_type fwd_begin = boost::spirit::make_default_multi_pass(in_begin);
  forward_iterator_type fwd_end;

  // prepare output
  std::vector<double> output;

  // parse
  bool r = qi::phrase_parse(
    fwd_begin, fwd_end,                          // iterators over input
    qi::double_ >> *(',' >> qi::double_) >> qi::eoi,    // recognize list of doubles
    ascii::space | '#' >> *(ascii::char_ - qi::eol) >> qi::eol, // comment skipper
    output);                              // doubles are stored into this object

  // error detection
  if( !r || fwd_begin != fwd_end )
    throw std::runtime_error("parse error");

  // return result
  return output;
}

int main()
{
  try {
    std::stringstream str("1.0,2.0\n");
    std::vector<double> values = parse(str);
    BOOST_TEST(values.size() == 2 && values[0] == 1.0 && values[1] == 2.0);
  }
  catch(std::exception const&) {
    BOOST_TEST(false);
  }
  return boost::report_errors();
}


/*    This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
 *    See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
 *    Author(s):       Vincent Rouvreau
 *
 *    Copyright (C) 2020 Inria
 *
 *    Modification(s):
 *      - YYYY/MM Author: Description of the modification
 */

#include <iostream>
#include <limits>  // for NaN
#include <cmath>  // for isNaN

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE "simplex_tree_make_filtration_non_decreasing"
#include <boost/test/unit_test.hpp>
#include <boost/mpl/list.hpp>

//  ^
// /!\ Nothing else from Simplex_tree shall be included to test includes are well defined.
#include "gudhi/Simplex_tree.h"

using namespace Gudhi;

typedef boost::mpl::list<Simplex_tree<>, Simplex_tree<Simplex_tree_options_fast_persistence>> list_of_tested_variants;

BOOST_AUTO_TEST_CASE_TEMPLATE(make_filtration_non_decreasing, typeST, list_of_tested_variants) {
  typeST st;

  st.insert_simplex_and_subfaces({2, 1, 0}, 2.0);
  st.insert_simplex_and_subfaces({3, 0}, 2.0);
  st.insert_simplex_and_subfaces({3, 4, 5}, 2.0);

  /* Inserted simplex:     */
  /*    1                  */
  /*    o                  */
  /*   /X\                 */
  /*  o---o---o---o        */
  /*  2   0   3\X/4        */
  /*            o          */
  /*            5          */

  std::clog << "Check default insertion ensures the filtration values are non decreasing" << std::endl;
  BOOST_CHECK(!st.make_filtration_non_decreasing());

  // Because of non decreasing property of simplex tree, { 0 } , { 1 } and { 0, 1 } are going to be set from value 2.0
  // to 1.0
  st.insert_simplex_and_subfaces({0, 1, 6, 7}, 1.0);

  // Inserted simplex:
  //    1   6
  //    o---o
  //   /X\7/
  //  o---o---o---o
  //  2   0   3\X/4
  //            o
  //            5

  std::clog << "Check default second insertion ensures the filtration values are non decreasing" << std::endl;
  BOOST_CHECK(!st.make_filtration_non_decreasing());

  // Copy original simplex tree
  typeST st_copy = st;

  // Modify specific values for st to become like st_copy thanks to make_filtration_non_decreasing
  st.assign_filtration(st.find({0,1,6,7}), 0.8);
  st.assign_filtration(st.find({0,1,6}), 0.9);
  st.assign_filtration(st.find({0,6}), 0.6);
  st.assign_filtration(st.find({3,4,5}), 1.2);
  st.assign_filtration(st.find({3,4}), 1.1);
  st.assign_filtration(st.find({4,5}), 1.99);

  std::clog << "Check the simplex_tree is rolled back in case of decreasing filtration values" << std::endl;
  BOOST_CHECK(st.make_filtration_non_decreasing());
  BOOST_CHECK(st == st_copy);

  // Other simplex tree
  typeST st_other;
  st_other.insert_simplex_and_subfaces({2, 1, 0}, 3.0);  // This one is different from st
  st_other.insert_simplex_and_subfaces({3, 0}, 2.0);
  st_other.insert_simplex_and_subfaces({3, 4, 5}, 2.0);
  st_other.insert_simplex_and_subfaces({0, 1, 6, 7}, 1.0);

  // Modify specific values for st to become like st_other thanks to make_filtration_non_decreasing
  st.assign_filtration(st.find({2}), 3.0);
  // By modifying just the simplex {2}
  // {0,1,2}, {1,2} and {0,2} will be modified

  std::clog << "Check the simplex_tree is repaired in case of decreasing filtration values" << std::endl;
  BOOST_CHECK(st.make_filtration_non_decreasing());
  BOOST_CHECK(st == st_other);

  // Modify specific values for st still to be non-decreasing
  st.assign_filtration(st.find({0,1,2}), 10.0);
  st.assign_filtration(st.find({0,2}), 9.0);
  st.assign_filtration(st.find({0,1,6,7}), 50.0);
  st.assign_filtration(st.find({0,1,6}), 49.0);
  st.assign_filtration(st.find({0,1,7}), 48.0);
  // Other copy simplex tree
  typeST st_other_copy = st;

  std::clog << "Check the simplex_tree is not modified in case of non-decreasing filtration values" << std::endl;
  BOOST_CHECK(!st.make_filtration_non_decreasing());
  BOOST_CHECK(st == st_other_copy);

}

BOOST_AUTO_TEST_CASE_TEMPLATE(make_filtration_non_decreasing_on_nan_values, typeST, list_of_tested_variants) {
  typeST st;

  st.insert_simplex_and_subfaces({2, 1, 0}, std::numeric_limits<double>::quiet_NaN());
  st.insert_simplex_and_subfaces({3, 0},    std::numeric_limits<double>::quiet_NaN());
  st.insert_simplex_and_subfaces({3, 4, 5}, std::numeric_limits<double>::quiet_NaN());

  /* Inserted simplex:     */
  /*    1                  */
  /*    o                  */
  /*   /X\                 */
  /*  o---o---o---o        */
  /*  2   0   3\X/4        */
  /*            o          */
  /*            5          */

  std::clog << "SPECIFIC CASE:" << std::endl;
  std::clog << "Insertion with NaN values does not ensure the filtration values are non decreasing" << std::endl;
  st.make_filtration_non_decreasing();

  std::clog << "Check all filtration values are NaN" << std::endl;
  for (auto f_simplex : st.complex_simplex_range()) {
    BOOST_CHECK(std::isnan(st.filtration(f_simplex)));
  }

  st.assign_filtration(st.find({0}), 0.);
  st.assign_filtration(st.find({1}), 0.);
  st.assign_filtration(st.find({2}), 0.);
  st.assign_filtration(st.find({3}), 0.);
  st.assign_filtration(st.find({4}), 0.);
  st.assign_filtration(st.find({5}), 0.);

  std::clog << "Check make_filtration_non_decreasing is modifying the simplicial complex" << std::endl;
  BOOST_CHECK(st.make_filtration_non_decreasing());

  std::clog << "Check all filtration values are now defined" << std::endl;
  for (auto f_simplex : st.complex_simplex_range()) {
    BOOST_CHECK(!std::isnan(st.filtration(f_simplex)));
  }
}


//------------------------------------------------------------------------------
/// \file SingleNode_tests.cpp
//------------------------------------------------------------------------------
#include "DataStructures/Lists/SingleNode.h"

#include <boost/test/unit_test.hpp>

using DataStructures::Lists::Nodes::SingleNode;
// Alternatively,
//template <typename T>
//using SingleNode = DataStructures::Lists::SingleNode::SingleNode<T>;

BOOST_AUTO_TEST_SUITE(DataStructures)
BOOST_AUTO_TEST_SUITE(Lists)
BOOST_AUTO_TEST_SUITE(Nodes)
BOOST_AUTO_TEST_SUITE(SingleNode_tests)

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(DefaultConstructs)
{
	SingleNode<int> node {};

	BOOST_TEST(node.retrieve() == 0);
	BOOST_TEST(node.next() == nullptr);
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(ConstructsWithElementValueOnly)
{
	SingleNode<int> node {42};

	BOOST_TEST(node.retrieve() == 42);
	BOOST_TEST(node.next() == nullptr);
}

BOOST_AUTO_TEST_SUITE_END() // SingleNode_tests
BOOST_AUTO_TEST_SUITE_END() // Nodes
BOOST_AUTO_TEST_SUITE_END() // Lists
BOOST_AUTO_TEST_SUITE_END() // DataStructures


/**
 * @license  this file is a part of libchef. more info see https://github.com/q191201771/libchef
 * @tag      v1.10.17
 * @file     chef_crypto_hmac_sha256.hpp
 * @deps     chef_crypto_sha256_op.hpp
 * @platform linux | macos | xxx
 *
 * @author
 *   chef <191201771@qq.com>
 *     -initial release xxxx-xx-xx
 *
 * @brief
 *   - hmac sha256加密
 *   - @NOTICE 实现部分拷贝自https://github.com/lyokato/cpp-cryptlite/blob/master/include/cryptlite/hmac.h
 *
     ```
     // 示例
     uint8_t key[] = {
  	  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  	  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  	  0x0b, 0x0b, 0x0b, 0x0b
     };
     std::size_t key_len = 20;
     const char *buf = "Hi There";
     std::size_t len = 8;

     chef::crypto_hmac_sha256 ctx(key, 20);
     ctx.update((const uint8_t *)buf, 8);
     uint8_t digest[32];
     ctx.final(digest);
     uint8_t result[] = {
       0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53,
       0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
       0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
       0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7
     };
     assert(memcmp(digest, result, 32) == 0);

     ```
 *
 */

#ifndef _CHEF_BASE_CRYPTO_HMAC_SHA256_HPP_
#define _CHEF_BASE_CRYPTO_HMAC_SHA256_HPP_
#pragma once

#include "chef_crypto_sha256_op.hpp"
#include <string>

namespace chef {

  namespace cryptlite__ {
    class sha256;
    template <typename T> class hmac;
  }

  class crypto_hmac_sha256 {
    public:
      crypto_hmac_sha256(const uint8_t *key, std::size_t key_len);
      ~crypto_hmac_sha256();
      void update(const uint8_t *buf, std::size_t len);
      void final(uint8_t dst[32] /* out */);

    private:
      crypto_hmac_sha256(const crypto_hmac_sha256 &);
      crypto_hmac_sha256 &operator=(const crypto_hmac_sha256 &);

    private:
      cryptlite__::hmac<cryptlite__::sha256> *ctx_;

  }; // class crypto_hmac_sha256

} // namespace chef

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// @NOTICE 该分隔线以上部分为该模块的接口，分割线以下部分为对应的实现

/*
The MIT License

Copyright (c) 2011 lyo.kato@gmail.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

//#ifndef _CRYPTLITE_HMAC_H_
//#define _CRYPTLITE_HMAC_H_

#include <string>
#include <sstream>
#include <cstring>
#include <cassert>
#include <iomanip>
//#include <boost/cstdint.hpp>

namespace chef {

namespace cryptlite__ {

template <typename T>
class hmac {

public:

    static const unsigned int BLOCK_SIZE = T::BLOCK_SIZE;
    static const unsigned int HASH_SIZE  = T::HASH_SIZE;

    static void calc(
            const char* text, int text_len,
            const char* key,  int key_len,
            uint8_t digest[HASH_SIZE]) {
        assert(digest);
        calc(reinterpret_cast<const uint8_t*>(text), text_len,
             reinterpret_cast<const uint8_t*>(key), key_len, digest);
    }

    static void calc(
            const uint8_t* text, int text_len,
            const uint8_t* key,  int key_len,
            uint8_t digest[HASH_SIZE]) {
        assert(digest);
        hmac<T> ctx(key, key_len);
        ctx.input(text, text_len);
        ctx.result(digest);
    }

    inline static void calc(
            const std::string& text,
            const std::string& key,
            uint8_t digest[HASH_SIZE]) {
        assert(digest);
        calc(reinterpret_cast<const char*>(text.c_str()), text.size(),
             reinterpret_cast<const char*>(key.c_str()), key.size(), digest);
    }

    inline static std::string calc_hex(
            const std::string& text,
            const std::string& key ) {
        return calc_hex(reinterpret_cast<const uint8_t*>(text.c_str()), text.size(),
                reinterpret_cast<const uint8_t*>(key.c_str()), key.size());
    }

    static std::string calc_hex(
            const uint8_t* text, int text_len,
            const uint8_t* key,  int key_len ) {
        int i;
        uint8_t digest[HASH_SIZE];
        assert(key);
        assert(text);
        std::ostringstream oss;
        oss << std::hex << std::setfill('0');
        hmac<T> ctx(key, key_len);
        ctx.input(text, text_len);
        ctx.result(digest);
        for (i = 0; i < HASH_SIZE; i++)
            oss << std::setw(2) << (digest[i] & 0xff);
        oss << std::dec;
        return oss.str();
    }

    hmac(const uint8_t* key, int key_len) : hasher_(T()) {
        assert(key);
        reset(key, key_len);
    }

    hmac(const std::string& key) : hasher_(T()) {
        reset(reinterpret_cast<const uint8_t*>(key.c_str()), key.size());
    }

    ~hmac() { }

    inline void reset(const std::string& key) {
        reset(reinterpret_cast<const uint8_t*>(key.c_str()), key.size());
    }

    void reset(const uint8_t* key, int key_len) {

        int i;
        uint8_t k_ipad[BLOCK_SIZE];
        uint8_t tempkey[HASH_SIZE];

        assert(key);

        if (key_len > static_cast<int>(BLOCK_SIZE)) {
            T sha;
            sha.input(key, key_len);
            sha.result(tempkey);
            key = tempkey;
            key_len = HASH_SIZE;
        }

        for (i=0; i < key_len; i++) {
            k_ipad[i]  = key[i] ^ 0x36;
            k_opad_[i] = key[i] ^ 0x5c;
        }

        for (; i < static_cast<int>(BLOCK_SIZE); i++) {
            k_ipad[i]  = 0x36;
            k_opad_[i] = 0x5c;
        }

        hasher_.reset();
        hasher_.input(k_ipad, static_cast<int>(BLOCK_SIZE));
    }

    inline void input(const std::string& text) {
        input(reinterpret_cast<const uint8_t*>(text.c_str()), text.size());
    }

    void input(const uint8_t* text, int text_len) {
        assert(text);
        hasher_.input(text, text_len);
    }

    void final_bits(const uint8_t bits, unsigned int bitcount) {
        hasher_.final_bits(bits, bitcount);
    }

    void result(uint8_t digest[HASH_SIZE]) {
        assert(digest);
        hasher_.result(digest);
        hasher_.reset();
        hasher_.input(k_opad_, BLOCK_SIZE);
        hasher_.input(digest, HASH_SIZE);
        hasher_.result(digest);
    }

private:
    uint8_t k_opad_[BLOCK_SIZE];
    T hasher_;
}; // end of class

}  // end of namespace

inline crypto_hmac_sha256::crypto_hmac_sha256(const uint8_t *key, std::size_t key_len) {
  ctx_ = new cryptlite__::hmac<cryptlite__::sha256>(key, key_len);
}

inline crypto_hmac_sha256::~crypto_hmac_sha256() {
  delete ctx_;
}

inline void crypto_hmac_sha256::update(const uint8_t *buf, std::size_t len) {
  ctx_->input(buf, len);
}

inline void crypto_hmac_sha256::final(uint8_t dst[32] /* out */) {
  ctx_->result(dst);
}

} // namespace chef

#endif


//  (C) Copyright Raffi Enficiaud 2014.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.

//[example_code
#define BOOST_TEST_MODULE dataset_example65
#include <boost/test/included/unit_test.hpp>
#include <boost/test/data/test_case.hpp>
#include <boost/test/data/monomorphic.hpp>

namespace bdata = boost::unit_test::data;

BOOST_DATA_TEST_CASE(
  test1,
  bdata::make(2),
  singleton)
{
  std::cout
    << "test 1: "
    << singleton << std::endl;
  BOOST_TEST(singleton == 2);
}

BOOST_DATA_TEST_CASE(
  test2,
  bdata::xrange(3) ^ bdata::make(2),
  xr, singleton)
{
  std::cout
    << "test 2: "
    << xr << ", " << singleton << std::endl;
  BOOST_TEST(singleton == 2);
}
//]


// Date Last Altered: $Date: 2008-08-04 22:55:41 -0600 (Mon, 04 Aug 2008) $
// Revision Number: $Revision: 344 $
//--------------------------------------------*-C++-*------------------------------------//
/*! \file MeshConcept.hh
 *  \author Greg Davidson
 *  \date November 6, 2006
 *
 *  \brief Provides the \c CartesianMeshConcept concept class.
 *
 *  This file provides the \c CartesianMeshConcept concept class.  This is provided to
 *  require that all \c CartesianMesh types provide certain minimal functionality. */

#ifndef MESHCONCEPT_HH
#define MESHCONCEPT_HH

#include <boost/concept_check.hpp>

#include "Types.hh"
#include "Dimension.hh"

using boost::function_requires;
using boost::ConvertibleConcept;
using boost::UnsignedIntegerConcept;

/*! \addtogroup MeshMod Mesh Module
 *  @{  */

/*! \brief Depicts the functionality that all \c CartesianMesh types must implement.
 *
 *  The \c CartesianMeshConcept class template dictates what functionality
 *  all \c CartesianMesh types must implement.
 *  \par Template Parameters:
 *     <dl> <dt> \e mesh_type </dt>
 *          <dd> The mesh type to check for concept conformity. </dd> </dl>
 *  \par Concept Requirements:
 *       The following types must be provided by the \c mesh_type type:
 *       <TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" WIDTH="100%">
 *          <TR>  <TD> \arg \c DimensionType </TD>
 *                <TD> The \c mesh_type type must provide a \c DimensionType. </TD> </TR>
 *          <TR>  <TD> \arg \c LengthType </TD>
 *                <TD> All \c mesh_type types must provide a \c LengthType. </TD> </TR>
 *          <TR>  <TD> \arg \c SizeType </TD>
 *                <TD> All \c mesh_type types must provide a \c SizeType. </TD> </TR>
 *          <TR>  <TD> \arg \c Zone </TD>
 *                <TD> All \c mesh_type types must provide a \c Zone. </TD> </TR>
 *          <TR>  <TD> \arg \c Node </TD>
 *                <TD> All \c mesh_type types must provide a \c Node. </TD> </TR>
 *          <TR>  <TD> \arg \c Corner </TD>
 *                <TD> All \c mesh_type types must provide a \c Corner. </TD> </TR>
 *          <TR>  <TD> \arg \c const_ZoneIterator </TD>
 *                <TD> All \c mesh_type types must provide a \c const_ZoneIterator
 *                                                                            type. </TD> </TR>
 *          <TR>  <TD> \arg \c const_NodeIterator </TD>
 *                <TD> All \c mesh_type types must provide a \c const_NodeIterator
 *                                                                            type. </TD> </TR>
 *          <TR>  <TD> \arg \c const_CornerIterator </TD>
 *                <TD> All \c mesh_type types must provide a \c const_CornerIterator
 *                                                                             type. </TD> </TR>
 *          <TR>  <TD> \arg \c SweepIterator </TD>
 *                <TD> All \c mesh_type types must provide a \c SweepIterator
 *                                                                             type. </TD> </TR>
 *       </TABLE>
 *       The following functionality must be provided by the \c mesh_type type:
 *       \arg The \c DimensionType must satisfy the \c DimensionConcept concept.
 *       \arg The \c LengthType type must be convertible to a \c Real8 type.
 *       \arg The \c SizeType type must satisfy the UnsignedIntegerConcept concept.
 *       \arg The \c mesh_type must provide a \c length() accessor.
 *       \arg The \c mesh_type must provide a \c area() accessor.
 *       \arg The \c mesh_type must provide a \c volume() accessor.
 *       \arg The \c mesh_type must provide a \c numZones() accessor.
 *       \arg The \c mesh_type must provide a \c numNodes() accessor.
 *       \arg The \c mesh_type must provide a \c numCorners() accessor.
 *       \arg The \c mesh_type must provide a \c getZone(Zone::Id) method.
 *       \arg The \c mesh_type must provide a \c getNode(Node::Id) method.
 *       \arg The \c mesh_type must provide a \c getCorner(Corner::Id) method.
 *       \arg The \c mesh_type must provide a \c zoneBegin() method.
 *       \arg The \c mesh_type must provide a \c zoneEnd() method.
 *       \arg The \c mesh_type must provide a \c nodeBegin() method.
 *       \arg The \c mesh_type must provide a \c nodeEnd() method.
 *       \arg The \c mesh_type must provide a \c cornerBegin() method.
 *       \arg The \c mesh_type must provide a \c cornerEnd() method.
 *       \arg The \c mesh_type must provide a \c sweepBegin(<tt>Angle</tt><\c DimensionType>) method.
 *       \arg The \c mesh_type must provide a \c sweepEnd(<tt>Angle</tt>< \c DimensionType>) method.
 *  \remarks  It should be noted that this class is compiled but never executed, so concept
 *            checking does not imply any runtime overhead. */
template<typename mesh_type>
class CartesianMeshConcept
{
public:
   // ****** Defines the required mesh types ******
   /// The \c mesh_type must provide a \c DimensionType type.
   typedef typename mesh_type::DimensionType          DimensionType;
   /// The \c mesh_type must provide a \c LengthType type.
   typedef typename mesh_type::LengthType             LengthType;
   /// The \c mesh_type must provide a \c SizeType type.
   typedef typename mesh_type::SizeType               SizeType;
   /// The \c mesh_type must provide a \c Zone type.
   typedef typename mesh_type::Zone                   Zone;
   /// The \c mesh_type must provide a \c Node type.
   typedef typename mesh_type::Node                   Node;
   /// The \c mesh_type must provide a \c Corner type.
   typedef typename mesh_type::Corner                 Corner;
   /// The \c mesh_type must provide a \c const_ZoneIterator type.
   typedef typename mesh_type::const_ZoneIterator     const_ZoneIterator;
   /// The \c mesh_type must provide a \c const_NodeIterator type.
   typedef typename mesh_type::const_NodeIterator     const_NodeIterator;
   /// The \c mesh_type must provide a \c const_CornerIterator type.
   typedef typename mesh_type::const_CornerIterator   const_CornerIterator;
   /// The \c mesh_type must provide a \c SweepIterator type.
   typedef typename mesh_type::SweepIterator          SweepIterator;

   // ****** Tests the required mesh functionality ******
   /*! \brief The constraints method tests that the \c mesh_type
    *         provides certain functionality. */
   void constraints()
   {
      function_requires< DimensionConcept<DimensionType> >();
      function_requires< ConvertibleConcept<LengthType, Real8> >();
      function_requires< UnsignedIntegerConcept<SizeType> >();

      // Basic mesh sizes
      LengthType length = mMesh->length();
      LengthType area   = mMesh->area();
      LengthType volume = mMesh->volume();

      // Meshes must have a way to number the geometric elements
      SizeType num_zones   = mMesh->numZones();
      SizeType num_nodes   = mMesh->numNodes();
      SizeType num_corners = mMesh->numCorners();

      // Meshes must have a way to access particular elements
      const Zone& zone     = mMesh->getZone( mZoneId );
      const Node& node     = mMesh->getNode( mNodeId );
      const Corner& corner = mMesh->getCorner( mCornerId );

      // Meshes must support at least forward iterators over each element
      mZoneIterator   = mMesh.zoneBegin();
      mZoneIterator   = mMesh.zoneEnd();
      mNodeIterator   = mMesh.nodeBegin();
      mNodeIterator   = mMesh.nodeEnd();
      mCornerIterator = mMesh.cornerBegin();
      mCornerIterator = mMesh.cornerEnd();

      // Meshes must support sweep iterators
      mSweepIterator = mMesh.sweepBegin(mAngle);
      mSweepIterator = mMesh.sweepEnd(mAngle);
   }

private:
   /// The \c mesh_type to use for the tests.
   mesh_type            mMesh;
   /// Used to test that the \c length() method returns a \c LengthType.
   LengthType           mLength;
   /// Used to test that the \c area() method returns a \c LengthType.
   LengthType           mArea;
   /// Used to test that the \c volume() method returns a \c LengthType.
   LengthType           mVolume;
   /// Used to test that the \c numZones() method returns a \c SizeType.
   SizeType             mNumZones;
   /// Used to test that the \c numNodes() method returns a \c SizeType.
   SizeType             mNumNodes;
   /// Used to test that the \c numCorners() method returns a \c SizeType.
   SizeType             mNumCorners;
   /// Used to test the \c getZone(Zone::Id) method.
   typename Zone::Id    mZoneId;
   /// Used to test the \c getNode(Node::Id) method.
   typename Node::Id    mNodeId;
   /// Used to test the \c getCorner(Corner::Id) method.
   typename Corner::Id  mCornerId;
   /*! \brief Used to test that the \c zoneBegin() and \c zoneEnd() methods
    *         return a \c const_ZoneIterator. */
   const_ZoneIterator   mZoneIterator;
   /*! \brief Used to test that the \c nodeBegin() and \c nodeEnd() methods
    *         return a \c const_NodeIterator. */
   const_NodeIterator   mNodeIterator;
   /*! \brief Used to test that the \c cornerBegin() and \c cornerEnd() methods
    *         return a \c const_CornerIterator. */
   const_CornerIterator mCornerIterator;
   /*! \brief Used to test that the \c sweepBegin(angle) and \c sweepEnd(angle)
    *         methods return a \c SweepIterator. */
   SweepIterator        mSweepIterator;
   /// Used as a parameter for the \c sweepBegin(angle) and \c sweepEnd(angle) methods.
   Angle<DimensionType> mAngle;
};

#endif


/**
 * @file
 * @brief UNITESTS for NPDE homework OutputImpedanceBVP
 * @author Erick Schulz
 * @date 28/03/2019
 * @copyright Developed at ETH Zurich
 */

#include <gtest/gtest.h>

#include <string>

#include <Eigen/Core>

#include <lf/assemble/assemble.h>
#include <lf/io/io.h>
#include <lf/mesh/hybrid2d/hybrid2d.h>
#include <lf/uscalfe/uscalfe.h>

#include "../evalclass.h"
#include "../outputimpedancebvp.h"

namespace OutputImpedanceBVP::test {

TEST(OutputImpedanceBVP, computeApproxSolDirichlet) {
  // Load mesh into a Lehrfem++ object
  auto mesh_factory = std::make_unique<lf::mesh::hybrid2d::MeshFactory>(2);
  const lf::io::GmshReader reader(std::move(mesh_factory), CURRENT_SOURCE_DIR
                                  "/../../meshes/unitsquare.msh");
  auto mesh_p = reader.mesh();  // type shared_ptr< const lf::mesh::Mesh>

  // Finite element space
  auto fe_space_p =
      std::make_shared<lf::uscalfe::FeSpaceLagrangeO1<double>>(mesh_p);
  // Obtain local->global index mapping for current finite element space
  const lf::assemble::DofHandler &dofh{fe_space_p->LocGlobMap()};
  // Dimension of finite element space
  const lf::uscalfe::size_type N_dofs(dofh.NumDofs());

  // Exact solution and Dirichlet boundary conditions
  Eigen::Vector2d g;
  g << 1.0, 3.0;
  auto uExact = [&g](Eigen::Vector2d x) -> double { return g.dot(x); };
  auto uExact_vec = interpolateData<std::function<double(Eigen::Vector2d)>>(
      fe_space_p, std::move(uExact));

  // Solve BVP
  Eigen::VectorXd uApprox_vec = solveImpedanceBVP(fe_space_p, g);

  ASSERT_TRUE(uApprox_vec.isApprox(uExact_vec));
}

}  // namespace OutputImpedanceBVP::test


/* Copyright (C) 2012-2020 IBM Corp.
 * This program is 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. See accompanying LICENSE file.
 */
#include <cassert>
#include <cstring>
#include <fstream>
#include <utility>
#include <unistd.h>

#include <NTL/ZZX.h>
#include <NTL/vector.h>

#include <helib/helib.h>
#include <helib/ArgMap.h>

#include <helib/debugging.h>

NTL_CLIENT
using namespace helib;

bool isLittleEndian()
{
    int i=1;
    return static_cast<bool>(*reinterpret_cast<char *>(&i));
}

void cleanupFiles(const char* file){
  if(unlink(file)) cerr<< "Delete of "<< file <<" failed."<<endl;
}

template<class... Files>
void cleanupFiles(const char * file, Files... files){
  cleanupFiles(file);
  cleanupFiles(files...);
}

// Compare two binary files, return 0 if they are equal, -1 if they
// have different length, and 1 if they have the same length but
// different content.
long compareFiles(string filename1, string filename2)
{

  ifstream file1(filename1);
  ifstream file2(filename2);

  if(!file1.is_open() && !file2.is_open()){
    cerr << "Could not open one of the following files:" << endl;
    cerr << filename1 << " and/or " << filename2 << endl;
    exit(EXIT_FAILURE);
  }

  fstream::pos_type file1size, file2size;

  file1size = file1.seekg(0, ifstream::end).tellg();
  file1.seekg(0, ifstream::beg);

  file2size = file2.seekg(0, ifstream::end).tellg();
  file2.seekg(0, ifstream::beg);

  // Quick compare sizes.
  if(file1size != file2size){
    file1.close();
    file2.close();
    cerr << "Files "<<filename1<<" and "<<filename2<<" not the same size :("<< endl;
    return -1;
  }

  // Now compare byte blocks at a time.
  const size_t BLOCKSIZE = 4096; // 4 kB

  char buffer1[BLOCKSIZE];
  char buffer2[BLOCKSIZE];
  size_t curBlckSz = 0;

  for(size_t i=file1size, cnt=0; i > 0; i-=curBlckSz, cnt++) {

    curBlckSz = std::min(BLOCKSIZE, i);

    file1.read(buffer1, curBlckSz);
    file2.read(buffer2, curBlckSz);

    if(memcmp(buffer1, buffer2, curBlckSz)) {
      cerr << "Block "
           <<cnt<<" (block size: "<<BLOCKSIZE<<" bytes) "
           <<cnt<<" does not match :("<<endl;
      return 1;
    }
  }
  return 0; // Files are the same!
}

int main(int argc, char *argv[])
{
  ArgMap amap;

  bool noPrint=true;
  long m=7;
  long r=1;
  long p=2;
  long c=2;
  long w=64;
  long L=300;
  long cleanup=1;
  string sampleFilePrefix;

  amap.arg("m", m, "order of cyclotomic polynomial");
  amap.arg("p", p, "plaintext base");
  amap.arg("r", r, "lifting");
  amap.arg("c", c, "number of columns in the key-switching matrices");
  amap.arg("L", L, "number of levels wanted");
  amap.arg("sample", sampleFilePrefix, "sample file prefix e.g. <prefix>_BE.txt");
  amap.arg("cleanup", cleanup, "cleanup files created");
  amap.arg("noPrint", noPrint, "suppress printouts");
  amap.parse(argc, argv);

  // FIXME: this is wrong!
  const char* asciiFile1 = "../misc/iotest_ascii1.txt";
  const char* asciiFile2 = "../misc/iotest_ascii2.txt";
  const char* binFile1 = "../misc/iotest_bin.bin";
  const char* otherEndianFileOut = "../misc/iotest_ascii3.txt";

  { // 1. Write ASCII and bin files.
    ofstream asciiFile(asciiFile1);
    ofstream binFile(binFile1, ios::binary);
    assert(asciiFile.is_open());

    std::unique_ptr<Context> context(new Context(m, p, r));
    buildModChain(*context, L, c);  // Set the modulus chain

    if (!noPrint) {
      cout << "Test to write out ASCII and Binary Files.\n";
      context->zMStar.printout(); // Printout context params
      cout << "\tSecurity Level: " << context->securityLevel() << endl;
    }
    std::unique_ptr<SecKey> secKey(new SecKey(*context));
    PubKey* pubKey = (PubKey*) secKey.get();
    secKey->GenSecKey(w);
    addSome1DMatrices(*secKey);
    addFrbMatrices(*secKey);

#ifdef DEBUG_PRINTOUT
        dbgEa = context->ea;
        dbgKey = secKey.get();
#endif

    // ASCII
    if (!noPrint)
      cout << "\tWriting ASCII1 file " << asciiFile1 << endl;
    writeContextBase(asciiFile, *context);
    asciiFile << *context << endl << endl;
    asciiFile << *pubKey << endl << endl;
    asciiFile << *secKey << endl << endl;

    // Bin
    if (!noPrint)
      cout << "\tWriting Binary file " << binFile1<< endl;
    writeContextBaseBinary(binFile, *context);
    writeContextBinary(binFile, *context);
    writePubKeyBinary(binFile, *pubKey);
    writeSecKeyBinary(binFile, *secKey);

    asciiFile.close();
    binFile.close();
    cout << "GOOD\n";
  }
  { // 2. Read in bin files and write out ASCII.
    if (!noPrint)
      cout << "Test to read binary file and write it out as ASCII" << endl;

    ifstream inFile(binFile1, ios::binary);
    ofstream outFile(asciiFile2);

    // Read in context,
    std::unique_ptr<Context> context = buildContextFromBinary(inFile);
    readContextBinary(inFile, *context);

    // Read in SecKey and PubKey.
    std::unique_ptr<SecKey> secKey(new SecKey(*context));

#ifdef DEBUG_PRINTOUT
        dbgEa = context->ea;
        dbgKey = secKey.get();
#endif

    PubKey* pubKey = (PubKey*) secKey.get();

    readPubKeyBinary(inFile, *pubKey);
    readSecKeyBinary(inFile, *secKey);

    // ASCII
    if (!noPrint)
      cout << "\tWriting ASCII2 file." << endl;
    writeContextBase(outFile, *context);
    outFile << *context << endl << endl;
    outFile << *pubKey << endl << endl;
    outFile << *secKey << endl << endl;

    inFile.close();
    outFile.close();

    cout << "GOOD\n";
  }
  { // 3. Compare byte-wise the two ASCII files
    if (!noPrint)
      cout << "Comparing the two ASCII files\n";

    long differ = compareFiles(asciiFile1, asciiFile2);

    if(differ != 0){
      cout << "BAD\n";
      if (!noPrint)
        cout << "\tFAIL - Files differ. Return Code: " << differ << endl;
      exit(EXIT_FAILURE);
    }
    cout << "GOOD\n";
  }
  { // 4. Read in binary and perform operation.
    if (!noPrint)
      cout << "Test reading in Binary files and performing an operation between two ctxts\n";

    ifstream inFile(binFile1, ios::binary);

    // Read in context,
    std::unique_ptr<Context> context = buildContextFromBinary(inFile);
    readContextBinary(inFile, *context);

    // Read in PubKey.
    std::unique_ptr<SecKey> secKey(new SecKey(*context));
    PubKey* pubKey = (PubKey*) secKey.get();

#ifdef DEBUG_PRINTOUT
        dbgEa = context->ea;
        dbgKey = secKey.get();
#endif

        readPubKeyBinary(inFile, *pubKey);
    readSecKeyBinary(inFile, *secKey);
    inFile.close();

    // Get the ea
    const EncryptedArray& ea = *context->ea;

    // Setup some ptxts and ctxts.
    Ctxt c1(*pubKey), c2(*pubKey);
    PlaintextArray p1(ea),  p2(ea);

    random(ea, p1);
    random(ea, p2);

    ea.encrypt(c1, *pubKey, p1);
    ea.encrypt(c2, *pubKey, p2);

    // Operation multiply and add.
    mul(ea, p1, p2);
    c1.multiplyBy(c2);
    //c1 *= c2;

    // Decrypt and Compare.
    PlaintextArray pp1(ea);
    ea.decrypt(c1, *secKey, pp1);

    if(!equals(ea, p1, pp1)) {
      cout << "BAD\n";
      exit(EXIT_FAILURE);
    }
    cout << "GOOD\n";

    if(cleanup) {
      if (!noPrint)
        cout << "Clean up. Deleting created files." << endl;
      cleanupFiles(asciiFile1, asciiFile2, binFile1);
    }
  }
  { // 5. Read in binary from opposite little endian and print ASCII and compare
    bool littleEndian = isLittleEndian();

    string otherEndianFileIn
      = sampleFilePrefix + (littleEndian? "_BE.bin" : "_LE.bin");
    string otherEndianASCII
      = sampleFilePrefix + (littleEndian? "_BE.txt" : "_LE.txt");

    if (!noPrint)
      cout << "Test to read in" << (littleEndian? " BE ":" LE ")
           << "binary file and write it out as ASCII" << endl;

    if(sampleFilePrefix.empty()) {
      if (!noPrint)
        cout << "\tSample prefix not provided, test not done." << endl;
    } else {
      if (!noPrint)
        cout << "\tSample file used: " << otherEndianFileIn << endl;

      ifstream inFile(otherEndianFileIn, ios::binary);

      if(!inFile.is_open()) {
        cout << "BAD boo!\n";
        if (!noPrint)
          cout << "  file " << otherEndianFileIn
               << " could not be opened.\n";
        exit(EXIT_FAILURE);
      }
      ofstream outFile(otherEndianFileOut);

      // Read in context,
      std::unique_ptr<Context> context = buildContextFromBinary(inFile);
      readContextBinary(inFile, *context);

      // Read in SecKey and PubKey.
      std::unique_ptr<SecKey> secKey(new SecKey(*context));
      PubKey* pubKey = (PubKey*) secKey.get();

#ifdef DEBUG_PRINTOUT
        dbgEa = context->ea;
        dbgKey = secKey.get();
#endif

        readPubKeyBinary(inFile, *pubKey);
      readSecKeyBinary(inFile, *secKey);
      inFile.close();

      // ASCII
      if (!noPrint)
        cout << "\tWriting other endian file." << endl;
      writeContextBase(outFile, *context);
      outFile << *context << endl << endl;
      outFile << *pubKey << endl << endl;
      outFile << *secKey << endl << endl;
      outFile.close();

      // Compare byte-wise the two ASCII files
      if (!noPrint)
        cout << "Comparing the two ASCII files\n";

      long differ = compareFiles(otherEndianASCII, otherEndianFileOut);

      if(differ != 0) {
        cout << "BAD\n";
        exit(EXIT_FAILURE);
      }
      cout << "GOOD\n";

      if(cleanup) {
        if (!noPrint)
          cout << "Clean up. Deleting created files." << endl;
        cleanupFiles(otherEndianFileOut);
      }
    }
  }
  return 0;
}


//==============================================================================
//         Copyright 2003 - 2012   LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2012   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
//==============================================================================
#define NT2_UNIT_MODULE "nt2 complex.arithmetic toolbox - cmplx_testing/simd Mode"

//////////////////////////////////////////////////////////////////////////////
// unit test behavior of complex.arithmetic components in simd  mode
//////////////////////////////////////////////////////////////////////////////
/// created by jt the 13/01/2012
///
#include <nt2/include/functions/abs.hpp>
#include <boost/simd/sdk/simd/io.hpp>
#include <boost/simd/sdk/simd/native.hpp>
#include <nt2/include/functions/splat.hpp>
#include <nt2/include/functions/real.hpp>
#include <boost/type_traits/is_same.hpp>
#include <nt2/sdk/functor/meta/call.hpp>
#include <nt2/sdk/meta/as_integer.hpp>
#include <nt2/sdk/meta/as_floating.hpp>
#include <nt2/sdk/meta/as_signed.hpp>
#include <nt2/sdk/meta/upgrade.hpp>
#include <nt2/sdk/meta/downgrade.hpp>
#include <nt2/sdk/meta/scalar_of.hpp>
#include <boost/dispatch/meta/as_floating.hpp>
#include <boost/type_traits/common_type.hpp>
#include <nt2/sdk/unit/tests.hpp>
#include <nt2/sdk/unit/module.hpp>

#include <nt2/toolbox/constant/constant.hpp>
#include <nt2/sdk/meta/cardinal_of.hpp>
#include <nt2/include/functions/splat.hpp>

#include <nt2/include/functions/load.hpp>
#include <nt2/sdk/complex/complex.hpp>
#include <nt2/sdk/complex/dry.hpp>
#include <nt2/sdk/complex/imaginary.hpp>
#include <nt2/sdk/complex/meta/as_complex.hpp>
#include <nt2/sdk/complex/meta/as_imaginary.hpp>
#include <nt2/sdk/complex/meta/as_dry.hpp>

NT2_TEST_CASE_TPL ( abs_cplx__1_0,   BOOST_SIMD_SIMD_REAL_TYPES)
{
  using boost::simd::native;
  typedef NT2_SIMD_DEFAULT_EXTENSION  ext_t;
  typedef std::complex<T>                              cT;
  typedef native<T ,ext_t>                             vT;
  typedef native<cT ,ext_t>                           vcT;
  typedef typename nt2::meta::as_imaginary<T>::type   ciT;
  typedef native<ciT ,ext_t>                         vciT;
  typedef typename nt2::meta::as_dry<T>::type          dT;
  typedef native<dT ,ext_t>                           vdT;

  NT2_TEST_EQUAL(nt2::abs(vcT(nt2::Inf<vT>(),nt2::Nan<vT>())), nt2::Inf<vT>());
  NT2_TEST_EQUAL(nt2::abs(vcT(nt2::Inf<vT>(), nt2::Zero<vT>())), nt2::Inf<vT>());
  NT2_TEST_EQUAL(nt2::abs(vcT(nt2::Minf<vT>(), nt2::Zero<vT>())), nt2::Inf<vT>());
  NT2_TEST_EQUAL(nt2::abs(vcT(nt2::Mone<vT>(), nt2::Zero<vT>())), nt2::One<vT>());
  NT2_TEST_EQUAL(nt2::abs(vcT(nt2::Nan<vT>(), nt2::Zero<vT>())), nt2::Nan<vT>());
  NT2_TEST_EQUAL(nt2::abs(vcT(nt2::One<vT>(), nt2::Zero<vT>())), nt2::One<vT>());
  NT2_TEST_EQUAL(nt2::abs(vcT(nt2::Valmax<vT>(), nt2::Zero<vT>())), nt2::Valmax<vT>());
  NT2_TEST_EQUAL(nt2::abs(vcT(nt2::Valmin<vT>(), nt2::Zero<vT>())), nt2::Valmax<vT>());
  NT2_TEST_EQUAL(nt2::abs(vcT(nt2::Zero<vT>(), nt2::Zero<vT>())), nt2::Zero<vT>());
  NT2_TEST_ULP_EQUAL(nt2::abs(vcT(nt2::One<vT>(), nt2::One<vT>()))[0], nt2::Sqrt_2<T>(), 1);
  NT2_TEST_EQUAL(nt2::abs(vcT(nt2::Four<vT>(), nt2::Three<vT>())), nt2::Five<vT>());

  NT2_TEST_EQUAL(nt2::abs(vciT(nt2::Inf<vciT>())), nt2::Inf<vT>());
  NT2_TEST_EQUAL(nt2::abs(vciT(nt2::Inf<vciT>())   ), nt2::Inf<vT>());
  NT2_TEST_EQUAL(nt2::abs(vciT(nt2::Minf<vciT>())  ), nt2::Inf<vT>());
  NT2_TEST_EQUAL(nt2::abs(vciT(nt2::Mone<vciT>())  ), nt2::One<vT>());
  NT2_TEST_EQUAL(nt2::abs(vciT(nt2::Nan<vciT>())   ), nt2::Nan<vT>());
  NT2_TEST_EQUAL(nt2::abs(vciT(nt2::One<vciT>())   ), nt2::One<vT>());
  NT2_TEST_EQUAL(nt2::abs(vciT(nt2::Valmax<vciT>())), nt2::Valmax<vT>());
  NT2_TEST_EQUAL(nt2::abs(vciT(nt2::Valmin<vciT>())), nt2::Valmax<vT>());
  NT2_TEST_EQUAL(nt2::abs(vciT(nt2::Zero<vciT>() ) ), nt2::Zero<vT>());
  NT2_TEST_EQUAL(nt2::abs(vciT(nt2::One<vciT>()   )), nt2::One<vT>());
  NT2_TEST_EQUAL(nt2::abs(vciT(nt2::Four<vciT>() ) ), nt2::Four<vT>());

  NT2_TEST_EQUAL(nt2::abs(vdT(nt2::Inf<vdT>())   ), nt2::Inf<vT>());
  NT2_TEST_EQUAL(nt2::abs(vdT(nt2::Inf<vdT>())   ), nt2::Inf<vT>());
  NT2_TEST_EQUAL(nt2::abs(vdT(nt2::Minf<vdT>())  ), nt2::Inf<vT>());
  NT2_TEST_EQUAL(nt2::abs(vdT(nt2::Mone<vdT>())  ), nt2::One<vT>());
  NT2_TEST_EQUAL(nt2::abs(vdT(nt2::Nan<vdT>())   ), nt2::Nan<vT>());
  NT2_TEST_EQUAL(nt2::abs(vdT(nt2::One<vdT>())   ), nt2::One<vT>());
  NT2_TEST_EQUAL(nt2::abs(vdT(nt2::Valmax<vdT>())), nt2::Valmax<vT>());
  NT2_TEST_EQUAL(nt2::abs(vdT(nt2::Valmin<vdT>())), nt2::Valmax<vT>());
  NT2_TEST_EQUAL(nt2::abs(vdT(nt2::Zero<vdT>())  ), nt2::Zero<vT>());
  NT2_TEST_EQUAL(nt2::abs(vdT(nt2::One<vdT>())   ), nt2::One<vT>());
  NT2_TEST_EQUAL(nt2::abs(vdT(nt2::Four<vdT>())  ), nt2::Four<vT>());

} // end of test for floating_