text:
#include "Object.h"
#include "Camera.h"
#include "Light.h"
#include "read_json.h"
#include "write_ppm.h"
#include "viewing_ray.h"
#include "raycolor.h"
#include <Eigen/Core>
#include <vector>
#include <iostream>
#include <memory>
#include <limits>
#include <functional>
#include "read_rgba_from_png.h"
#include "rgba_to_rgb.h"

int main(int argc, char * argv[])
{
  Camera camera;
  std::vector< std::shared_ptr<Object> > objects;
  std::vector< std::shared_ptr<Light> > lights;

  std::vector<std::vector<unsigned char>> textures;
  std::vector<int> texture_height_offsets;
  bool use_textures = false;

  std::string outputname;

  if (argc == 2 && strcmp(argv[1], "texture") == 0)
  {
    outputname = "textured_seattle.ppm";
    use_textures = true;
    // Read a camera and scene description from given .json file
    read_json(
      "../shared/data/seattle-postcard.json",
      camera,
      objects,
      lights);

    // read texture files
    const char * default_input_file_names[] {
      "../images/seattle_skyline.png",
      "../images/floor_texture.png"
    };
    char ** input_file_names = const_cast<char **>(default_input_file_names);

    // background texture
    int background_width, background_height;
    std::vector<unsigned char> background_rgba;
    read_rgba_from_png(input_file_names[0], background_rgba, background_width, background_height);

    std::vector<unsigned char> background_rgb;
    rgba_to_rgb(background_rgba, background_width, background_height, background_rgb);
    textures.push_back(background_rgb);
    texture_height_offsets.push_back(background_height - 1);

    std::shared_ptr<Plane> background(new Plane());
    background->texture_id = 0;
    background->point = Eigen::Vector3d(0,0,-5);
    background->normal = Eigen::Vector3d(0,0,1).normalized();
    objects.push_back(background);

    // floor texture
    int floor_width, floor_height;
    std::vector<unsigned char> floor_rgba;
    read_rgba_from_png(input_file_names[1], floor_rgba, floor_width, floor_height);
    std::vector<unsigned char> floor_rgb;
    rgba_to_rgb(floor_rgba, floor_width, floor_height, floor_rgb);
    textures.push_back(floor_rgb);
    texture_height_offsets.push_back(floor_height - 1);

    std::shared_ptr<Plane> floor_plane(new Plane());
    floor_plane->texture_id = 1;
    floor_plane->point = Eigen::Vector3d(0,-1,0);
    floor_plane->normal = Eigen::Vector3d(0,1,0).normalized();
    objects.push_back(floor_plane);
  }
  else
  {
    // Read a camera and scene description from given .json file
    read_json(
      "../shared/data/untextured-seattle-postcard.json",
      camera,
      objects,
      lights);
    outputname = "untextured_seattle.ppm";
  }

  int width =  640;
  int height = 360;
  std::vector<unsigned char> rgb_image(3*width*height);
  // For each pixel (i,j)
  for(unsigned i=0; i<height; ++i)
  {
    for(unsigned j=0; j<width; ++j)
    {
      // Set background color
      Eigen::Vector3d rgb(0,0,0);

      // Compute viewing ray
      Ray ray;
      viewing_ray(camera,i,j,width,height,ray);

      // Shoot ray and collect color
      if (raycolor(ray,1.0,objects,lights,0, i, j, textures, texture_height_offsets, rgb))
      {
        // Write double precision color into image
        auto clamp = [](double s){ return std::max(std::min(s,1.0),0.0);};
        rgb_image[0+3*(j+width*i)] = 255.0*clamp(rgb(0));
        rgb_image[1+3*(j+width*i)] = 255.0*clamp(rgb(1));
        rgb_image[2+3*(j+width*i)] = 255.0*clamp(rgb(2));
      }
      else
      {
        rgb_image[0+3*(j+width*i)] = rgb(0);
        rgb_image[1+3*(j+width*i)] = rgb(1);
        rgb_image[2+3*(j+width*i)] = rgb(2);
      }
    }
  }

  write_ppm(outputname, rgb_image, width, height, 3);
}

ext: cpp


text:
//  Copyright (c) 2007-2013 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)

#if !defined(HPX_UTIL_SERIALIZE_EMPTY_TYPE_JAN_28_2013_0623AM)
#define HPX_UTIL_SERIALIZE_EMPTY_TYPE_JAN_28_2013_0623AM

#include <hpx/hpx_fwd.hpp>
#include <hpx/util/portable_binary_iarchive.hpp>
#include <hpx/util/portable_binary_oarchive.hpp>

#include <boost/serialization/serialization.hpp>
#include <boost/type_traits/is_empty.hpp>
#include <boost/utility/enable_if.hpp>

namespace boost { namespace serialization
{
    // This is a default implementation of serialization which kicks in for
    // empty types.
    template <typename T>
    BOOST_FORCEINLINE typename boost::enable_if<boost::is_empty<T> >::type
    serialize(hpx::util::portable_binary_oarchive&, T&, unsigned int const) {}

    template <typename T>
    BOOST_FORCEINLINE typename boost::enable_if<boost::is_empty<T> >::type
    serialize(hpx::util::portable_binary_iarchive&, T&, unsigned int const) {}
}}

#endif

ext: hpp


text:
/**
 * @example waveq3d/test/reflection_test.cc
 */
#include <boost/test/unit_test.hpp>
#include <usml/netcdf/netcdf_files.h>
#include <usml/waveq3d/waveq3d.h>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <boost/foreach.hpp>
#include <boost/progress.hpp>

BOOST_AUTO_TEST_SUITE(reflection_test)

using namespace boost ;
using namespace unit_test ;
using namespace numeric::ublas ;
using namespace usml::netcdf ;
using namespace usml::waveq3d ;

/**
 * @ingroup waveq3d_test
 * @{
 */

// TODO: reflect_flat_test disabled until reverb model delivered

/**
 * Monitor callbacks from reflection model.
 */
class reflection_callback {

public:
    eigenverb_collection* _collection ;
    double time ;
    double latitude ;
    bool surface ;
    bool bottom ;
    size_t surf_count ;
    size_t bot_count;

    /**
     * Initialize counter.
     */
    reflection_callback( eigenverb_collection* collection )
        : _collection(collection), time(0.0), latitude(),
          surface(false), bottom(false), surf_count(0), bot_count(0)
    {}

    virtual ~reflection_callback() {}

    bool check_count( size_t& old_count ) {
        bottom = surface = false ;
        if( surf_count != _collection->eigenverbs(1).size() ) {
            surf_count = _collection->eigenverbs(1).size() ;
            surface = true ;
        }
        if( bot_count != _collection->eigenverbs(0).size() ) {
            bot_count = _collection->eigenverbs(0).size() ;
            bottom = true ;
        }
        if( old_count != (surf_count + bot_count) ) {
            old_count = surf_count + bot_count ;
            if( surface ) {
                eigenverb_list elist = _collection->eigenverbs(1) ;
                eigenverb_list::iterator it = elist.end() ;
                --it ;
                latitude = it->position.latitude() ;
                time = it->time ;
            }
            else if( bottom ) {
                eigenverb_list elist = _collection->eigenverbs(0) ;
                eigenverb_list::iterator it = elist.end() ;
                --it ;
                latitude = it->position.latitude() ;
                time = it->time ;
            }
        }
        return (surface || bottom) ;
    }

};

/**
 * Bottom and surface reflection in a flat bottomed isovelocity ocean.
 * Constructs a geometry in which the changes in latitude
 * and travel time between bounces can be calculated analytically.
 * The following equations predict the path of a downwardly
 * steered ray, given a \f$ \Delta \theta \f$ = latitude change
 * between the surface and the bottom.
 * \f[
 *      s^2 = R_1^2 + R_2^2 - 2 R_1 R_2 cos( \Delta \theta )
 * \f]\f[
 *      sin(\gamma_s) = \frac{ R_1^2 - R_2^2 + s^2 }
 *                         { 2 R_1 s }
 * \f]\f[
 *      \tau = s / c
 * \f]
 * where:
 *      - \f$ R_1 \f$ = radius to ocean surface
 *      - \f$ R_2 \f$ = radius to ocean bottom
 *      - \f$ R_2 - R_1 \f$ = ocean depth
 *      - \f$ \Delta\theta \f$ = latitude change between
 *        the surface and the bottom.
 *      - \f$ s \f$ = path length from surface to bottom
 *      - \f$ \gamma_s \f$ = grazing angle at surface
 *        = ray launch angle
 *      - \f$ \gamma_b  \f$ = grazing angle at bottom
 *        = \f$ \gamma_s - \Delta\theta \f$
 *      - \f$ c      \f$ = sound speed
 *      - \f$ \tau   \f$ = travel time between the surface and the bottom.
 *
 * Selecting \f$ \gamma \f$ to make the latitude change exactly 0.1 degrees
 * yields the following test values.
 *
 *      - \f$ R_1 \f$ = 6378101.030201019 m
 *      - \f$ R_2 \f$ = \f$ R_1 \f$ - 1000 m
 *      - \f$ \Delta \theta \f$ = 0.1 deg
 *      - \f$ s   \f$ = 11,175.841460125 m
 *      - \f$ \gamma_s \f$ = 5.183617057 deg
 *      - \f$ \gamma_b \f$ = 5.083617057 deg
 *      - \f$ c      \f$ = 1500 m/sec
 *      - \f$ \tau   \f$ = 7.450560973 sec
 *
 * Uses a 100 millisecond time step so that the time and location of the
 * collision can be compared to the analytic values without breaking
 * into the guts of the reflection model.
 */
BOOST_AUTO_TEST_CASE( reflect_flat_test ) {
    cout << "=== reflection_test: reflect_flat_test ===" << endl ;
    try {
        const double src_lat = 45.0; // default to 45 degrees

        // initialize propagation model

        // Ensure static (global scope of test framework) set
        wposition::compute_earth_radius(src_lat) ;
        const double c0 = 1500.0 ;
        profile_model*  profile = new profile_linear(c0) ;
        boundary_model* surface = new boundary_flat() ;
        boundary_model* bottom  = new boundary_flat(1000.0) ;
        ocean_model ocean( surface, bottom, profile ) ;

        seq_log freq( 10.0, 10.0, 1 ) ;
        wposition1 pos( 45.0, -45.0, 0.0 ) ;
        seq_linear de( -5.183617057, 0.0, 1 ) ;  // steer down
        seq_linear az( 0.0, 0.0, 1 ) ;           // north
        const double time_step = 0.1 ;           // 100 msec
        const double max_time = 60.0 ;           // maximum travel time

        wave_queue wave( ocean, freq, pos, de, az, time_step ) ;
        eigenverb_collection verb_collection( 0 ) ;
        wave.add_eigenverb_listener( &verb_collection ) ;
        reflection_callback callback( &verb_collection ) ;
        size_t old_count = callback.surf_count + callback.bot_count ;
        double max_time_error = 0.0 ;
        double max_lat_error = 0.0 ;

        // initialize output to spreadsheet file

        const char* name = USML_TEST_DIR "/waveq3d/test/reflect_flat_test.csv" ;
        std::ofstream os(name) ;
        cout << "Writing tables to " << name << endl ;

        os << "t,"
           << "lat,lng,alt,"
           << "de,az,bot,srf,cst,"
           << "r,theta,phi,"
           << "rd,thd,phid,"
           << "mu,eta,nu,"
           << "mud,etad,nud,"
           << "c,dcdz"
           << endl ;
        os << std::scientific << std::showpoint << std::setprecision(18) ;

        cout << "time step = " << time_step << " secs" << endl ;

        // propagate rays to stimulate bottom and surface reflections

        while ( wave.time() < max_time ) {

            // write to spreadsheet file

            wvector1 ndir( wave.curr()->ndirection, 0, 0 ) ;
            double de, az ;
            ndir.direction( &de, &az ) ;

            os << wave.time() << ','
               << wave.curr()->position.latitude(0,0) << ','
               << wave.curr()->position.longitude(0,0) << ','
               << wave.curr()->position.altitude(0,0) << ','
               << de << "," << az << ","
               << wave.curr()->surface(0,0) << ','
               << wave.curr()->bottom(0,0) << ','
               << wave.curr()->caustic(0,0) << ','
               << wave.curr()->position.rho(0,0) << ','
               << wave.curr()->position.theta(0,0) << ','
               << wave.curr()->position.phi(0,0) << ','
               << wave.curr()->pos_gradient.rho(0,0) << ','
               << wave.curr()->pos_gradient.theta(0,0) << ','
               << wave.curr()->pos_gradient.phi(0,0) << ','
               << wave.curr()->ndirection.rho(0,0) << ','
               << wave.curr()->ndirection.theta(0,0) << ','
               << wave.curr()->ndirection.phi(0,0) << ','
               << wave.curr()->ndir_gradient.rho(0,0) << ','
               << wave.curr()->ndir_gradient.theta(0,0) << ','
               << wave.curr()->ndir_gradient.phi(0,0) << ','
               << wave.curr()->sound_speed(0,0) << ','
               << wave.curr()->sound_gradient.rho(0,0) << endl ;

            // move wavefront to next time step

            wave.step() ;

            // check location and time of reflections against analytic result

            if( callback.check_count( old_count ) ) {
                double predict_time = old_count * 7.450560973 ;
                double current_time = callback.time ;
                double predict_lat = 45.0 + old_count * 0.1 ;
                double current_lat = callback.latitude ;

                if ( callback.surface ) cout << "surface" ;
                if ( callback.bottom ) cout << "bottom " ;
                cout << " reflection at t=" << current_time
                     << " lat=" << current_lat
                     << endl ;

                double time_error = abs( current_time - predict_time ) ;
                max_time_error = max( time_error, max_time_error ) ;
                BOOST_CHECK_SMALL( time_error, 1e-4 ) ;

                double lat_error = abs( current_lat - predict_lat ) ;
                max_lat_error = max( lat_error, max_lat_error ) ;
                BOOST_CHECK_SMALL( lat_error, 1e-6 ) ;
            }
        }
        cout << "wave propagates for " << wave.time() << " secs" << endl
             << "max_time_error = " << max_time_error << " secs "
             << "max_lat_error = " << max_lat_error  << " deg " << endl ;
    } catch ( std::exception* except ) {
        BOOST_ERROR( except->what() ) ;
    }
}

/**
 * Modified version of the reflect_flat_test() in which the bottom
 * has a 1 degree up-slope in the latitude direction.  This change should
 * create a 2 degree increase in grazing angle for each reflection that
 * hits the bottom.
 */
BOOST_AUTO_TEST_CASE( reflect_slope_test ) {
    cout << "=== reflection_test: reflect_slope_test ===" << endl ;
    try {

        // initialize propagation model

        const double c0 = 1500.0 ;
        profile_model*  profile = new profile_linear(c0) ;
        boundary_model* surface = new boundary_flat() ;

        wposition1 slope_ref( 45.1, -45.0, 0.0 ) ;
        reflect_loss_model* slope_loss = new reflect_loss_rayleigh( reflect_loss_rayleigh::SILT ) ;
        boundary_model* bottom  = new boundary_slope(
            slope_ref, 1000.0, to_radians(1.0), 0.0, slope_loss ) ;

        ocean_model ocean( surface, bottom, profile ) ;

        seq_log freq( 10.0, 10.0, 1 ) ;
        wposition1 pos( 45.0, -45.0, 0.0 ) ;
        seq_linear de( -5.175034664, 0.0, 1 ) ;  // steer down
        seq_linear az( 0.0, 0.0, 1 ) ;           // north
        const double time_step = 0.001 ;

        wave_queue wave( ocean, freq, pos, de, az, time_step ) ;

        // initialize output to spreadsheet file

        const char* name = USML_TEST_DIR "/waveq3d/test/reflect_slope_test.csv" ;
        std::ofstream os(name) ;
        cout << "Writing tables to " << name << endl ;

        os << "t,"
           << "lat,lng,alt,"
           << "de,az,bot,surf,"
           << "r,theta,phi,"
           << "rd,thd,phid,"
           << "mu,eta,nu,"
           << "mud,etad,nud,"
           << "c,dcdz"
           << endl ;
        os << std::scientific << std::showpoint << std::setprecision(18) ;

        cout << "time step = " << time_step << " secs" << endl ;

        // propagate rays to stimulate bottom and surface reflections

        int bounce = 0 ;
        double old_de = de(0) ;
        while ( wave.time() < 25.0 ) {

            // write to spreadsheet file

            wvector1 ndir( wave.curr()->ndirection, 0, 0 ) ;
            double de, az ;
            ndir.direction( &de, &az ) ;

            os << wave.time() << ','
               << wave.curr()->position.latitude(0,0) << ','
               << wave.curr()->position.longitude(0,0) << ','
               << wave.curr()->position.altitude(0,0) << ','
               << de << "," << az << ","
               << wave.curr()->surface(0,0) << ','
               << wave.curr()->bottom(0,0) << ','
               << wave.curr()->position.rho(0,0) << ','
               << wave.curr()->position.theta(0,0) << ','
               << wave.curr()->position.phi(0,0) << ','
               << wave.curr()->pos_gradient.rho(0,0) << ','
               << wave.curr()->pos_gradient.theta(0,0) << ','
               << wave.curr()->pos_gradient.phi(0,0) << ','
               << wave.curr()->ndirection.rho(0,0) << ','
               << wave.curr()->ndirection.theta(0,0) << ','
               << wave.curr()->ndirection.phi(0,0) << ','
               << wave.curr()->ndir_gradient.rho(0,0) << ','
               << wave.curr()->ndir_gradient.theta(0,0) << ','
               << wave.curr()->ndir_gradient.phi(0,0) << ','
               << wave.curr()->sound_speed(0,0) << ','
               << wave.curr()->sound_gradient.rho(0,0) << endl ;

            // move wavefront to next time step

            wave.step() ;

            // check angle change for each reflection

            if ( old_de * de < 0.0 ) {
                ++bounce ;

                if ( old_de < 0.0 ) {
                    cout << "bottom  reflection at t=" << wave.time()
                         << " lat=" << wave.curr()->position.latitude(0,0)
                         << " old de=" << old_de << " new de=" << de
                         << " diff=" << (de+old_de)
                         << endl ;
                    BOOST_CHECK_SMALL( 2.0-(de+old_de), 0.001 ) ;
                } else {
                    cout << "surface reflection at t=" << wave.time()
                         << " lat=" << wave.curr()->position.latitude(0,0)
                         << " old de=" << old_de << " new de=" << de
                         << " diff=" << (old_de+de)
                         << endl ;
                    BOOST_CHECK_SMALL( old_de+de, 0.001 ) ;
                }
            }
            old_de = de ;
        }
        cout << "wave propagates for " << wave.time() << " secs" << endl ;

    } catch ( std::exception* except ) {
        BOOST_ERROR( except->what() ) ;
    }
}

/**
 * Reflect rays off of the ETOPO1 bottom near the Malta escarpment.
 * Ray path starts from 35:59N 16:00E, D/E=-20 deg AZ=270 deg.
 * A run for 90 seconds should propagate up the slope, turn around
 * and head back down the slope.  Because of slope features in the
 * latitude direction, the ray does not stay in the east-west plane.
 *
 * When the gcc -ffast-math compiler option is turned off, these results are
 * expected to be accurate to at least 0.09 percent.  With fast-math turned on,
 * the accuracy of the lat/long drops to 5e-5 percent, and about 6 meters
 * are lost on the accuracy in depth.
 */
BOOST_AUTO_TEST_CASE( reflect_grid_test ) {
    const char* csvname = USML_TEST_DIR "/waveq3d/test/reflect_grid_test.csv" ;
    const char* ncname = USML_TEST_DIR "/waveq3d/test/reflect_grid_test.nc" ;
    cout << "=== reflection_test: reflect_grid_test ===" << endl ;
    try {

        // define scenario parameters

        const double c0 = 1500.0 ;  // speed of sound

        const double lat1 = 35.5 ;  // Mediterranean sea
        const double lat2 = 36.5 ;  // malta escarpment
        const double lng1 = 15.25 ; // south-east of Sicily
        const double lng2 = 16.25 ;
        wposition::compute_earth_radius( (lat1+lat2)/2.0 ) ;

        wposition1 pos( 35.983333333, 16.0, -10.0 ) ;
        seq_linear de( -20.0, 1.0, 1 ) ;    // down
        seq_linear az( 270.0, 1.0, 1 ) ;    // west
        const double time_step = 0.1 ;
        const double time_max = 80.0 ;

        seq_log freq( 3000.0, 1.0, 1 ) ;

        // load bathymetry from ETOPO1 database

        cout << "load bathymetry" << endl ;
        boundary_model* bottom = new boundary_grid<double,2>( new netcdf_bathy(
    	    USML_DATA_DIR "/bathymetry/ETOPO1_Ice_g_gmt4.grd",
            lat1, lat2, lng1, lng2 ) ) ;

        // combine sound speed and bathymetry into ocean model

        profile_model*  profile = new profile_linear(c0) ;
        boundary_model* surface = new boundary_flat() ;
        ocean_model ocean( surface, bottom, profile ) ;

        // initialize output to spreadsheet file

        std::ofstream os(csvname) ;
        cout << "writting tables to " << csvname << endl ;

        os << "t,"
           << "lat,lng,alt,"
           << "de,az,surf,bot,"
           << "r,theta,phi,"
           << "rd,thd,phid,"
           << "mu,eta,nu,"
           << "mud,etad,nud,"
           << "c,dcdz"
           << endl ;
        os << std::scientific << std::showpoint << std::setprecision(18) ;

        cout << "time step = " << time_step << " secs" << endl ;

        // propagate rays & record to netCDF file

        wave_queue wave( ocean, freq, pos, de, az, time_step ) ;
        cout << "Writing wavefronts to " << ncname << endl ;
        wave.init_netcdf( ncname ) ;
        wave.save_netcdf() ;
        while ( wave.time() < time_max ) {

            // move wavefront to next time step

            wave.step() ;
            wave.save_netcdf() ;

            // write to spreadsheet file

            wvector1 ndir( wave.curr()->ndirection, 0, 0 ) ;
            double de, az ;
            ndir.direction( &de, &az ) ;

            os << wave.time() << ','
               << wave.curr()->position.latitude(0,0) << ','
               << wave.curr()->position.longitude(0,0) << ','
               << wave.curr()->position.altitude(0,0) << ','
               << de << "," << az << ","
               << wave.curr()->surface(0,0) << ','
               << wave.curr()->bottom(0,0) << ','
               << wave.curr()->position.rho(0,0) << ','
               << wave.curr()->position.theta(0,0) << ','
               << wave.curr()->position.phi(0,0) << ','
               << wave.curr()->pos_gradient.rho(0,0) << ','
               << wave.curr()->pos_gradient.theta(0,0) << ','
               << wave.curr()->pos_gradient.phi(0,0) << ','
               << wave.curr()->ndirection.rho(0,0) << ','
               << wave.curr()->ndirection.theta(0,0) << ','
               << wave.curr()->ndirection.phi(0,0) << ','
               << wave.curr()->ndir_gradient.rho(0,0) << ','
               << wave.curr()->ndir_gradient.theta(0,0) << ','
               << wave.curr()->ndir_gradient.phi(0,0) << ','
               << wave.curr()->sound_speed(0,0) << ','
               << wave.curr()->sound_gradient.rho(0,0) << endl ;
        }
        wave.close_netcdf() ;
        cout << "wave propagates for " << wave.time() << " secs" << endl ;

        // compare to prior runs

        #ifdef __FAST_MATH__
            const double position_accuracy = 5e-4 ;
        #else
            const double position_accuracy = 0.09 ;
        #endif
        BOOST_CHECK_CLOSE( wave.curr()->position.latitude(0,0), 36.169253160619995, position_accuracy ) ;
        BOOST_CHECK_CLOSE( wave.curr()->position.longitude(0,0), 16.012084836798909, position_accuracy ) ;

//        #ifdef __FAST_MATH__
//            BOOST_CHECK_SMALL( wave.curr()->position.altitude(0,0)+566.97501238062978, 6.0 ) ;
//        #else
//            BOOST_CHECK_SMALL( wave.curr()->position.altitude(0,0)+566.97501238062978, 1e-6 ) ;
//        #endif

    } catch ( std::exception* except ) {
        BOOST_ERROR( except->what() ) ;
    }
}

BOOST_AUTO_TEST_CASE( reflect_interp_spd_acc_test ){
    const char* csvname = USML_TEST_DIR "/waveq3d/test/reflect_interp_test.csv" ;
    cout << "=== reflection_test: reflect_interp_spd_acc_test ===" << endl ;

    // define scenario parameters

    const double c0 = 1500.0 ;  // speed of sound

    const double lat1 = 35.5 ;  // Mediterranean sea
    const double lat2 = 36.5 ;  // malta escarpment
    const double lng1 = 15.25 ; // south-east of Sicily
    const double lng2 = 16.25 ;
    wposition::compute_earth_radius( (lat1+lat2)/2.0 ) ;

    wposition1 pos( 35.983333333, 16.0, -10.0 ) ;
    seq_linear de( -20.0, 1.0, 1 ) ;    // down
    seq_linear az( 270.0, 1.0, 1 ) ;    // west
    const double time_step = 0.1 ;
    const double time_max = 80.0 ;

    seq_log freq( 3000.0, 1.0, 1 ) ;

    // load bathymetry from ETOPO1 database

    cout << "load bathymetry" << endl ;
    boundary_model* bottom = new boundary_grid<double,2>( new netcdf_bathy(
        USML_DATA_DIR "/bathymetry/ETOPO1_Ice_g_gmt4.grd",
        lat1, lat2, lng1, lng2 ) ) ;

    // combine sound speed and bathymetry into ocean model

    profile_model*  profile = new profile_linear(c0) ;
    boundary_model* surface = new boundary_flat() ;
    ocean_model ocean( surface, bottom, profile ) ;

    std::ofstream os(csvname) ;
    cout << "Writing tables to " << csvname << endl ;

    os << "t,"
       << "lat,lng,alt,"
       << "de,az,surf,bot,"
       << "r,theta,phi,"
       << "rd,thd,phid,"
       << "mu,eta,nu,"
       << "mud,etad,nud,"
       << "c,dcdz"
       << endl ;
    os << std::scientific << std::showpoint << std::setprecision(18) ;

    cout << "time step = " << time_step << " secs" << endl ;

    // propagate rays & record to netCDF file

    wave_queue wave( ocean, freq, pos, de, az, time_step ) ;
    while ( wave.time() < time_max ) {
        wave.step() ;

        wvector1 ndir( wave.curr()->ndirection, 0, 0 ) ;
        double de, az ;
        ndir.direction( &de, &az ) ;

        os << wave.time() << ','
           << wave.curr()->position.latitude(0,0) << ','
           << wave.curr()->position.longitude(0,0) << ','
           << wave.curr()->position.altitude(0,0) << ','
           << de << "," << az << ","
           << wave.curr()->surface(0,0) << ','
           << wave.curr()->bottom(0,0) << ','
           << wave.curr()->position.rho(0,0) << ','
           << wave.curr()->position.theta(0,0) << ','
           << wave.curr()->position.phi(0,0) << ','
           << wave.curr()->pos_gradient.rho(0,0) << ','
           << wave.curr()->pos_gradient.theta(0,0) << ','
           << wave.curr()->pos_gradient.phi(0,0) << ','
           << wave.curr()->ndirection.rho(0,0) << ','
           << wave.curr()->ndirection.theta(0,0) << ','
           << wave.curr()->ndirection.phi(0,0) << ','
           << wave.curr()->ndir_gradient.rho(0,0) << ','
           << wave.curr()->ndir_gradient.theta(0,0) << ','
           << wave.curr()->ndir_gradient.phi(0,0) << ','
           << wave.curr()->sound_speed(0,0) << ','
           << wave.curr()->sound_gradient.rho(0,0) << endl ;
   }
}

/**
 *
 */
BOOST_AUTO_TEST_CASE( bounce_threshold_test ) {
    cout << "=== reflection_test: bounce_threshold_test ===" << endl ;

    double depth = 1000.0 ;
    double c0 = 1500.0 ;
    double dt = 0.1 ;
    double max_time = 10.0 ;

    seq_linear freq( 900.0, 1.0, 1) ;
    seq_linear de(-90.0, 1.0, 90.0) ;
    seq_linear az(0.0, 30.0, 360.0) ;
    wposition1 src( 0.0, 0.0, -500.0 ) ;

    boundary_model* surface = new boundary_flat() ;
    boundary_model* bottom = new boundary_flat( depth, new reflect_loss_constant(0.0) ) ;
    profile_model* profile = new profile_linear( c0 ) ;
    ocean_model ocean( surface, bottom, profile ) ;

    wposition target(1, 1, 0.01, 0.0, -500.0) ;
    eigenray_collection loss( freq, src, de, az, dt, &target ) ;
    eigenverb_collection reverb( 0 ) ;
    wave_queue wave( ocean, freq, src, de, az, dt, &target ) ;
    wave.add_eigenray_listener(&loss) ;
    wave.add_eigenverb_listener(&reverb) ;
    wave.max_surface(3) ;
    wave.max_bottom(5) ;

    cout << "propagating for " << max_time << " seconds" << endl ;
    while ( wave.time() < max_time ) {
        wave.step() ;
    }

    eigenray_list* elist = loss.eigenrays(0,0) ;
    cout << "propagation complete, " << elist->size() << " rays were produced" << endl ;
    BOOST_FOREACH( eigenray e, *elist ) {
        BOOST_CHECK( e.bottom <= wave.max_bottom() ) ;
        BOOST_CHECK( e.surface <= wave.max_surface() ) ;
    }
    cout << "Checking eigenerbs for bottom interface" << endl ;
    eigenverb_list vlist = reverb.eigenverbs( eigenverb::BOTTOM ) ;
    BOOST_FOREACH( eigenverb v, vlist ) {
        BOOST_CHECK( v.bottom <= wave.max_bottom() ) ;
        BOOST_CHECK( v.surface <= wave.max_surface() ) ;
    }
    cout << "Checking eigenverbs for surface interface" << endl ;
    vlist = reverb.eigenverbs( eigenverb::SURFACE ) ;
    BOOST_FOREACH( eigenverb v, vlist ) {
        BOOST_CHECK( v.bottom <= wave.max_bottom() ) ;
        BOOST_CHECK( v.surface <= wave.max_surface() ) ;
    }

}
/// @}

BOOST_AUTO_TEST_SUITE_END()

ext: cc

max_stars_repo_name: fraclipe/UnderSeaModelingLibrary

max_issues_repo_name: Wolframy-NUDT/UnderSeaModelingLibrary

max_forks_repo_name: Wolframy-NUDT/UnderSeaModelingLibrary


text:
///////////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007, 2010 Michael A. Jackson for BlueQuartz Software
//  All rights reserved.
//  BSD License: http://www.opensource.org/licenses/bsd-license.html
//
//  This code was written under United States Air Force Contract number
//                           FA8650-04-C-5229
//
///////////////////////////////////////////////////////////////////////////////

//TODO: Write a Unit Test for Data Dimension Insertion

#include "MXA/MXA.h"
#include <MXA/Common/MXATypeDefs.h>
#include <MXA/Common/MXAEndian.h>
#include <MXA/Base/IDataFile.h>
#include <MXA/Base/IRequiredMetaData.h>
#include <MXA/Core/MXAConstants.h>
#include <MXA/Core/MXADataModel.h>
#include <MXA/Core/MXADataDimension.h>
#include <MXA/Core/MXADataRecord.h>
#include <MXA/HDF5/H5MXADataFile.h>
#include <MXA/HDF5/H5MXARequiredMetaData.h>
#include <MXA/DataWrappers/MXAArrayTemplate.hpp>
#include <MXA/DataWrappers/MXAAsciiStringData.h>
#include <Tests/MXAUnitTestDataFileLocations.h>
#include <MXA/Utilities/MXADir.h>
#include "UnitTestSupport.hpp"

// C++ Includes
#include <iostream>
#include <vector>
#include <map>

//Boost Includes
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void RemoveTestFiles()
{
#if REMOVE_TEST_FILES
  MXADir::remove(MXAUnitTest::DataModelTest::BeforeH5File);
  MXADir::remove(MXAUnitTest::DataModelTest::AfterH5File);
  MXADir::remove(MXAUnitTest::DataModelTest::OverwriteH5File);
#endif
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void TestRequiredMetaData()
{
  int32_t err = -1;
  std::string errorMessage;
 // std::cout << "TestRequiredMetaData Running...." ;
  MXADataModel::Pointer model = createModel();

  // Test setting the Required MetaData by individual strings
  std::string researcherName("");
  std::string dateCreated("");
  std::string datasetName("");
  std::string description("");
  std::string distributionRights("");
  std::string releaseNumber("");
  std::string pedigree("");
  std::string derivedSrcFile("");

  IRequiredMetaData::Pointer metaData = H5MXARequiredMetaData::New(researcherName, dateCreated,
                                   datasetName, description, distributionRights,
                                   releaseNumber, pedigree, derivedSrcFile);
  MXA_REQUIRE(metaData->isValid(errorMessage) == false);

  err = model->setRequiredMetaData(researcherName, dateCreated,
                                   datasetName, description, distributionRights,
                                   releaseNumber, pedigree, derivedSrcFile);
  errorMessage.clear();
  MXA_REQUIRE ( (model->isValid(errorMessage) ) == false );

  err = model->setRequiredMetaData(metaData);
  errorMessage.clear();
  MXA_REQUIRE ( (model->isValid(errorMessage) ) == false );

  //Create the Required MetaData
  std::map<std::string, std::string> md;
  md[MXA::MXA_CREATOR_TAG] = "Mike Jackson";
  err = model->setRequiredMetaData(md);
  MXA_REQUIRE(err == -1); // The data should NOT validate
  errorMessage.clear();

  md[MXA::MXA_DATE_TAG] = "2006:12:24 15:34.51";
  md[MXA::MXA_DSET_NAME_TAG] = "TESTING Example Data Model";
  md[MXA::MXA_DESCRIPTION_TAG] = "Just a test case showing how to organize OIM FIB data";
  md[MXA::MXA_PEDIGREE_TAG] = "Original";
  md[MXA::MXA_DERIVED_SRC_TAG] = "Original Data Files";
  md[MXA::MXA_RIGHTS_TAG] = "Unlimited";
  md[MXA::MXA_RELEASE_NUMBER_TAG] = "AFRL/WS07-0476";

  err = model->setRequiredMetaData(md);
  errorMessage.clear();
  MXA_REQUIRE ( (model->isValid(errorMessage) ) == true );

  researcherName = "Mike Jackson";
  dateCreated = "2006:12:24 15:34.51";
  datasetName = "TESTING Example Data Model";
  description = "Just a test case showing how to organize OIM FIB data";
  distributionRights = "Unlimited";
  releaseNumber = "AFRL/WS07-0476";
  pedigree = "Original";
  derivedSrcFile = "Original Data Files";

  err = model->setRequiredMetaData(researcherName, dateCreated,
                                   datasetName, description, distributionRights,
                                   releaseNumber, pedigree, derivedSrcFile);
  errorMessage.clear();
  MXA_REQUIRE(err >= 0);
  MXA_REQUIRE ( (model->isValid(errorMessage) ) == true );

  metaData = H5MXARequiredMetaData::New(researcherName, dateCreated,
                                     datasetName, description, distributionRights,
                                     releaseNumber, pedigree, derivedSrcFile);
  MXA_REQUIRE(metaData->isValid(errorMessage) == true);
  err = model->setRequiredMetaData(metaData);
  errorMessage.clear();
  MXA_REQUIRE(err >= 0);
  MXA_REQUIRE ( (model->isValid(errorMessage) ) == true );

  // std::cout << "......Passed" << std::endl;
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
bool recordExists(MXADataModel::Pointer model, std::string recName)
{
  IDataRecord::Pointer rec = model->getDataRecordByNamedPath(recName);
  //std::cout << "recName: " << recName << " <===> rec.get()" << rec.get() << std::endl;
  if (rec.get() != NULL) {
    return true;
  }
  return false;
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
bool recordInternalPathExists(MXADataModel::Pointer model, std::string recName)
{
  IDataRecord::Pointer rec = model->getDataRecordByInternalPath(recName);
  return (rec.get() != NULL) ? true : false;
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void TestLookupTableGeneration()
{
 // std::cout << "TestLookupTableGeneration Running...." << std::endl;
  MXADataModel::Pointer modelPtr = createModel();
  IDataRecord::Container records = modelPtr->getDataRecords();
  IDataRecord::LookupTable lut;
  MXADataRecord::generateLUT(lut, records);
  for (IDataRecord::LookupTable::iterator iter = lut.begin(); iter != lut.end(); ++iter )
  {
    MXADataRecord* rec = dynamic_cast<MXADataRecord*>( (*(iter)).second.get() );
    std::cout << (*(iter)).first << "  " << rec->getRecordName() << std::endl;
  }
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void TestRetrieveDataRecords()
{
  MXADataModel::Pointer model = createModel();
  MXA_REQUIRE( recordExists(model, "/Order Parameters/Eta1/") == true);
  MXA_REQUIRE( recordExists(model, "Order Parameters/Eta1") == true);
  MXA_REQUIRE( recordExists(model, "/Order Parameters/Eta1") == true);
  MXA_REQUIRE( recordExists(model, "Order Parameters/Eta1/") == true);
  MXA_REQUIRE( recordExists(model, "Order Parameters/Eta1/Junk") == false);
  MXA_REQUIRE( recordExists(model, "Order Parameters/Order Parameters 2/Junk") == false);
  MXA_REQUIRE( recordExists(model, "Order Parameters/Order Parameters 2/Eta1") == true);
  MXA_REQUIRE( recordExists(model, "Order Parameters/Order Parameters 2/") == true);
  MXA_REQUIRE( recordExists(model, "/Composition") == true);
  MXA_REQUIRE( recordExists(model, "/Composition") == true);
  MXA_REQUIRE( recordExists(model, "/Composition/") == true);
  MXA_REQUIRE( recordExists(model, "Composition/") == true);
  MXA_REQUIRE( recordExists(model, "/Composition/Eta1") == false);

  MXA_REQUIRE( recordExists(model, "") == false);
  MXA_REQUIRE( recordExists(model, "/") == false);
  MXA_REQUIRE( recordExists(model, "//") == false);
  MXA_REQUIRE( recordExists(model, "///") == false);

  MXA_REQUIRE( recordInternalPathExists(model, "") == false);
  MXA_REQUIRE( recordInternalPathExists(model, "/") == false);
  MXA_REQUIRE( recordInternalPathExists(model, "//") == false);
  MXA_REQUIRE( recordInternalPathExists(model, "///") == false);
  MXA_REQUIRE( recordInternalPathExists(model, "/1") == true);
  MXA_REQUIRE( recordInternalPathExists(model, "/0/2") == false);
  MXA_REQUIRE( recordInternalPathExists(model, "/0/0") == false);
  MXA_REQUIRE( recordInternalPathExists(model, "/0/1/") == false);
  MXA_REQUIRE( recordInternalPathExists(model, "/0/3/") == false);
  MXA_REQUIRE( recordInternalPathExists(model, "/1/3/") == true);
  MXA_REQUIRE( recordInternalPathExists(model, "/1/3/0") == true);
  MXA_REQUIRE( recordInternalPathExists(model, "/1/3/3") == false);
 // std::cout << "......Passed" << std::endl;
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void TestDataDimensionMethods()
{
 // std::cout << "Test DataDimensionMethods Running....";
  MXADataModel::Pointer model = createModel(); // Created on the stack
  int32_t error = 0;

  IDataDimension::Pointer dim0 = model->getDataDimension(0);
  IDataDimension::Pointer dim1 = model->getDataDimension(1);
  IDataDimension::Pointer dim2 = model->getDataDimension(2);
  IDataDimension::Pointer dim3 = model->getDataDimension(3);
  IDataDimension::Pointer dimNull = model->getDataDimension(4);
  MXA_REQUIRE(dim0.get() != NULL);
  MXA_REQUIRE(dim1.get() != NULL);
  MXA_REQUIRE(dim2.get() != NULL);
  MXA_REQUIRE(dim3.get() != NULL);
  MXA_REQUIRE(dimNull.get() == NULL); // The last one should be NULL because it does NOT exist

  //Test removing by index
  error = model->removeDataDimension(3); // Remove the last Dimension
  MXA_REQUIRE( error > 0);
  IDataDimension::Pointer test = model->getDataDimension(2);
  MXA_REQUIRE(test != dim3);
  MXA_REQUIRE(model->getDataDimensions().size() == 3);

  error = model->removeDataDimension(4); // Remove the last Dimension
  MXA_REQUIRE( error < 0);
  MXA_REQUIRE(model->getDataDimensions().size() == 3);

  //Test Removing by Name - This Dimension does exits and should decrement the count by 1
  error = model->removeDataDimension("Random Seed");
  MXA_REQUIRE( error > 0);
  MXA_REQUIRE(model->getDataDimensions().size() == 2);

  // Test removing a Dimension by name that does NOT exist.
  error = model->removeDataDimension("Junk");
  MXA_REQUIRE( error < 0);
  MXA_REQUIRE(model->getDataDimensions().size() == 2);
  // std::cout << "......Passed" << std::endl;
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void WriteTestModel()
{
  {
   // std::cout << "WriteTestModel Running....";
    MXADataModel::Pointer modelPtr = createModel();
    IDataFile::Pointer dataFile = H5MXADataFile::CreateFileWithModel(MXAUnitTest::DataModelTest::BeforeH5File, modelPtr);
    MXA_REQUIRE(dataFile.get() != 0x0);
    // std::cout << "......Passed" << std::endl;
  }

  {
   // std::cout << "Read DataModel Running...." ;
    IDataFile::Pointer dataFile = H5MXADataFile::OpenFile(MXAUnitTest::DataModelTest::BeforeH5File, false);
    MXA_REQUIRE(dataFile.get() != 0x0);
    IDataModel::Pointer modelPtr = dataFile->getDataModel();
    MXA_REQUIRE(modelPtr.get() != 0x0);
    // Resave the model. This should work with out any problems.
    MXA_REQUIRE (dataFile->saveDataModel() >= 0);
    // std::cout << "......Passed" << std::endl;
  }
}

// -----------------------------------------------------------------------------
//  Read a model from a data file on disk, then write that model back out to
//  a new file. Use h5dump and diff to compare the files. They should be the same
//  assuming the original file only had a DataModel in it.
// -----------------------------------------------------------------------------
void ReWriteModelTest()
{
 // std::cout << "ReWriteModelTest Running.....";

  std::string inFilename(MXAUnitTest::DataModelTest::BeforeH5File);
  std::string outFilename(MXAUnitTest::DataModelTest::AfterH5File);

  {
    IDataFile::Pointer dataFile = H5MXADataFile::OpenFile(inFilename, false);
    MXA_REQUIRE(dataFile.get() != 0x0);

    IDataModel::Pointer modelPtr  = dataFile->getDataModel();
    MXA_REQUIRE(modelPtr.get() != 0x0);

    IDataFile::Pointer outFile = H5MXADataFile::CreateFileWithModel(outFilename, modelPtr);
    MXA_REQUIRE(outFile.get() != 0x0);
  }

  // std::cout << "......Passed" << std::endl;
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void TestDimensionCount()
{
 // std::cout << "Testing Dimension Count Running...." ;
  IDataDimension::Pointer dim = MXADataDimension::New("Test", "Test", 0, 10, 0, 9, 1, 1);
  int32_t count = dim->calculateCount();
  MXA_REQUIRE(count == 10);

  dim->setStartValue(1);
  count = dim->calculateCount();
  MXA_REQUIRE(count == 9);

  dim->setStartValue(2);
  count = dim->calculateCount();
  MXA_REQUIRE(count == 8);

  dim->setStartValue(-1);
  count = dim->calculateCount();
  MXA_REQUIRE(count == 11);

  dim->setStartValue(-10);
  count = dim->calculateCount();
  MXA_REQUIRE(count == 20);

  dim->setIncrement(3);
  dim->setStartValue(0);
  dim->setEndValue(8);
  count = dim->calculateCount();
  MXA_REQUIRE(count == 3);

  dim->setEndValue(9);
  count = dim->calculateCount();
  MXA_REQUIRE(count == 4);

  dim->setIncrement(2);
  dim->setStartValue(0);
  dim->setEndValue(8);
  count = dim->calculateCount();
  MXA_REQUIRE(count == 5);

  dim->setIncrement(3);
  dim->setStartValue(1);
  dim->setEndValue(30);
  count = dim->calculateCount();
  MXA_REQUIRE(count == 10);

  dim->setEndValue(31);
  count = dim->calculateCount();
  MXA_REQUIRE(count == 11);
  // std::cout << "......Passed" << std::endl;
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void TestEndianSwap()
{
 // std::cout << "Testing Endian Swapping Running....";
  uint32_t value = 0xAABBCCDD;
  MXA::Endian::reverseBytes ( value );
  MXA_REQUIRE(0xDDCCBBAA == value);

  uint16_t value16 = 0xAABB;
  MXA::Endian::reverseBytes( value16);
  MXA_REQUIRE(0xBBAA == value16);
  // std::cout << "......Passed" << std::endl;
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void TestDataRecordRemoval()
{
 // std::cout << "TestDataRecordRemoval Running....";
  MXADataModel::Pointer modelPtr = createModel();
  MXADataModel* model = modelPtr.get();
  IDataRecord::Pointer nullRec;
  IDataRecord::Pointer r0;
  {
    IDataRecord::Container records = model->getDataRecords();
    r0 = records[0];
    MXA_REQUIRE( r0.use_count() == 3);
    model->removeDataRecord(r0);
    MXA_REQUIRE( r0.use_count() == 2);
  }
  MXA_REQUIRE( model->getDataRecords().size() == 1);
  MXA_REQUIRE( r0.use_count() == 1);
  r0.reset(nullRec.get());
  // std::cout << "......Passed" << std::endl;
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void TestDataModelOverWrite()
{
  //std::cout << "TestDataModelOverWrite Running...." ;
  std::string outFilename (MXAUnitTest::DataModelTest::OverwriteH5File);
  {

    MXADataModel::Pointer modelPtr = createModel();
    IDataFile::Pointer dataFile = H5MXADataFile::CreateFileWithModel(outFilename, modelPtr);
    // Make sure nothing went wrong in the file creation
    MXA_REQUIRE(dataFile.get() != 0x0);
    //Make sure the model pointers are the same. They SHOULD be.
    MXA_REQUIRE(dataFile->getDataModel().get() == modelPtr.get() );

    MXADataModel* model = modelPtr.get();
    // Update one of the dimensions
    IDataDimension::Pointer dim0 = model->getDataDimension(0);
    //IDataDimension::Pointer dim0 = model->addDataDimension("Volume Fraction", "Vol Frac",  15, 20, 50, 2, 1);
    dim0->setStartValue(0);
    dim0->setEndValue(9);
    dim0->setIncrement(1);
    int32_t count = dim0->calculateCount();
    model->setDataRoot("New/Data/Root/");
    MXA_REQUIRE(count == 10);
    int8_t  i8  = -8 * 2;
    uint8_t ui8 = 8 * 2;
    int16_t i16 = -16 * 2;
    uint16_t ui16 = 16 * 2;
    int32_t i32 = -32 * 2;
    uint32_t ui32 = 32 * 2;
    int64_t i64 = -64 * 2;
    uint64_t ui64 = 64 * 2;
    float f32 = 32.32f * 2;
    double f64 = 64.64 * 2;
    MakeScalarAttribute( i8, "Scalar Int 8", model);
    MakeScalarAttribute( ui8, "Scalar UInt8", model);
    MakeScalarAttribute( i16, "Scalar Int 16", model);
    MakeScalarAttribute( ui16, "Scalar UInt16", model);
    MakeScalarAttribute( i32, "Scalar Int 32", model);
    MakeScalarAttribute( ui32, "Scalar UInt32", model);
    MakeScalarAttribute( i64, "Scalar Int 64", model);
    MakeScalarAttribute( ui64, "Scalar UInt64", model);
    // Floating point Numbers
    MakeScalarAttribute( f32, "Scalar Float 32", model);
    MakeScalarAttribute( f64, "Scalar Float 64", model);
    int32_t err = dataFile->saveDataModel();
    MXA_REQUIRE(err >= 0); // This must pass
  }
  //Reread the model from the file and compare values
  {
    IDataFile::Pointer dataFile = H5MXADataFile::OpenFile(outFilename, true);
    MXA_REQUIRE(dataFile.get() != 0x0);
    IDataModel::Pointer modelPtr = dataFile->getDataModel();
    IDataDimension::Pointer dim0 = modelPtr->getDataDimension(0);
    MXA_REQUIRE ( dim0->getCount() == 10);
    MXA_REQUIRE ( dim0->getStartValue() == 0);
    MXA_REQUIRE ( dim0->getEndValue() == 9);
    MXA_REQUIRE ( dim0->getIncrement() == 1);
    MXA_REQUIRE ( modelPtr->getDataRoot().compare("New/Data/Root/") == 0);
  }

  // std::cout << "......Passed" << std::endl;
}

// -----------------------------------------------------------------------------
//  Shared Pointer Test
// -----------------------------------------------------------------------------
void SharedPointerTest()
{
 // std::cout << "SharedPointerTest Running...." ;

  MXADataModel::Pointer model = createModel();
  IDataDimension::Pointer dim = model->getDataDimension(0);

  IDataDimension::Pointer nDim = MXADataDimension::New("Name", "Name", 0, 10, 0, 9, 1, 1);
  IDataModel::Pointer nModel = MXADataModel::New(MXA::MXACurrentFileVersion, MXA::ModelType, "Data");
  nModel->addDataDimension(nDim);
  //nModel->printModel(std::cout, 2);
  // std::cout << "......Passed" << std::endl;

}

// -----------------------------------------------------------------------------
//  Test the copy constructors
// -----------------------------------------------------------------------------
void CopyConstructorTest()
{
  //std::cout << "CopyConstructorTest Running...." ;

  IDataDimension::Pointer nDim = MXADataDimension::New("Name", "Name", 0, 10, 0, 9, 1, 1);
  IDataDimension::Pointer copy = MXADataDimension::New(nDim);
  MXA_REQUIRE(nDim.get() != copy.get());

  IDataRecord::Pointer rec = MXADataRecord::New(0, "Name", "Name");
  IDataRecord::Pointer rCopy = MXADataRecord::New(rec);
  MXA_REQUIRE(rec.get() != rCopy.get());

  // std::cout << "......Passed" << std::endl;

}

// -----------------------------------------------------------------------------
//  Use MXA unit test framework
// -----------------------------------------------------------------------------
int main(int argc, char **argv) {
  int err = EXIT_SUCCESS;
  MXA_REGISTER_TEST( SharedPointerTest() );
  MXA_REGISTER_TEST( WriteTestModel() );
  MXA_REGISTER_TEST( ReWriteModelTest() );
  MXA_REGISTER_TEST( TestRetrieveDataRecords() );
  MXA_REGISTER_TEST( TestDataDimensionMethods() );
  MXA_REGISTER_TEST( TestRequiredMetaData() );
  MXA_REGISTER_TEST( TestDimensionCount() );
  MXA_REGISTER_TEST( TestEndianSwap() );
  MXA_REGISTER_TEST( TestDataRecordRemoval() );
  MXA_REGISTER_TEST( TestDataModelOverWrite() );
  MXA_REGISTER_TEST( SharedPointerTest() );
  MXA_REGISTER_TEST( CopyConstructorTest() );
  MXA_REGISTER_TEST( RemoveTestFiles() );

  PRINT_TEST_SUMMARY();
  return err;
}

max_stars_repo_name: mpartio/MXADataModel

max_issues_repo_name: mpartio/MXADataModel

max_forks_repo_name: mpartio/MXADataModel


text:
/*
* HOME       : ecourse.co.kr
* EMAIL      : smkang @ codenuri.co.kr
* COURSENAME : C++ Template Programming
* MODULE     : boost.cpp
* Copyright (C) 2017 CODENURI Inc. All rights reserved.
*/

#include <iostream>
#include <typeinfo>
#include <boost/type_index.hpp>
using namespace std;
using namespace boost::typeindex;

template<typename T> void foo(const T a)
{
//	cout << "T : " << typeid(T).name() << endl;
//	cout << "T : " << typeid(a).name() << endl;

	cout << "T : " << type_id_with_cvr<T>().pretty_name() << endl;
	cout << "a : " << type_id_with_cvr<decltype(a)>().pretty_name() << endl;
}

int main()
{
	foo(3);		// T : int		a : const int
	foo(3.3);
}


text:
/*==============================================================================
    Copyright (c) 2001-2010 Joel de Guzman
    Copyright (c) 2010 Thomas Heller

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#ifndef BOOST_PHOENIX_STATEMENT_SWITCH_HPP
#define BOOST_PHOENIX_STATEMENT_SWITCH_HPP

#include <boost/phoenix/core/limits.hpp>
#include <boost/fusion/iterator/advance.hpp>
#include <boost/phoenix/core/call.hpp>
#include <boost/phoenix/core/expression.hpp>
#include <boost/phoenix/core/meta_grammar.hpp>
#include <boost/phoenix/core/is_nullary.hpp>
#include <boost/phoenix/support/iterate.hpp>
#include <boost/proto/make_expr.hpp>
#include <boost/proto/fusion.hpp>

BOOST_PHOENIX_DEFINE_EXPRESSION(
    (boost)(phoenix)(switch_case)
  , (proto::terminal<proto::_>)
    (meta_grammar)
)

BOOST_PHOENIX_DEFINE_EXPRESSION(
    (boost)(phoenix)(switch_default_case)
  , (meta_grammar)
)

namespace boost { namespace phoenix
{
    namespace detail
    {
        struct switch_case_grammar;
        struct switch_case_with_default_grammar;
        struct switch_grammar
            : proto::or_<
                proto::when<
                    detail::switch_case_grammar
                  , mpl::false_()
                >
              , proto::when<
                    detail::switch_case_with_default_grammar
                  , mpl::true_()
                >
            >
        {};
    }

    namespace detail
    {
        struct switch_case_is_nullary
            : proto::or_<
                proto::when<
                    proto::comma<
                        switch_case_is_nullary
                      , proto::or_<phoenix::rule::switch_default_case, phoenix::rule::switch_case>
                    >
                  , mpl::and_<
                        switch_case_is_nullary(
                            proto::_child_c<0>
                          , proto::_state
                        )
                      , switch_case_is_nullary(
                            proto::_child_c<1>
                          , proto::_state
                        )
                    >()
                >
              , proto::when<
                    proto::or_<phoenix::rule::switch_default_case, phoenix::rule::switch_case>
                  , evaluator(proto::_child_c<0>, proto::_state)
                >
            >
        {};

        struct switch_case_grammar
            : proto::or_<
                proto::comma<switch_case_grammar, phoenix::rule::switch_case>
              , proto::when<phoenix::rule::switch_case, proto::_>
            >
        {};

        struct switch_case_with_default_grammar
            : proto::or_<
                proto::comma<switch_case_grammar, phoenix::rule::switch_default_case>
              , proto::when<phoenix::rule::switch_default_case, proto::_>
            >
        {};

        struct switch_size
            : proto::or_<
                proto::when<
                    proto::comma<switch_size, proto::_>
                  , mpl::next<switch_size(proto::_left)>()
                >
              , proto::when<proto::_, mpl::int_<1>()>
            >
        {};
    }
}}

BOOST_PHOENIX_DEFINE_EXPRESSION(
    (boost)(phoenix)(switch_)
  , (meta_grammar)           // Cond
    (detail::switch_grammar) // Cases
)

namespace boost { namespace phoenix {

    template <typename Dummy>
    struct is_nullary::when<rule::switch_, Dummy>
        : proto::and_<
            evaluator(proto::_child_c<0>, _context)
          , detail::switch_case_is_nullary(proto::_child_c<1>, _context)
        >
    {};

    struct switch_eval
    {
        typedef void result_type;

        template <typename Context>
        result_type
        operator()(Context &) const
        {
        }

        template <typename Cond, typename Cases, typename Context>
        result_type
        operator()(Cond const & cond, Cases const & cases, Context & ctx) const
        {
            this->evaluate(
                    ctx
                  , cond
                  , cases
                  , typename detail::switch_size::impl<Cases, int, int>::result_type()
                  , typename detail::switch_grammar::impl<Cases, int, int>::result_type()
                );
        }

        private:
            template <typename Context, typename Cond, typename Cases>
            result_type
            evaluate(
                Context & ctx
              , Cond const & cond
              , Cases const & cases
              , mpl::int_<1>
              , mpl::false_
            ) const
            {
                typedef
                    typename proto::result_of::value<
                        typename proto::result_of::child_c<
                            Cases
                          , 0
                        >::type
                    >::type
                    case_label;

                switch(boost::phoenix::eval(cond, ctx))
                {
                    case case_label::value:
                        boost::phoenix::eval(proto::child_c<1>(cases), ctx);
                }
            }

            template <typename Context, typename Cond, typename Cases>
            result_type
            evaluate(
                Context & ctx
              , Cond const & cond
              , Cases const & cases
              , mpl::int_<1>
              , mpl::true_
            ) const
            {
                switch(boost::phoenix::eval(cond, ctx))
                {
                    default:
                        boost::phoenix::eval(proto::child_c<0>(cases), ctx);
                }
            }

            // Bring in the evaluation functions
            #include <boost/phoenix/statement/detail/switch.hpp>
    };

    template <typename Dummy>
    struct default_actions::when<rule::switch_, Dummy>
        : call<switch_eval>
    {};

    template <int N, typename A>
    inline
    typename proto::result_of::make_expr<
        tag::switch_case
      , proto::basic_default_domain
      , mpl::int_<N>
      , A
    >::type const
    case_(A const & a)
    {
        return
            proto::make_expr<
                tag::switch_case
              , proto::basic_default_domain
            >(
                mpl::int_<N>()
              , a
            );
    }

    template <typename A>
    inline
    typename proto::result_of::make_expr<
        tag::switch_default_case
      , proto::basic_default_domain
      , A
    >::type const
    default_(A const& a)
    {
        return
            proto::make_expr<
                tag::switch_default_case
              , proto::basic_default_domain
            >(a);
    }

    template <typename Cond>
    struct switch_gen
    {
        switch_gen(Cond const& cond) : cond(cond) {}

        template <typename Cases>
        typename expression::switch_<
            Cond
          , Cases
        >::type
        operator[](Cases const& cases) const
        {
            return
                this->generate(
                    cases
                  , proto::matches<Cases, detail::switch_grammar>()
                );
        }

        private:
            Cond const& cond;

            template <typename Cases>
            typename expression::switch_<
                Cond
              , Cases
            >::type
            generate(Cases const & cases, mpl::true_) const
            {
                return expression::switch_<Cond, Cases>::make(cond, cases);
            }

            template <typename Cases>
            typename expression::switch_<
                Cond
              , Cases
            >::type
            generate(Cases const &, mpl::false_) const
            {
                BOOST_MPL_ASSERT_MSG(
                    false
                  , INVALID_SWITCH_CASE_STATEMENT
                  , (Cases)
                );
            }
    };

    template <typename Cond>
    inline
    switch_gen<Cond> const
    switch_(Cond const& cond)
    {
        return switch_gen<Cond>(cond);
    }

}}

#endif

max_stars_repo_name: brinkqiang/dmspirit


text:
// Boost.Geometry (aka GGL, Generic Geometry Library)

// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.

// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_BOX_BOX_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_BOX_BOX_HPP

#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_type.hpp>

namespace geofeatures_boost {} namespace boost = geofeatures_boost; namespace geofeatures_boost { namespace geometry
{

#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace intersection
{

template <std::size_t Dimension, std::size_t DimensionCount>
struct intersection_box_box
{
    template
    <
        typename Box1, typename Box2,
        typename RobustPolicy,
        typename BoxOut,
        typename Strategy
    >
    static inline bool apply(Box1 const& box1,
            Box2 const& box2,
            RobustPolicy const& robust_policy,
            BoxOut& box_out,
            Strategy const& strategy)
    {
        typedef typename coordinate_type<BoxOut>::type ct;

        ct min1 = get<min_corner, Dimension>(box1);
        ct min2 = get<min_corner, Dimension>(box2);
        ct max1 = get<max_corner, Dimension>(box1);
        ct max2 = get<max_corner, Dimension>(box2);

        if (max1 < min2 || max2 < min1)
        {
            return false;
        }
        // Set dimensions of output coordinate
        set<min_corner, Dimension>(box_out, min1 < min2 ? min2 : min1);
        set<max_corner, Dimension>(box_out, max1 > max2 ? max2 : max1);

        return intersection_box_box<Dimension + 1, DimensionCount>
               ::apply(box1, box2, robust_policy, box_out, strategy);
    }
};

template <std::size_t DimensionCount>
struct intersection_box_box<DimensionCount, DimensionCount>
{
    template
    <
        typename Box1, typename Box2,
        typename RobustPolicy,
        typename BoxOut,
        typename Strategy
    >
    static inline bool apply(Box1 const&, Box2 const&,
            RobustPolicy const&, BoxOut&, Strategy const&)
    {
        return true;
    }
};

}} // namespace detail::intersection
#endif // DOXYGEN_NO_DETAIL

}} // namespace geofeatures_boost::geometry

#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_BOX_BOX_HPP

max_stars_repo_name: tonystone/geofeatures

max_issues_repo_name: tonystone/geofeatures

max_forks_repo_name: tonystone/geofeatures


text:
#define BOOST_TEST_MODULE pcraster col2map
#include <boost/test/unit_test.hpp>
#include <cassert>
#include "dal_Client.h"
#include "dal_CSFRasterDriver.h"

static int const argc = 1;
static char const* argv[1] = { "/my/path/col2map_test" };

struct Fixture:
    private dal::Client
{

    Fixture()
        : dal::Client(argv[0], true)
    {
    }

    ~Fixture()=default;

};

BOOST_GLOBAL_FIXTURE(Fixture);

BOOST_AUTO_TEST_CASE(NaN)
{
  // http://pcrserver.geo.uu.nl/bugzilla/show_bug.cgi?id=247
  // nan.map is created in testrun.prolog.
  // Test whether a NaN on the input is converted to a missing value on the
  // output.
  // Status not yet correct: also test under DIFFERENT compilers if the file
  // reading already detets a string nan as a NAN, seems not standarized
//  #ifdef _MSC_VER
//    BOOST_WARN_MESSAGE( 0, "MSC does not read Nan (std? or gcc non-std)?");
//  #else
  dal::CSFRasterDriver driver;
  std::string filename("nan.map");
  dal::Raster* raster = dynamic_cast<dal::RasterDriver&>(driver).read(filename);

  assert(raster);
  assert(raster->typeId() == dal::TI_REAL4);

  BOOST_CHECK(!pcr::isMV(raster->cell<REAL4>(0)));
  BOOST_CHECK_EQUAL(raster->cell<REAL4>(0), 1.0F);
  //cuTodo(pcr::isMV(raster->cell<REAL4>(1)));
  BOOST_WARN(pcr::isMV(raster->cell<REAL4>(1)));
  BOOST_CHECK(!pcr::isMV(raster->cell<REAL4>(2)));
  BOOST_CHECK_EQUAL(raster->cell<REAL4>(2), 3.0F);
//  #endif
}

max_stars_repo_name: quanpands/wflow

max_issues_repo_name: quanpands/wflow

max_forks_repo_name: quanpands/wflow


text:
//==============================================================================
//         Copyright 2003 - 2012   LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2012   LRI    UMR 8623 CNRS/Univ Paris Sud XI
//         Copyright 2011 - 2012   MetaScale SAS
//
//          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_CORE_FUNCTIONS_CLASS_HPP_INCLUDED
#define NT2_CORE_FUNCTIONS_CLASS_HPP_INCLUDED

#include <nt2/sdk/meta/as.hpp>
#include <nt2/sdk/meta/container_traits.hpp>
#include <boost/dispatch/details/ignore_unused.hpp>

namespace nt2
{
  /*!
    @brief Retrieve the numerical class of an object

    For any given object, class returns a meta-descriptor that contains
    informations about the numerical type of values stored inside.

    @par Semantic

    For any given @c t of type @c T:

    @code
    auto x = class_(t);
    @endcode

    is equivalent to

    @code
    nt2::meta::as_<meta::value_type_<T>::type> x;
    @endcode

    @param t Object to extract the numeric class from

    @return A meta-object describing the valeu type of t
   **/
  template<class T> BOOST_FORCEINLINE
  meta::as_<typename meta::value_type_<T>::type>
  class_( T const& t )
  {
    boost::dispatch::ignore_unused(t);
    meta::as_< typename meta::value_type_<T>::type > that;
    return that;
  }
}

#endif


text:
// Comparison of bounded buffers based on different containers.

// Copyright (c) 2003-2008 Jan Gaspar
// Copyright 2013 Paul A. Bristow.  Added some Quickbook snippet markers.

// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#define BOOST_CB_DISABLE_DEBUG

#include <boost/circular_buffer.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/thread.hpp>
#include <boost/call_traits.hpp>
#include <boost/progress.hpp>
#include <boost/bind.hpp>
#include <deque>
#include <list>
#include <string>
#include <iostream>

const unsigned long QUEUE_SIZE     = 1000L;
const unsigned long TOTAL_ELEMENTS = QUEUE_SIZE * 1000L;

template <class T>
class bounded_buffer {
public:

    typedef boost::circular_buffer<T> container_type;
    typedef typename container_type::size_type size_type;
    typedef typename container_type::value_type value_type;
    typedef typename boost::call_traits<value_type>::param_type param_type;

    explicit bounded_buffer(size_type capacity) : m_unread(0), m_container(capacity) {}

    void push_front(param_type item) {
        boost::mutex::scoped_lock lock(m_mutex);
        m_not_full.wait(lock, boost::bind(&bounded_buffer<value_type>::is_not_full, this));
        m_container.push_front(item);
        ++m_unread;
        lock.unlock();
        m_not_empty.notify_one();
    }

    void pop_back(value_type* pItem) {
        boost::mutex::scoped_lock lock(m_mutex);
        m_not_empty.wait(lock, boost::bind(&bounded_buffer<value_type>::is_not_empty, this));
        *pItem = m_container[--m_unread];
        lock.unlock();
        m_not_full.notify_one();
    }

private:
    bounded_buffer(const bounded_buffer&);              // Disabled copy constructor
    bounded_buffer& operator = (const bounded_buffer&); // Disabled assign operator

    bool is_not_empty() const { return m_unread > 0; }
    bool is_not_full() const { return m_unread < m_container.capacity(); }

    size_type m_unread;
    container_type m_container;
    boost::mutex m_mutex;
    boost::condition m_not_empty;
    boost::condition m_not_full;
};

template <class T>
class bounded_buffer_space_optimized {
public:

    typedef boost::circular_buffer_space_optimized<T> container_type;
    typedef typename container_type::size_type size_type;
    typedef typename container_type::value_type value_type;
    typedef typename boost::call_traits<value_type>::param_type param_type;

    explicit bounded_buffer_space_optimized(size_type capacity) : m_container(capacity) {}

    void push_front(param_type item) {
        boost::mutex::scoped_lock lock(m_mutex);
        m_not_full.wait(lock, boost::bind(&bounded_buffer_space_optimized<value_type>::is_not_full, this));
        m_container.push_front(item);
        lock.unlock();
        m_not_empty.notify_one();
    }

    void pop_back(value_type* pItem) {
        boost::mutex::scoped_lock lock(m_mutex);
        m_not_empty.wait(lock, boost::bind(&bounded_buffer_space_optimized<value_type>::is_not_empty, this));
        *pItem = m_container.back();
        m_container.pop_back();
        lock.unlock();
        m_not_full.notify_one();
    }

private:

    bounded_buffer_space_optimized(const bounded_buffer_space_optimized&);              // Disabled copy constructor
    bounded_buffer_space_optimized& operator = (const bounded_buffer_space_optimized&); // Disabled assign operator

    bool is_not_empty() const { return m_container.size() > 0; }
    bool is_not_full() const { return m_container.size() < m_container.capacity(); }

    container_type m_container;
    boost::mutex m_mutex;
    boost::condition m_not_empty;
    boost::condition m_not_full;
};

template <class T>
class bounded_buffer_deque_based {
public:

    typedef std::deque<T> container_type;
    typedef typename container_type::size_type size_type;
    typedef typename container_type::value_type value_type;
    typedef typename boost::call_traits<value_type>::param_type param_type;

    explicit bounded_buffer_deque_based(size_type capacity) : m_capacity(capacity) {}

    void push_front(param_type item) {
        boost::mutex::scoped_lock lock(m_mutex);
        m_not_full.wait(lock, boost::bind(&bounded_buffer_deque_based<value_type>::is_not_full, this));
        m_container.push_front(item);
        lock.unlock();
        m_not_empty.notify_one();
    }

    void pop_back(value_type* pItem) {
        boost::mutex::scoped_lock lock(m_mutex);
        m_not_empty.wait(lock, boost::bind(&bounded_buffer_deque_based<value_type>::is_not_empty, this));
        *pItem = m_container.back();
        m_container.pop_back();
        lock.unlock();
        m_not_full.notify_one();
    }

private:

    bounded_buffer_deque_based(const bounded_buffer_deque_based&);              // Disabled copy constructor
    bounded_buffer_deque_based& operator = (const bounded_buffer_deque_based&); // Disabled assign operator

    bool is_not_empty() const { return m_container.size() > 0; }
    bool is_not_full() const { return m_container.size() < m_capacity; }

    const size_type m_capacity;
    container_type m_container;
    boost::mutex m_mutex;
    boost::condition m_not_empty;
    boost::condition m_not_full;
};

template <class T>
class bounded_buffer_list_based {
public:

    typedef std::list<T> container_type;
    typedef typename container_type::size_type size_type;
    typedef typename container_type::value_type value_type;
    typedef typename boost::call_traits<value_type>::param_type param_type;

    explicit bounded_buffer_list_based(size_type capacity) : m_capacity(capacity) {}

    void push_front(param_type item) {
        boost::mutex::scoped_lock lock(m_mutex);
        m_not_full.wait(lock, boost::bind(&bounded_buffer_list_based<value_type>::is_not_full, this));
        m_container.push_front(item);
        lock.unlock();
        m_not_empty.notify_one();
    }

    void pop_back(value_type* pItem) {
        boost::mutex::scoped_lock lock(m_mutex);
        m_not_empty.wait(lock, boost::bind(&bounded_buffer_list_based<value_type>::is_not_empty, this));
        *pItem = m_container.back();
        m_container.pop_back();
        lock.unlock();
        m_not_full.notify_one();
    }

private:

    bounded_buffer_list_based(const bounded_buffer_list_based&);              // Disabled copy constructor
    bounded_buffer_list_based& operator = (const bounded_buffer_list_based&); // Disabled assign operator

    bool is_not_empty() const { return m_container.size() > 0; }
    bool is_not_full() const { return m_container.size() < m_capacity; }

    const size_type m_capacity;
    container_type m_container;
    boost::mutex m_mutex;
    boost::condition m_not_empty;
    boost::condition m_not_full;
};

template<class Buffer>
class Consumer {

    typedef typename Buffer::value_type value_type;
    Buffer* m_container;
    value_type m_item;

public:
    Consumer(Buffer* buffer) : m_container(buffer) {}

    void operator()() {
        for (unsigned long i = 0L; i < TOTAL_ELEMENTS; ++i) {
            m_container->pop_back(&m_item);
        }
    }
};

template<class Buffer>
class Producer {

    typedef typename Buffer::value_type value_type;
    Buffer* m_container;

public:
    Producer(Buffer* buffer) : m_container(buffer) {}

    void operator()() {
        for (unsigned long i = 0L; i < TOTAL_ELEMENTS; ++i) {
            m_container->push_front(value_type());
        }
    }
};

template<class Buffer>
void fifo_test(Buffer* buffer) {

    // Start of measurement
    boost::progress_timer progress;

    // Initialize the buffer with some values before launching producer and consumer threads.
    for (unsigned long i = QUEUE_SIZE / 2L; i > 0; --i) {
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
        buffer->push_front(Buffer::value_type());
#else
        buffer->push_front(BOOST_DEDUCED_TYPENAME Buffer::value_type());
#endif
    }

    Consumer<Buffer> consumer(buffer);
    Producer<Buffer> producer(buffer);

    // Start the threads.
    boost::thread consume(consumer);
    boost::thread produce(producer);

    // Wait for completion.
    consume.join();
    produce.join();

    // End of measurement
}

int main(int /*argc*/, char* /*argv*/[]) {

    bounded_buffer<int> bb_int(QUEUE_SIZE);
    std::cout << "bounded_buffer<int> ";
    fifo_test(&bb_int);

    bounded_buffer_space_optimized<int> bb_space_optimized_int(QUEUE_SIZE);
    std::cout << "bounded_buffer_space_optimized<int> ";
    fifo_test(&bb_space_optimized_int);

    bounded_buffer_deque_based<int> bb_deque_based_int(QUEUE_SIZE);
    std::cout << "bounded_buffer_deque_based<int> ";
    fifo_test(&bb_deque_based_int);

    bounded_buffer_list_based<int> bb_list_based_int(QUEUE_SIZE);
    std::cout << "bounded_buffer_list_based<int> ";
    fifo_test(&bb_list_based_int);

    bounded_buffer<std::string> bb_string(QUEUE_SIZE);
    std::cout << "bounded_buffer<std::string> ";
    fifo_test(&bb_string);

    bounded_buffer_space_optimized<std::string> bb_space_optimized_string(QUEUE_SIZE);
    std::cout << "bounded_buffer_space_optimized<std::string> ";
    fifo_test(&bb_space_optimized_string);

    bounded_buffer_deque_based<std::string> bb_deque_based_string(QUEUE_SIZE);
    std::cout << "bounded_buffer_deque_based<std::string> ";
    fifo_test(&bb_deque_based_string);

    bounded_buffer_list_based<std::string> bb_list_based_string(QUEUE_SIZE);
    std::cout << "bounded_buffer_list_based<std::string> ";
    fifo_test(&bb_list_based_string);

    return 0;
}
/*

//[bounded_buffer_comparison_output

  Description: Autorun "J:\Cpp\Misc\Debug\bounded_buffer_comparison.exe"
  bounded_buffer<int> 5.15 s

  bounded_buffer_space_optimized<int> 5.71 s

  bounded_buffer_deque_based<int> 15.57 s

  bounded_buffer_list_based<int> 17.33 s

  bounded_buffer<std::string> 24.49 s

  bounded_buffer_space_optimized<std::string> 28.33 s

  bounded_buffer_deque_based<std::string> 29.45 s

  bounded_buffer_list_based<std::string> 31.29 s

  //] //[bounded_buffer_comparison_output]

*/

max_stars_repo_name: Abce/boost


text:
/*
Copyright (c) 2017 InversePalindrome
InPal - ModifyFunctionsWindow.cpp
InversePalindrome.com
*/

#include "ModifyFunctionsWindow.hpp"

#include <wx/scrolwin.h>

#include <boost/algorithm/string.hpp>

ModifyFunctionsWindow::ModifyFunctionsWindow(wxWindow* parent, MathDataDefault* mathData) :
    wxMiniFrame(parent, wxID_ANY, "Modify Functions", wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX),
    mathData(mathData),
    mainPanel(new wxPanel(this)),
    secondaryPanel(new wxPanel(this)),
    mainSizer(new wxBoxSizer(wxVERTICAL)),
    functionName(new wxStaticText(secondaryPanel, wxID_ANY, "")),
    parametersEntry(new wxTextCtrl(secondaryPanel, wxID_ANY)),
    bodyEntry(new wxTextCtrl(secondaryPanel, wxID_ANY, "", wxDefaultPosition, wxSize(250u, 300u), wxTE_MULTILINE))
{
    SetBackgroundColour(wxColor(128u, 128u, 128u));

    secondaryPanel->Hide();
    mainPanel->Show();

    auto* scrollPanel = new wxScrolledWindow(mainPanel, wxID_ANY, wxDefaultPosition, wxSize(200u, 300u));

    auto* nameText = new wxStaticText(scrollPanel, wxID_ANY, "Name");

    nameText->SetFont(wxFont(12u, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD));

    auto* topSizer = new wxBoxSizer(wxVERTICAL);

    topSizer->Add(nameText, 0u, wxALIGN_CENTER | wxALL, 5u);

    for (const auto& function : mathData->functions)
    {
        auto* functionButton = new wxButton(scrollPanel, wxID_ANY, function.first);

        topSizer->Add(functionButton, 0u, wxALIGN_CENTER | wxALL, 5u);

        functionButton->Bind(wxEVT_LEFT_DOWN, &ModifyFunctionsWindow::OnSelectFunction, this);
    }

    scrollPanel->SetSizer(topSizer);

    scrollPanel->FitInside();
    scrollPanel->SetScrollRate(10u, 10u);

    topSizer->Fit(this);
    topSizer->SetSizeHints(this);

    mainSizer->Add(mainPanel, 0u, wxEXPAND | wxALL);

    mainSizer->Fit(this);
    mainSizer->SetSizeHints(this);

    SetSizer(mainSizer);
}

void ModifyFunctionsWindow::OnSelectFunction(wxMouseEvent & event)
{
    this->mainPanel->Hide();
    this->secondaryPanel->Show();

    auto* selectedButton = dynamic_cast<wxButton*>(event.GetEventObject());

    auto* nameText = new wxStaticText(secondaryPanel, wxID_ANY, "Name");

    this->functionName->SetLabel(selectedButton->GetLabel().ToStdString());

    auto* parametersText = new wxStaticText(secondaryPanel, wxID_ANY, "Parameters");

    this->parametersEntry->SetValue(this->mathData->functions.at(selectedButton->GetLabel().ToStdString()).first);

    auto* bodyText = new wxStaticText(secondaryPanel, wxID_ANY, "Body");

    this->bodyEntry->SetValue(this->mathData->functions.at(selectedButton->GetLabel().ToStdString()).second);

    auto* modifyButton = new wxButton(secondaryPanel, wxID_ANY, "Modify");
    auto* deleteButton = new wxButton(secondaryPanel, wxID_DELETE);

    auto* buttonSizer = new wxBoxSizer(wxHORIZONTAL);

    buttonSizer->Add(modifyButton, 0u, wxALIGN_CENTER | wxALL, 5u);
    buttonSizer->Add(deleteButton, 0u, wxALIGN_CENTER | wxALL, 5u);

    auto* bottomSizer = new wxBoxSizer(wxVERTICAL);

    bottomSizer->Add(nameText, 0u, wxALL, 3u);
    bottomSizer->Add(functionName, 0u, wxEXPAND | wxALL, 5u);
    bottomSizer->Add(parametersText, 0u, wxALL, 5u);
    bottomSizer->Add(parametersEntry, 0u, wxEXPAND | wxALL, 5u);
    bottomSizer->Add(bodyText, 0u, wxALL, 5u);
    bottomSizer->Add(bodyEntry, 0u, wxALL, 5u);
    bottomSizer->Add(buttonSizer, 0u, wxALIGN_CENTER | wxALL, 5u);

    this->secondaryPanel->SetSizer(bottomSizer);

    auto& font = wxFont(8u, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);

    nameText->SetFont(font);
    parametersText->SetFont(font);
    bodyText->SetFont(font);

    this->mainSizer->Add(secondaryPanel);

    this->secondaryPanel->FitInside();

    this->mainSizer->Fit(this);
    this->mainSizer->SetSizeHints(this);

    modifyButton->Bind(wxEVT_LEFT_DOWN, &ModifyFunctionsWindow::OnModifyFunction, this);
    deleteButton->Bind(wxEVT_LEFT_DOWN, &ModifyFunctionsWindow::OnDeleteFunction, this);
}

void ModifyFunctionsWindow::OnModifyFunction(wxMouseEvent & event)
{
    std::vector<std::string> parameterTokens;

    boost::split(parameterTokens, this->parametersEntry->GetValue().ToStdString(), boost::is_any_of(", "));

    this->mathData->mathSolver.addCompositorFunction(this->functionName->GetLabel().ToStdString(), parameterTokens, this->bodyEntry->GetValue().ToStdString());

    this->mathData->functions.at(this->functionName->GetLabel().ToStdString()) =
        std::make_pair(this->parametersEntry->GetValue().ToStdString(), this->bodyEntry->GetValue().ToStdString());

    this->Close();
}

void ModifyFunctionsWindow::OnDeleteFunction(wxMouseEvent & event)
{
    this->mathData->mathSolver.removeFunction(this->functionName->GetLabel().ToStdString());
    this->mathData->functions.erase(this->functionName->GetLabel().ToStdString());

    this->Close();
}

max_stars_repo_name: saktheeswaranswan/InPalgrapher

max_issues_repo_name: InversePalindrome/Prime-Numbers

max_forks_repo_name: InversePalindrome/Prime-Numbers


text: #include <boost/fusion/algorithm/iteration/for_each.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
/*
// Copyright (c) 2000-2009, Texas Engineering Experiment Station (TEES), a
// component of the Texas A&M University System.

// All rights reserved.

// The information and source code contained herein is the exclusive
// property of TEES and may not be disclosed, examined or reproduced
// in whole or in part without explicit written authorization from TEES.
*/

#ifndef STAPL_DOMAINS_DOMAINSET1D_HPP
#define STAPL_DOMAINS_DOMAINSET1D_HPP

#include <stapl/containers/type_traits/container_traits.hpp>
#include <stapl/containers/type_traits/index_bounds.hpp>
#include <stapl/domains/interval.hpp>
#include <stapl/domains/indexed.hpp>
#include <stapl/views/type_traits/is_domain_sparse.hpp>
#include <stapl/runtime/p_object.hpp>
#include <stapl/runtime/promise.hpp>
#include <stapl/runtime/pointer.hpp>
#include <stapl/utility/down_cast.hpp>
#include <cstddef>
#include <functional>
#include <utility>
#include <boost/mpl/bool.hpp>

namespace stapl {

//////////////////////////////////////////////////////////////////////
/// @brief Defines a one dimensional distributed domain for indexes
///        that are not necessarily consecutive.
///
/// @tparam Distribution Type of distribution used to support the
///                      methods.
//////////////////////////////////////////////////////////////////////
template<typename Distribution>
class domainset1D
{
public:
  typedef default_traversal<1>::type                        traversal_type;
  typedef typename container_traits<Distribution>::gid_type index_type;
  typedef index_type                                        gid_type;
  typedef std::size_t                                       size_type;
  typedef domset1D<gid_type>                                sparse_domain;

private:
  p_object_pointer_wrapper<const Distribution> m_dist;
  sparse_domain                                m_sparse_domain;

  //////////////////////////////////////////////////////////////////////
  /// @todo Propagate constness and then add const to reference return type.
  //////////////////////////////////////////////////////////////////////
  Distribution& distribution(void) const
  { return *const_cast<Distribution*>(m_dist.get()); }

public:
  domainset1D(void)
    : m_dist(0),
      m_sparse_domain()
  { }

  explicit domainset1D(Distribution const& dist)
    : m_dist(&dist),
      m_sparse_domain()
  { }

  explicit domainset1D(size_type size, bool is_cont_dom = true)
    : m_dist(0),
      m_sparse_domain(size, is_cont_dom)
  { }

  //////////////////////////////////////////////////////////////////////
  /// @todo hgview fails with the explicit keyword.
  //////////////////////////////////////////////////////////////////////
  /*explicit*/ domainset1D(sparse_domain const& sparse_dom)
    : m_dist(0),
      m_sparse_domain(sparse_dom)
  { }

  //////////////////////////////////////////////////////////////////////
  /// @todo This allows graph_metadata to work. Notice that it discards the
  ///       distribution.
  //////////////////////////////////////////////////////////////////////
  domainset1D(sparse_domain const& sparse_dom, Distribution*)
    : m_dist(0),
      m_sparse_domain(sparse_dom)
  { }

  //////////////////////////////////////////////////////////////////////
  /// @brief Constructor used in view coarsening to construct subdomains.
  //////////////////////////////////////////////////////////////////////
  domainset1D(index_type const& first, index_type const& last,
              bool is_cont_dom = false)
    : m_dist(0),
      m_sparse_domain(first, last, is_cont_dom)
  { }

  //////////////////////////////////////////////////////////////////////
  /// @brief Constructs a new domain by restricting the given domain (@p dom)
  ///        to be between first and last (included).
  //////////////////////////////////////////////////////////////////////
  domainset1D(index_type const& first,
              index_type const& last,
              domainset1D const& dom)
    : m_dist(0),
      m_sparse_domain(first, last, dom.m_sparse_domain)
  { }

  //////////////////////////////////////////////////////////////////////
  /// @brief Constructs a new domain by converting it from an existing
  ///        @ref indexed_domain.
  //////////////////////////////////////////////////////////////////////
  domainset1D(indexed_domain<gid_type> const& dom)
    : m_dist(0),
      m_sparse_domain(dom)
  { }

  index_type first(void) const
  {
    if (!m_dist)
      return m_sparse_domain.first();
    promise<gid_type> p;
    auto f = p.get_future();
    distribution().container_manager().find_first(std::move(p));
    return f.get(); // sync_rmi() equivalent
  }

  index_type last(void) const
  {
    if (!m_dist)
      return m_sparse_domain.last();
    promise<gid_type> p;
    auto f = p.get_future();
    distribution().container_manager().find_last(std::move(p));
    return f.get(); // sync_rmi() equivalent
  }

  index_type open_last(void) const
  {
    return advance(last(), 1);
  }

  template<typename Distance>
  index_type advance(index_type const& g, Distance n) const
  {
    if (!m_dist)
      return m_sparse_domain.advance(g, n);

    if (distribution().container_manager().contains(g))
    {
      gid_type new_gid = distribution().container_manager().advance(g, n);
      return new_gid;
    }
    else
    {
      typedef promise<gid_type> promise_type;

      promise_type p;
      auto f = p.get_future();

      distribution().directory().invoke_where(
        std::bind(
          [](p_object& d, index_type const& gid, Distance n, promise_type& p)
          { down_cast<Distribution&>(d).defer_advance(gid, n, std::move(p)); },
          std::placeholders::_1, std::placeholders::_2, n, std::move(p)), g);

      return f.get(); // sync_rmi() equivalent
    }
  }

  size_type size(void) const
  {
    if (!m_dist)
      return m_sparse_domain.size();
    if (distribution().get_num_locations()==1)
      return local_size();

    return sync_reduce_rmi(std::plus<size_type>(),
                           distribution().get_rmi_handle(),
                           &Distribution::local_size);
  }

  size_type dimensions(void) const
  {
    return size();
  }

  size_type local_size(void) const
  {
    return distribution().container_manager().num_elements();
  }

  bool contains(index_type const& g) const
  {
    if (!m_dist)
      return m_sparse_domain.contains(g);

    typedef promise<bool> promise_type;

    promise_type p;
    auto f = p.get_future();

    distribution().directory().invoke_where(
      std::bind(
        [](p_object& d, index_type const& gid, promise_type& p)
        { down_cast<Distribution&>(d).defer_contains(gid, std::move(p)); },
        std::placeholders::_1, std::placeholders::_2, std::move(p)), g);

    return f.get(); // sync_rmi() equivalent
  }

  bool empty(void) const
  {
    return (size() == 0);
  }

  size_type distance(index_type const& a, index_type const& b) const
  {
    if (!m_dist)
      return m_sparse_domain.distance(a, b);
    auto dist = std::distance(distribution().find(a), distribution().find(b));
    return (dist < 0) ? -dist : dist;
  }

  //////////////////////////////////////////////////////////////////////
  /// @brief Adds the given @p gid to the domain.
  //////////////////////////////////////////////////////////////////////
  domainset1D& operator+=(index_type const& gid)
  {
    if (!m_dist)
      m_sparse_domain += gid;
    return *this;
  }

  //////////////////////////////////////////////////////////////////////
  /// @brief Removes the given @p gid from the domain.
  //////////////////////////////////////////////////////////////////////
  domainset1D& operator-=(index_type const& gid)
  {
    if (!m_dist)
      m_sparse_domain -= gid;
    return *this;
  }

  bool is_same_container_domain(void) const
  {
    return (m_dist != 0) || m_sparse_domain.is_same_container_domain();
  }

  //////////////////////////////////////////////////////////////////////
  /// @copydoc stapl::indexed_domain::is_contiguous
  //////////////////////////////////////////////////////////////////////
  bool is_contiguous(void) const
  {
    if (!m_dist)
      return m_sparse_domain.is_contiguous();
    return false;
  }

  //////////////////////////////////////////////////////////////////////
  /// @copydoc stapl::indexed_domain::operator&(domainset1D const&)
  //////////////////////////////////////////////////////////////////////
  domainset1D operator&(domainset1D const& other) const
  {
    if (empty() || other.empty())
      return domainset1D();

    if (!m_dist && !other.m_dist)
      return domainset1D(m_sparse_domain&(other.m_sparse_domain));

    if (m_dist && !other.m_dist)
      return other;

    return *this;
  }

  sparse_domain const& get_sparse_domain(void) const
  {
    return m_sparse_domain;
  }

  void define_type(typer& t)
  {
    t.member(m_dist);
    t.member(m_sparse_domain);
  }

  Distribution const* get_distribution(void) const
  { return m_dist; }

  template<typename T>
  friend std::ostream& operator<<(std::ostream&, domainset1D<T> const&);
};

template<typename T>
std::ostream& operator<<(std::ostream& os, domainset1D<T> const& d)
{
  if (d.empty())
  {
    os << "empty";
    return os;
  }

  if (!d.m_dist)
    os << "sparse_domain: ";
  else
    os << "distributed_domain: ";

  std::size_t domain_size = d.size();
  std::size_t elt = d.first();
  os << "{";
  for (typename domainset1D<T>::size_type i=0; i<domain_size-1; ++i)
  {
    os << elt << ", ";
    elt = d.advance(elt, 1);
  }
  return os << elt << "}";
}

//////////////////////////////////////////////////////////////////////
/// @brief Specialization of type checker to determine if domainset1D
///        represents a sparse domain.
//////////////////////////////////////////////////////////////////////
template<typename Distribution>
struct is_domain_sparse<domainset1D<Distribution>>
  : boost::mpl::true_
{ };

} // namespace stapl

#endif // STAPL_DOMAINS_DOMAINSET1D_HPP


text:
// tests.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

IOptionsWithString* g_Options = NULL;

#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>

//int _tmain(int argc, _TCHAR* argv[])
//{
//
//	return 0;
//}

max_stars_repo_name: Adept-Space/pn

max_issues_repo_name: Adept-Space/pn

max_forks_repo_name: Adept-Space/pn


text:
//  Copyright Neil Groves 2009. Use, modification and
//  distribution is subject to the Boost Software License, Version
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//
//
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_ALGORITHM_REPLACE_COPY_HPP_INCLUDED
#define BOOST_RANGE_ALGORITHM_REPLACE_COPY_HPP_INCLUDED

#include <boost/concept_check.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/concepts.hpp>
#include <algorithm>

namespace boost
{
    namespace range
    {

/// \brief template function replace_copy
///
/// range-based version of the replace_copy std algorithm
///
/// \pre ForwardRange is a model of the ForwardRangeConcept
template< class ForwardRange, class OutputIterator, class Value >
inline OutputIterator
replace_copy(ForwardRange& rng, OutputIterator out_it, const Value& what,
        const Value& with_what)
{
    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
    return std::replace_copy(boost::begin(rng), boost::end(rng), out_it,
        what, with_what);
}

    } // namespace range
    using range::replace_copy;
} // namespace boost

#endif // include guard

max_stars_repo_name: jonstewart/boost-svn

max_issues_repo_name: jonstewart/boost-svn

max_forks_repo_name: jonstewart/boost-svn


text:
/*

Copyright (c) 2008-2012, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author 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 OWNER 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.

*/

#ifndef TORRENT_CREATE_TORRENT_HPP_INCLUDED
#define TORRENT_CREATE_TORRENT_HPP_INCLUDED

#include "libtorrent/bencode.hpp"
#include "libtorrent/peer_id.hpp"
#include "libtorrent/file_storage.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/storage.hpp"
#include "libtorrent/hasher.hpp"
#include "libtorrent/utf8.hpp"
#include "libtorrent/allocator.hpp"
#include "libtorrent/file.hpp" // for combine_path etc.

#include <vector>
#include <string>
#include <utility>

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/scoped_ptr.hpp>
#include <boost/config.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

namespace libtorrent
{
	class torrent_info;

	struct TORRENT_EXPORT create_torrent
	{
		enum flags_t
		{
			optimize = 1
			, merkle = 2
			, modification_time = 4
			, symlinks = 8
			, calculate_file_hashes = 16
		};

		create_torrent(file_storage& fs, int piece_size = 0
			, int pad_file_limit = -1, int flags = optimize, int alignment = 0x4000);
		create_torrent(torrent_info const& ti);
		~create_torrent();
		entry generate() const;

		file_storage const& files() const { return m_files; }

		void set_comment(char const* str);
		void set_creator(char const* str);
		void set_hash(int index, sha1_hash const& h);
		void set_file_hash(int index, sha1_hash const& h);
		void add_url_seed(std::string const& url);
		void add_http_seed(std::string const& url);
		void add_node(std::pair<std::string, int> const& node);
		void add_tracker(std::string const& url, int tier = 0);
		void set_root_cert(std::string const& pem);
		void set_priv(bool p) { m_private = p; }

		int num_pieces() const { return m_files.num_pieces(); }
		int piece_length() const { return m_files.piece_length(); }
		int piece_size(int i) const { return m_files.piece_size(i); }
		bool priv() const { return m_private; }

		bool should_add_file_hashes() const { return m_calculate_file_hashes; }
		std::vector<sha1_hash> const& merkle_tree() const { return m_merkle_tree; }

	private:

		file_storage& m_files;
		// if m_info_dict is initialized, it is
		// used instead of m_files to generate
		// the info dictionary
		entry m_info_dict;

		// the urls to the trackers
		typedef std::pair<std::string, int> announce_entry;
		std::vector<announce_entry> m_urls;

		std::vector<std::string> m_url_seeds;
		std::vector<std::string> m_http_seeds;

		std::vector<sha1_hash> m_piece_hash;

		std::vector<sha1_hash> m_filehashes;

		// if we're generating a merkle torrent, this is the
		// merkle tree we got. This should be saved in fast-resume
		// in order to start seeding the torrent
		mutable std::vector<sha1_hash> m_merkle_tree;

		// dht nodes to add to the routing table/bootstrap from
		typedef std::vector<std::pair<std::string, int> > nodes_t;
		nodes_t m_nodes;

		// the hash that identifies this torrent
		// is mutable because it's calculated
		// lazily
		mutable sha1_hash m_info_hash;

		// if a creation date is found in the torrent file
		// this will be set to that, otherwise it'll be
		// 1970, Jan 1
		time_t m_creation_date;

		// if a comment is found in the torrent file
		// this will be set to that comment
		std::string m_comment;

		// an optional string naming the software used
		// to create the torrent file
		std::string m_created_by;

		// this is the root cert for SSL torrents
		std::string m_root_cert;

		// this is used when creating a torrent. If there's
		// only one file there are cases where it's impossible
		// to know if it should be written as a multifile torrent
		// or not. e.g. test/test  there's one file and one directory
		// and they have the same name.
		bool m_multifile:1;

		// this is true if the torrent is private. i.e., is should not
		// be announced on the dht
		bool m_private:1;

		// if set to one, a merkle torrent will be generated
		bool m_merkle_torrent:1;

		// if set, include the 'mtime' modification time in the
		// torrent file
		bool m_include_mtime:1;

		// if set, symbolic links are declared as such in
		// the torrent file. The full data of the pointed-to
		// file is still included
		bool m_include_symlinks:1;

		// this is only used by set_piece_hashes(). It will
		// calculate sha1 hashes for each file and add it
		// to the file list
		bool m_calculate_file_hashes:1;
	};

	namespace detail
	{
		inline bool default_pred(std::string const&) { return true; }

		inline bool ignore_subdir(std::string const& leaf)
		{ return leaf == ".." || leaf == "."; }

		inline void nop(int i) {}

		int get_file_attributes(std::string const& p);
		std::string get_symlink_path(std::string const& p);

		// internal
		TORRENT_EXPORT void add_files_impl(file_storage& fs, std::string const& p
			, std::string const& l, boost::function<bool(std::string)> pred
			, boost::uint32_t flags);
	}

	template <class Pred>
	void add_files(file_storage& fs, std::string const& file, Pred p, boost::uint32_t flags = 0)
	{
		detail::add_files_impl(fs, parent_path(complete(file)), filename(file), p, flags);
	}

	inline void add_files(file_storage& fs, std::string const& file, boost::uint32_t flags = 0)
	{
		detail::add_files_impl(fs, parent_path(complete(file)), filename(file)
			, detail::default_pred, flags);
	}

	TORRENT_EXPORT void set_piece_hashes(create_torrent& t, std::string const& p
		, boost::function<void(int)> f, error_code& ec);

#ifndef BOOST_NO_EXCEPTIONS
	template <class Fun>
	void set_piece_hashes(create_torrent& t, std::string const& p, Fun f)
	{
		error_code ec;
		set_piece_hashes(t, p, f, ec);
		if (ec) throw libtorrent_exception(ec);
	}

	inline void set_piece_hashes(create_torrent& t, std::string const& p)
	{
		error_code ec;
		set_piece_hashes(t, p, detail::nop, ec);
		if (ec) throw libtorrent_exception(ec);
	}
#endif

	inline void set_piece_hashes(create_torrent& t, std::string const& p, error_code& ec)
	{
		set_piece_hashes(t, p, detail::nop, ec);
	}

#if TORRENT_USE_WSTRING
	// wstring versions

	template <class Pred>
	void add_files(file_storage& fs, std::wstring const& wfile, Pred p, boost::uint32_t flags = 0)
	{
		std::string utf8;
		wchar_utf8(wfile, utf8);
		detail::add_files_impl(fs, parent_path(complete(utf8))
			, filename(utf8), p, flags);
	}

	inline void add_files(file_storage& fs, std::wstring const& wfile, boost::uint32_t flags = 0)
	{
		std::string utf8;
		wchar_utf8(wfile, utf8);
		detail::add_files_impl(fs, parent_path(complete(utf8))
			, filename(utf8), detail::default_pred, flags);
	}

	void TORRENT_EXPORT set_piece_hashes(create_torrent& t, std::wstring const& p
		, boost::function<void(int)> const& f, error_code& ec);

#ifndef BOOST_NO_EXCEPTIONS
	template <class Fun>
	void set_piece_hashes(create_torrent& t, std::wstring const& p, Fun f)
	{
		error_code ec;
		set_piece_hashes(t, p, f, ec);
		if (ec) throw libtorrent_exception(ec);
	}

	inline void set_piece_hashes(create_torrent& t, std::wstring const& p)
	{
		error_code ec;
		set_piece_hashes(t, p, detail::nop, ec);
		if (ec) throw libtorrent_exception(ec);
	}
#endif

	inline void set_piece_hashes(create_torrent& t, std::wstring const& p, error_code& ec)
	{
		set_piece_hashes(t, p, detail::nop, ec);
	}

#endif // TORRENT_USE_WPATH

}

#endif

max_stars_repo_name: majestrate/twister-core

max_issues_repo_name: majestrate/twister-core

max_forks_repo_name: twisterarmy/twister-core