<commit_before>/*
 * Copyright (c) 2001,2002 Steven M. Cherry. All rights reserved.
 *
 * This file is a part of slib - a c++ utility library
 *
 * The slib project, including all files needed to compile
 * it, is free software; you can redistribute it and/or use it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  See file COPYING for details.
 */

/* ******************************************************* */
/* Simple program to test the functions in twine.cpp       */
/* ******************************************************* */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "twine.h"
using namespace SLib;

#include "catch.hpp"

const size_t MAX_INPUT_SIZE = 1024000000;

TEST_CASE( "Twine - short string", "[twine]" )
{
    twine t( "I am a short string" );

    REQUIRE_FALSE( t.empty() );
    REQUIRE( t.size() == 19 );
    REQUIRE( t.capacity() >= 19 );
}

// according to twine.h, a "Short string" is <=32 characters, including the final '\0'
TEST_CASE( "Twine - assignment from const char", "[twine]" )
{
    SECTION( "Short string") {
        SECTION( "Direct assignment" ){
            twine t = "I am a short string";
            REQUIRE_FALSE( t.empty() );
            REQUIRE( t.size() == 19 );
            REQUIRE( t.capacity() >= 19 );
        }

        SECTION( "Assignment after construction" ){
            twine t; t = "I am a short string";
            REQUIRE_FALSE( t.empty() );
            REQUIRE( t.size() == 19 );
            REQUIRE( t.capacity() >= 19 );
        }
    }

    SECTION( "Long string") {
        SECTION( "Direct assignment of a long string" ){
            twine t = "I am a longer string that will not fit in optimized storage.";
            REQUIRE_FALSE( t.empty() );
            REQUIRE( t.size() == 60 );
            REQUIRE( t.capacity() >= 60 );
        }

        SECTION( "Assignment after construction of a long string" ){
            twine t; t = "I am a longer string that will not fit in optimized storage.";
            REQUIRE_FALSE( t.empty() );
            REQUIRE( t.size() == 60 );
            REQUIRE( t.capacity() >= 60 );
        }
    }

    SECTION("Extremely long string") {
        SECTION("MAX_INPUT_SIZE") {
            SECTION( "Direct assignment of a long string" ){
                char* monster = (char*)malloc((MAX_INPUT_SIZE + 1) * sizeof(*monster));
                for(int i = 0; i < MAX_INPUT_SIZE; ++i)
                {
                    monster[i] = (i % 94) + 32; // fill it with printable characters! Why? Who cares!
                }
                monster[MAX_INPUT_SIZE] = 0;
                twine* t = NULL;
                // This is a valid size, because the exception is
                // thrown when number of non-zero chars in string
                // is greater than MAX_INPUT_SIZE

                REQUIRE_NOTHROW([&](){twine t_real = monster; t = &t_real;}());
                REQUIRE_FALSE(t->empty());
                REQUIRE(t->size() == MAX_INPUT_SIZE);
                REQUIRE(t->capacity() >= MAX_INPUT_SIZE);
                INFO("t.capacity() is " << t->capacity());
                INFO("MAX_INPUT_SIZE is " << MAX_INPUT_SIZE);

            }

            SECTION( "Assignment after construction of a long string" ){
                char* monster = (char*)malloc((MAX_INPUT_SIZE + 1) * sizeof(*monster));
                for(int i = 0; i < MAX_INPUT_SIZE; ++i)
                {
                    monster[i] = (i % 94) + 32; // fill it with printable characters! Why? Who cares!
                }
                monster[MAX_INPUT_SIZE] = 0;

                twine t;
                REQUIRE_NOTHROW(t = monster);

                REQUIRE_FALSE(t.empty());
                REQUIRE(t.size() == MAX_INPUT_SIZE);
                REQUIRE(t.capacity() >= MAX_INPUT_SIZE);
                INFO("t.capacity() is " << t.capacity());
                INFO("MAX_INPUT_SIZE is " << MAX_INPUT_SIZE);
            }
        }

        SECTION("MAX_INPUT_SIZE + 1") {
            SECTION( "Direct assignment of a long string" ){
                char* monster = (char*)malloc((MAX_INPUT_SIZE + 2) * sizeof(*monster));
                for(int i = 0; i <= MAX_INPUT_SIZE; ++i)
                {
                    monster[i] = (i % 94) + 32; // fill it with printable characters! Why? Who cares!
                }
                monster[MAX_INPUT_SIZE + 1] = 0;
                REQUIRE_THROWS([&](){twine t = monster;}());
            }

            SECTION( "Assignment after construction of a long string" ){
                char* monster = (char*)malloc((MAX_INPUT_SIZE + 2) * sizeof(*monster));
                for(int i = 0; i <= MAX_INPUT_SIZE; ++i)
                {
                    monster[i] = (i % 94) + 32; // fill it with printable characters! Why? Who cares!
                }
                monster[MAX_INPUT_SIZE + 1] = 0;

                twine t;
                REQUIRE_THROWS(t = monster);
            }
        }
    }

}

TEST_CASE( "Twine - Copy Constructor" )
{
    SECTION( "Copy Empty" ) {
        SECTION( "Calling constructor by name" ){
            twine orig;
            twine t = twine(orig);
            REQUIRE(t.empty());
            REQUIRE(t.size() == 0);
            REQUIRE(t.capacity() == TWINE_SMALL_STRING - 1);

            REQUIRE(t.compare(orig) == 0);
            REQUIRE(&t != &orig);
        }

        SECTION("Implicitly calling constructor"){
            twine orig;
            twine t = orig;
            REQUIRE(t.empty());
            REQUIRE(t.size() == 0);
            REQUIRE(t.capacity() == TWINE_SMALL_STRING - 1);

            REQUIRE(t.compare(orig) == 0);
            REQUIRE(&t != &orig);
        }

        SECTION("Calling constructor after initial creation"){
            twine orig;
            twine t; t = orig;
            REQUIRE(t.empty());
            REQUIRE(t.size() == 0);
            REQUIRE(t.capacity() == TWINE_SMALL_STRING - 1);

            REQUIRE(t.compare(orig) == 0);
            REQUIRE(&t != &orig);
        }
    }

    SECTION( "Copy Short Twine" ) {
        SECTION( "Calling constructor by name" ){
            twine orig = "I am a short string";
            twine t = twine(orig);
            REQUIRE_FALSE(t.empty());
            REQUIRE(t.size() == 19);
            REQUIRE(t.capacity() == TWINE_SMALL_STRING - 1);

            REQUIRE(t.compare(orig) == 0);
            REQUIRE(&t != &orig);
        }

        SECTION("Implicitly calling constructor"){
            twine orig = "I am a short string";
            twine t = orig;
            REQUIRE_FALSE(t.empty());
            REQUIRE(t.size() == 19);
            REQUIRE(t.capacity() == TWINE_SMALL_STRING - 1);

            REQUIRE(t.compare(orig) == 0);
            REQUIRE(&t != &orig);
        }

        SECTION("Calling constructor after initial creation"){
            twine orig = "I am a short string";
            twine t; t = orig;
            REQUIRE_FALSE(t.empty());
            REQUIRE(t.size() == 19);
            REQUIRE(t.capacity() == TWINE_SMALL_STRING - 1);

            REQUIRE(t.compare(orig) == 0);
            REQUIRE(&t != &orig);
        }
    }

}
<commit_msg>Fixed pointer mistake.<commit_after>/*
 * Copyright (c) 2001,2002 Steven M. Cherry. All rights reserved.
 *
 * This file is a part of slib - a c++ utility library
 *
 * The slib project, including all files needed to compile
 * it, is free software; you can redistribute it and/or use it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  See file COPYING for details.
 */

/* ******************************************************* */
/* Simple program to test the functions in twine.cpp       */
/* ******************************************************* */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "twine.h"
using namespace SLib;

#include "catch.hpp"

const size_t MAX_INPUT_SIZE = 1024000000;

TEST_CASE( "Twine - short string", "[twine]" )
{
    twine t( "I am a short string" );

    REQUIRE_FALSE( t.empty() );
    REQUIRE( t.size() == 19 );
    REQUIRE( t.capacity() >= 19 );
}

// according to twine.h, a "Short string" is <=32 characters, including the final '\0'
TEST_CASE( "Twine - assignment from const char", "[twine]" )
{
    SECTION( "Short string") {
        SECTION( "Direct assignment" ){
            twine t = "I am a short string";
            REQUIRE_FALSE( t.empty() );
            REQUIRE( t.size() == 19 );
            REQUIRE( t.capacity() >= 19 );
        }

        SECTION( "Assignment after construction" ){
            twine t; t = "I am a short string";
            REQUIRE_FALSE( t.empty() );
            REQUIRE( t.size() == 19 );
            REQUIRE( t.capacity() >= 19 );
        }
    }

    SECTION( "Long string") {
        SECTION( "Direct assignment of a long string" ){
            twine t = "I am a longer string that will not fit in optimized storage.";
            REQUIRE_FALSE( t.empty() );
            REQUIRE( t.size() == 60 );
            REQUIRE( t.capacity() >= 60 );
        }

        SECTION( "Assignment after construction of a long string" ){
            twine t; t = "I am a longer string that will not fit in optimized storage.";
            REQUIRE_FALSE( t.empty() );
            REQUIRE( t.size() == 60 );
            REQUIRE( t.capacity() >= 60 );
        }
    }

    SECTION("Extremely long string") {
        SECTION("MAX_INPUT_SIZE") {

            // This is a valid size, because the exception is
            // thrown when number of non-zero chars in string
            // is greater than MAX_INPUT_SIZE
            char* monster = (char*)malloc((MAX_INPUT_SIZE + 1) * sizeof(*monster));
            for(int i = 0; i < MAX_INPUT_SIZE; ++i)
            {
                monster[i] = (i % 94) + 32; // fill it with printable characters! Why? Who cares!
            }
            monster[MAX_INPUT_SIZE] = 0;

            SECTION( "Direct assignment of a long string" ){
                twine* t = NULL;

                REQUIRE_NOTHROW([&](){t = new twine(monster);}());
                REQUIRE_FALSE(t->empty());
                REQUIRE(t->size() == MAX_INPUT_SIZE);
                REQUIRE(t->capacity() >= MAX_INPUT_SIZE);
                INFO("t.capacity() is " << t->capacity());
                INFO("MAX_INPUT_SIZE is " << MAX_INPUT_SIZE);

                if(t != NULL)
                    delete t;
            }

            SECTION( "Assignment after construction of a long string" ){
                twine t;
                REQUIRE_NOTHROW(t = monster);

                REQUIRE_FALSE(t.empty());
                REQUIRE(t.size() == MAX_INPUT_SIZE);
                REQUIRE(t.capacity() >= MAX_INPUT_SIZE);
                INFO("t.capacity() is " << t.capacity());
                INFO("MAX_INPUT_SIZE is " << MAX_INPUT_SIZE);
            }
        }

        SECTION("MAX_INPUT_SIZE + 1") {
            // This is an invalid size, because the nonzero portion of the string is of length greater
            // than MAX_INPUT_SIZE
            char* monster = (char*)malloc((MAX_INPUT_SIZE + 2) * sizeof(*monster));
            for(int i = 0; i <= MAX_INPUT_SIZE; ++i)
            {
                monster[i] = (i % 94) + 32; // fill it with printable characters! Why? Who cares!
            }
            monster[MAX_INPUT_SIZE + 1] = 0;

            SECTION( "Direct assignment of a long string" ){
                REQUIRE_THROWS([&](){twine t = monster;}());
            }

            SECTION( "Assignment after construction of a long string" ){
                twine t;
                REQUIRE_THROWS(t = monster);
            }
        }
    }

}

TEST_CASE( "Twine - Copy Constructor" )
{
    SECTION( "Copy Empty" ) {
        SECTION( "Calling constructor by name" ){
            twine orig;
            twine t = twine(orig);
            REQUIRE(t.empty());
            REQUIRE(t.size() == 0);
            REQUIRE(t.capacity() == TWINE_SMALL_STRING - 1);

            REQUIRE(t.compare(orig) == 0);
            REQUIRE(&t != &orig);
        }

        SECTION("Implicitly calling constructor"){
            twine orig;
            twine t = orig;
            REQUIRE(t.empty());
            REQUIRE(t.size() == 0);
            REQUIRE(t.capacity() == TWINE_SMALL_STRING - 1);

            REQUIRE(t.compare(orig) == 0);
            REQUIRE(&t != &orig);
        }

        SECTION("Calling constructor after initial creation"){
            twine orig;
            twine t; t = orig;
            REQUIRE(t.empty());
            REQUIRE(t.size() == 0);
            REQUIRE(t.capacity() == TWINE_SMALL_STRING - 1);

            REQUIRE(t.compare(orig) == 0);
            REQUIRE(&t != &orig);
        }
    }

    SECTION( "Copy Short Twine" ) {
        SECTION( "Calling constructor by name" ){
            twine orig = "I am a short string";
            twine t = twine(orig);
            REQUIRE_FALSE(t.empty());
            REQUIRE(t.size() == 19);
            REQUIRE(t.capacity() == TWINE_SMALL_STRING - 1);

            REQUIRE(t.compare(orig) == 0);
            REQUIRE(&t != &orig);
        }

        SECTION("Implicitly calling constructor"){
            twine orig = "I am a short string";
            twine t = orig;
            REQUIRE_FALSE(t.empty());
            REQUIRE(t.size() == 19);
            REQUIRE(t.capacity() == TWINE_SMALL_STRING - 1);

            REQUIRE(t.compare(orig) == 0);
            REQUIRE(&t != &orig);
        }

        SECTION("Calling constructor after initial creation"){
            twine orig = "I am a short string";
            twine t; t = orig;
            REQUIRE_FALSE(t.empty());
            REQUIRE(t.size() == 19);
            REQUIRE(t.capacity() == TWINE_SMALL_STRING - 1);

            REQUIRE(t.compare(orig) == 0);
            REQUIRE(&t != &orig);
        }
    }

    SECTION("Copy Long Twine") {
        twine orig = "";
    }
}
<|endoftext|>


<commit_before><commit_msg>improve bullet hitting detection<commit_after><|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

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

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

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// library configuration
#include "libmesh/libmesh_config.h"

// C++ includes
#include <algorithm> // for std::min
#include <map>       // for std::multimap
#include <sstream>   // for std::ostringstream

// Local includes
#include "libmesh/boundary_info.h"
#include "libmesh/elem.h"
#include "libmesh/mesh_base.h"
#include "libmesh/parallel.h"
#include "libmesh/partitioner.h"
#include "libmesh/point_locator_base.h"
#include "libmesh/threads.h"

namespace libMesh
{

// ------------------------------------------------------------
// MeshBase class member functions
MeshBase::MeshBase (const Parallel::Communicator &comm_in,
                    unsigned char d) :
  ParallelObject (comm_in),
  boundary_info  (new BoundaryInfo(*this)),
  _n_parts       (1),
  _is_prepared   (false),
  _point_locator (NULL),
  _partitioner   (NULL),
#ifdef LIBMESH_ENABLE_UNIQUE_ID
  _next_unique_id(DofObject::invalid_unique_id),
#endif
  _skip_partitioning(false),
  _skip_renumber_nodes_and_elements(false)
{
  _elem_dims.insert(d);
  libmesh_assert_less_equal (LIBMESH_DIM, 3);
  libmesh_assert_greater_equal (LIBMESH_DIM, d);
  libmesh_assert (libMesh::initialized());
}

#ifndef LIBMESH_DISABLE_COMMWORLD
MeshBase::MeshBase (unsigned char d) :
  ParallelObject (CommWorld),
  boundary_info  (new BoundaryInfo(*this)),
  _n_parts       (1),
  _is_prepared   (false),
  _point_locator (NULL),
  _partitioner   (NULL),
#ifdef LIBMESH_ENABLE_UNIQUE_ID
  _next_unique_id(DofObject::invalid_unique_id),
#endif
  _skip_partitioning(false),
  _skip_renumber_nodes_and_elements(false)
{
  _elem_dims.insert(d);
  libmesh_assert_less_equal (LIBMESH_DIM, 3);
  libmesh_assert_greater_equal (LIBMESH_DIM, d);
  libmesh_assert (libMesh::initialized());
}
#endif // !LIBMESH_DISABLE_COMMWORLD

MeshBase::MeshBase (const MeshBase& other_mesh) :
  ParallelObject (other_mesh),
  boundary_info  (new BoundaryInfo(*this)),
  _n_parts       (other_mesh._n_parts),
  _is_prepared   (other_mesh._is_prepared),
  _point_locator (NULL),
  _partitioner   (NULL),
#ifdef LIBMESH_ENABLE_UNIQUE_ID
  _next_unique_id(other_mesh._next_unique_id),
#endif
  _skip_partitioning(other_mesh._skip_partitioning),
  _skip_renumber_nodes_and_elements(false),
  _elem_dims(other_mesh._elem_dims)
{
  if(other_mesh._partitioner.get())
    {
      _partitioner = other_mesh._partitioner->clone();
    }
}

MeshBase::~MeshBase()
{
  this->clear();

  libmesh_exceptionless_assert (!libMesh::closed());
}

unsigned int MeshBase::mesh_dimension() const
{
  libmesh_assert(!_elem_dims.empty());
  return cast_int<unsigned int>(*_elem_dims.rbegin());
}

void MeshBase::prepare_for_use (const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
{
  parallel_object_only();

  // A distributed mesh may have processors with no elements (or
  // processors with no elements of higher dimension, if we ever
  // support mixed-dimension meshes), but we want consistent
  // mesh_dimension anyways.
  libmesh_assert(this->comm().verify(this->is_serial()));

  if (!this->is_serial())
    {
      unsigned char dim = this->mesh_dimension();
      this->comm().max(dim);
      this->set_mesh_dimension(dim);
    }

  // Renumber the nodes and elements so that they in contiguous
  // blocks.  By default, _skip_renumber_nodes_and_elements is false.
  //
  // We may currently change that by passing
  // skip_renumber_nodes_and_elements==true to this function, but we
  // should use the allow_renumbering() accessor instead.
  //
  // Instances where you if prepare_for_use() should not renumber the nodes
  // and elements include reading in e.g. an xda/r or gmv file. In
  // this case, the ordering of the nodes may depend on an accompanying
  // solution, and the node ordering cannot be changed.

  if (skip_renumber_nodes_and_elements)
    {
      libmesh_deprecated();
      this->allow_renumbering(false);
    }

  // Mesh modification operations might not leave us with consistent
  // id counts, but our partitioner might need that consistency.
  if(!_skip_renumber_nodes_and_elements)
    this->renumber_nodes_and_elements();
  else
    this->update_parallel_id_counts();

  // Let all the elements find their neighbors
  if(!skip_find_neighbors)
    this->find_neighbors();

  // Partition the mesh.
  this->partition();

  // If we're using ParallelMesh, we'll want it parallelized.
  this->delete_remote_elements();

#ifdef LIBMESH_ENABLE_UNIQUE_ID
  // Assign DOF object unique ids
  this->assign_unique_ids();
#endif

  if(!_skip_renumber_nodes_and_elements)
    this->renumber_nodes_and_elements();

  // Search the mesh for all the dimensions of the elements
  // and cache them.
  this->cache_elem_dims();

  // Reset our PointLocator.  This needs to happen any time the elements
  // in the underlying elements in the mesh have changed, so we do it here.
  this->clear_point_locator();

  // The mesh is now prepared for use.
  _is_prepared = true;
}

void MeshBase::clear ()
{
  // Reset the number of partitions
  _n_parts = 1;

  // Reset the _is_prepared flag
  _is_prepared = false;

  // Clear boundary information
  this->get_boundary_info().clear();

  // Clear element dimensions
  _elem_dims.clear();

  // Clear our point locator.
  this->clear_point_locator();
}

void MeshBase::subdomain_ids (std::set<subdomain_id_type> &ids) const
{
  // This requires an inspection on every processor
  parallel_object_only();

  ids.clear();

  const_element_iterator el  = this->active_local_elements_begin();
  const_element_iterator end = this->active_local_elements_end();

  for (; el!=end; ++el)
    ids.insert((*el)->subdomain_id());

  // Some subdomains may only live on other processors
  this->comm().set_union(ids);
}

subdomain_id_type MeshBase::n_subdomains() const
{
  // This requires an inspection on every processor
  parallel_object_only();

  std::set<subdomain_id_type> ids;

  this->subdomain_ids (ids);

  return cast_int<subdomain_id_type>(ids.size());
}

dof_id_type MeshBase::n_nodes_on_proc (const processor_id_type proc_id) const
{
  // We're either counting a processor's nodes or unpartitioned
  // nodes
  libmesh_assert (proc_id < this->n_processors() ||
                  proc_id == DofObject::invalid_processor_id);

  return static_cast<dof_id_type>(std::distance (this->pid_nodes_begin(proc_id),
                                                 this->pid_nodes_end  (proc_id)));
}

dof_id_type MeshBase::n_elem_on_proc (const processor_id_type proc_id) const
{
  // We're either counting a processor's elements or unpartitioned
  // elements
  libmesh_assert (proc_id < this->n_processors() ||
                  proc_id == DofObject::invalid_processor_id);

  return static_cast<dof_id_type>(std::distance (this->pid_elements_begin(proc_id),
                                                 this->pid_elements_end  (proc_id)));
}

dof_id_type MeshBase::n_active_elem_on_proc (const processor_id_type proc_id) const
{
  libmesh_assert_less (proc_id, this->n_processors());
  return static_cast<dof_id_type>(std::distance (this->active_pid_elements_begin(proc_id),
                                                 this->active_pid_elements_end  (proc_id)));
}

dof_id_type MeshBase::n_sub_elem () const
{
  dof_id_type ne=0;

  const_element_iterator       el  = this->elements_begin();
  const const_element_iterator end = this->elements_end();

  for (; el!=end; ++el)
    ne += (*el)->n_sub_elem();

  return ne;
}

dof_id_type MeshBase::n_active_sub_elem () const
{
  dof_id_type ne=0;

  const_element_iterator       el  = this->active_elements_begin();
  const const_element_iterator end = this->active_elements_end();

  for (; el!=end; ++el)
    ne += (*el)->n_sub_elem();

  return ne;
}

std::string MeshBase::get_info() const
{
  std::ostringstream oss;

  oss << " Mesh Information:"                                  << '\n'
      << "  mesh_dimension()="    << this->mesh_dimension()    << '\n'
      << "  spatial_dimension()=" << this->spatial_dimension() << '\n'
      << "  n_nodes()="           << this->n_nodes()           << '\n'
      << "    n_local_nodes()="   << this->n_local_nodes()     << '\n'
      << "  n_elem()="            << this->n_elem()            << '\n'
      << "    n_local_elem()="    << this->n_local_elem()      << '\n'
#ifdef LIBMESH_ENABLE_AMR
      << "    n_active_elem()="   << this->n_active_elem()     << '\n'
#endif
      << "  n_subdomains()="      << static_cast<std::size_t>(this->n_subdomains()) << '\n'
      << "  n_partitions()="      << static_cast<std::size_t>(this->n_partitions()) << '\n'
      << "  n_processors()="      << static_cast<std::size_t>(this->n_processors()) << '\n'
      << "  n_threads()="         << static_cast<std::size_t>(libMesh::n_threads()) << '\n'
      << "  processor_id()="      << static_cast<std::size_t>(this->processor_id()) << '\n';

  return oss.str();
}

void MeshBase::print_info(std::ostream& os) const
{
  os << this->get_info()
     << std::endl;
}

std::ostream& operator << (std::ostream& os, const MeshBase& m)
{
  m.print_info(os);
  return os;
}

void MeshBase::partition (const unsigned int n_parts)
{
  // NULL partitioner means don't partition
  // Non-serial meshes aren't ready for partitioning yet.
  if(!skip_partitioning() &&
     partitioner().get() &&
     this->is_serial())
    {
      partitioner()->partition (*this, n_parts);
    }
  else
    {
      // Make sure locally cached partition count
      this->recalculate_n_partitions();

      // Make sure any other locally cached data is correct
      this->update_post_partitioning();
    }
}

unsigned int MeshBase::recalculate_n_partitions()
{
  // This requires an inspection on every processor
  parallel_object_only();

  const_element_iterator el  = this->active_local_elements_begin();
  const_element_iterator end = this->active_local_elements_end();

  unsigned int max_proc_id=0;

  for (; el!=end; ++el)
    max_proc_id = std::max(max_proc_id, static_cast<unsigned int>((*el)->processor_id()));

  // The number of partitions is one more than the max processor ID.
  _n_parts = max_proc_id+1;

  this->comm().max(_n_parts);

  return _n_parts;
}

const PointLocatorBase& MeshBase::point_locator () const
{
  libmesh_deprecated();

  if (_point_locator.get() == NULL)
    {
      // PointLocator construction may not be safe within threads
      libmesh_assert(!Threads::in_threads);

      _point_locator.reset (PointLocatorBase::build(TREE_ELEMENTS, *this).release());
    }

  return *_point_locator;
}

AutoPtr<PointLocatorBase> MeshBase::sub_point_locator () const
{
  if (_point_locator.get() == NULL)
    {
      // PointLocator construction may not be safe within threads
      libmesh_assert(!Threads::in_threads);

      _point_locator.reset (PointLocatorBase::build(TREE_ELEMENTS, *this).release());
    }

  return PointLocatorBase::build(TREE_ELEMENTS, *this, _point_locator.get());
}

void MeshBase::clear_point_locator ()
{
  _point_locator.reset(NULL);
}

std::string& MeshBase::subdomain_name(subdomain_id_type id)
{
  return _block_id_to_name[id];
}

const std::string& MeshBase::subdomain_name(subdomain_id_type id) const
{
  // An empty string to return when no matching subdomain name is found
  static const std::string empty;

  std::map<subdomain_id_type, std::string>::const_iterator iter = _block_id_to_name.find(id);
  if (iter == _block_id_to_name.end())
    return empty;
  else
    return iter->second;
}

subdomain_id_type MeshBase::get_id_by_name(const std::string& name) const
{
  // Linear search over the map values.
  std::map<subdomain_id_type, std::string>::const_iterator
    iter = _block_id_to_name.begin(),
    end_iter = _block_id_to_name.end();

  for ( ; iter != end_iter; ++iter)
    if (iter->second == name)
      return iter->first;

  // If we made it here without returning, we don't have a subdomain
  // with the requested name, so return Elem::invalid_subdomain_id.
  return Elem::invalid_subdomain_id;
}

void MeshBase::cache_elem_dims()
{
  // This requires an inspection on every processor
  parallel_object_only();

  const_element_iterator el  = this->active_local_elements_begin();
  const_element_iterator end = this->active_local_elements_end();

  for (; el!=end; ++el)
    _elem_dims.insert((*el)->dim());

  // Some different dimension elements may only live on other processors
  this->comm().set_union(_elem_dims);
}

} // namespace libMesh
<commit_msg>Always repartition mesh nodes<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

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

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

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// library configuration
#include "libmesh/libmesh_config.h"

// C++ includes
#include <algorithm> // for std::min
#include <map>       // for std::multimap
#include <sstream>   // for std::ostringstream

// Local includes
#include "libmesh/boundary_info.h"
#include "libmesh/elem.h"
#include "libmesh/mesh_base.h"
#include "libmesh/parallel.h"
#include "libmesh/partitioner.h"
#include "libmesh/point_locator_base.h"
#include "libmesh/threads.h"

namespace libMesh
{

// ------------------------------------------------------------
// MeshBase class member functions
MeshBase::MeshBase (const Parallel::Communicator &comm_in,
                    unsigned char d) :
  ParallelObject (comm_in),
  boundary_info  (new BoundaryInfo(*this)),
  _n_parts       (1),
  _is_prepared   (false),
  _point_locator (NULL),
  _partitioner   (NULL),
#ifdef LIBMESH_ENABLE_UNIQUE_ID
  _next_unique_id(DofObject::invalid_unique_id),
#endif
  _skip_partitioning(false),
  _skip_renumber_nodes_and_elements(false)
{
  _elem_dims.insert(d);
  libmesh_assert_less_equal (LIBMESH_DIM, 3);
  libmesh_assert_greater_equal (LIBMESH_DIM, d);
  libmesh_assert (libMesh::initialized());
}

#ifndef LIBMESH_DISABLE_COMMWORLD
MeshBase::MeshBase (unsigned char d) :
  ParallelObject (CommWorld),
  boundary_info  (new BoundaryInfo(*this)),
  _n_parts       (1),
  _is_prepared   (false),
  _point_locator (NULL),
  _partitioner   (NULL),
#ifdef LIBMESH_ENABLE_UNIQUE_ID
  _next_unique_id(DofObject::invalid_unique_id),
#endif
  _skip_partitioning(false),
  _skip_renumber_nodes_and_elements(false)
{
  _elem_dims.insert(d);
  libmesh_assert_less_equal (LIBMESH_DIM, 3);
  libmesh_assert_greater_equal (LIBMESH_DIM, d);
  libmesh_assert (libMesh::initialized());
}
#endif // !LIBMESH_DISABLE_COMMWORLD

MeshBase::MeshBase (const MeshBase& other_mesh) :
  ParallelObject (other_mesh),
  boundary_info  (new BoundaryInfo(*this)),
  _n_parts       (other_mesh._n_parts),
  _is_prepared   (other_mesh._is_prepared),
  _point_locator (NULL),
  _partitioner   (NULL),
#ifdef LIBMESH_ENABLE_UNIQUE_ID
  _next_unique_id(other_mesh._next_unique_id),
#endif
  _skip_partitioning(other_mesh._skip_partitioning),
  _skip_renumber_nodes_and_elements(false),
  _elem_dims(other_mesh._elem_dims)
{
  if(other_mesh._partitioner.get())
    {
      _partitioner = other_mesh._partitioner->clone();
    }
}

MeshBase::~MeshBase()
{
  this->clear();

  libmesh_exceptionless_assert (!libMesh::closed());
}

unsigned int MeshBase::mesh_dimension() const
{
  libmesh_assert(!_elem_dims.empty());
  return cast_int<unsigned int>(*_elem_dims.rbegin());
}

void MeshBase::prepare_for_use (const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
{
  parallel_object_only();

  // A distributed mesh may have processors with no elements (or
  // processors with no elements of higher dimension, if we ever
  // support mixed-dimension meshes), but we want consistent
  // mesh_dimension anyways.
  libmesh_assert(this->comm().verify(this->is_serial()));

  if (!this->is_serial())
    {
      unsigned char dim = this->mesh_dimension();
      this->comm().max(dim);
      this->set_mesh_dimension(dim);
    }

  // Renumber the nodes and elements so that they in contiguous
  // blocks.  By default, _skip_renumber_nodes_and_elements is false.
  //
  // We may currently change that by passing
  // skip_renumber_nodes_and_elements==true to this function, but we
  // should use the allow_renumbering() accessor instead.
  //
  // Instances where you if prepare_for_use() should not renumber the nodes
  // and elements include reading in e.g. an xda/r or gmv file. In
  // this case, the ordering of the nodes may depend on an accompanying
  // solution, and the node ordering cannot be changed.

  if (skip_renumber_nodes_and_elements)
    {
      libmesh_deprecated();
      this->allow_renumbering(false);
    }

  // Mesh modification operations might not leave us with consistent
  // id counts, but our partitioner might need that consistency.
  if(!_skip_renumber_nodes_and_elements)
    this->renumber_nodes_and_elements();
  else
    this->update_parallel_id_counts();

  // Let all the elements find their neighbors
  if(!skip_find_neighbors)
    this->find_neighbors();

  // Partition the mesh.
  this->partition();

  // If we're using ParallelMesh, we'll want it parallelized.
  this->delete_remote_elements();

#ifdef LIBMESH_ENABLE_UNIQUE_ID
  // Assign DOF object unique ids
  this->assign_unique_ids();
#endif

  if(!_skip_renumber_nodes_and_elements)
    this->renumber_nodes_and_elements();

  // Search the mesh for all the dimensions of the elements
  // and cache them.
  this->cache_elem_dims();

  // Reset our PointLocator.  This needs to happen any time the elements
  // in the underlying elements in the mesh have changed, so we do it here.
  this->clear_point_locator();

  // The mesh is now prepared for use.
  _is_prepared = true;
}

void MeshBase::clear ()
{
  // Reset the number of partitions
  _n_parts = 1;

  // Reset the _is_prepared flag
  _is_prepared = false;

  // Clear boundary information
  this->get_boundary_info().clear();

  // Clear element dimensions
  _elem_dims.clear();

  // Clear our point locator.
  this->clear_point_locator();
}

void MeshBase::subdomain_ids (std::set<subdomain_id_type> &ids) const
{
  // This requires an inspection on every processor
  parallel_object_only();

  ids.clear();

  const_element_iterator el  = this->active_local_elements_begin();
  const_element_iterator end = this->active_local_elements_end();

  for (; el!=end; ++el)
    ids.insert((*el)->subdomain_id());

  // Some subdomains may only live on other processors
  this->comm().set_union(ids);
}

subdomain_id_type MeshBase::n_subdomains() const
{
  // This requires an inspection on every processor
  parallel_object_only();

  std::set<subdomain_id_type> ids;

  this->subdomain_ids (ids);

  return cast_int<subdomain_id_type>(ids.size());
}

dof_id_type MeshBase::n_nodes_on_proc (const processor_id_type proc_id) const
{
  // We're either counting a processor's nodes or unpartitioned
  // nodes
  libmesh_assert (proc_id < this->n_processors() ||
                  proc_id == DofObject::invalid_processor_id);

  return static_cast<dof_id_type>(std::distance (this->pid_nodes_begin(proc_id),
                                                 this->pid_nodes_end  (proc_id)));
}

dof_id_type MeshBase::n_elem_on_proc (const processor_id_type proc_id) const
{
  // We're either counting a processor's elements or unpartitioned
  // elements
  libmesh_assert (proc_id < this->n_processors() ||
                  proc_id == DofObject::invalid_processor_id);

  return static_cast<dof_id_type>(std::distance (this->pid_elements_begin(proc_id),
                                                 this->pid_elements_end  (proc_id)));
}

dof_id_type MeshBase::n_active_elem_on_proc (const processor_id_type proc_id) const
{
  libmesh_assert_less (proc_id, this->n_processors());
  return static_cast<dof_id_type>(std::distance (this->active_pid_elements_begin(proc_id),
                                                 this->active_pid_elements_end  (proc_id)));
}

dof_id_type MeshBase::n_sub_elem () const
{
  dof_id_type ne=0;

  const_element_iterator       el  = this->elements_begin();
  const const_element_iterator end = this->elements_end();

  for (; el!=end; ++el)
    ne += (*el)->n_sub_elem();

  return ne;
}

dof_id_type MeshBase::n_active_sub_elem () const
{
  dof_id_type ne=0;

  const_element_iterator       el  = this->active_elements_begin();
  const const_element_iterator end = this->active_elements_end();

  for (; el!=end; ++el)
    ne += (*el)->n_sub_elem();

  return ne;
}

std::string MeshBase::get_info() const
{
  std::ostringstream oss;

  oss << " Mesh Information:"                                  << '\n'
      << "  mesh_dimension()="    << this->mesh_dimension()    << '\n'
      << "  spatial_dimension()=" << this->spatial_dimension() << '\n'
      << "  n_nodes()="           << this->n_nodes()           << '\n'
      << "    n_local_nodes()="   << this->n_local_nodes()     << '\n'
      << "  n_elem()="            << this->n_elem()            << '\n'
      << "    n_local_elem()="    << this->n_local_elem()      << '\n'
#ifdef LIBMESH_ENABLE_AMR
      << "    n_active_elem()="   << this->n_active_elem()     << '\n'
#endif
      << "  n_subdomains()="      << static_cast<std::size_t>(this->n_subdomains()) << '\n'
      << "  n_partitions()="      << static_cast<std::size_t>(this->n_partitions()) << '\n'
      << "  n_processors()="      << static_cast<std::size_t>(this->n_processors()) << '\n'
      << "  n_threads()="         << static_cast<std::size_t>(libMesh::n_threads()) << '\n'
      << "  processor_id()="      << static_cast<std::size_t>(this->processor_id()) << '\n';

  return oss.str();
}

void MeshBase::print_info(std::ostream& os) const
{
  os << this->get_info()
     << std::endl;
}

std::ostream& operator << (std::ostream& os, const MeshBase& m)
{
  m.print_info(os);
  return os;
}

void MeshBase::partition (const unsigned int n_parts)
{
  // NULL partitioner means don't partition
  // Non-serial meshes aren't ready for partitioning yet.
  if(!skip_partitioning() &&
     partitioner().get() &&
     this->is_serial())
    {
      partitioner()->partition (*this, n_parts);
    }
  else
    {
      // Adaptive coarsening may have "orphaned" nodes on processors
      // whose elements no longer share them.  We need to check for
      // and possibly fix that.
      Partitioner::set_node_processor_ids(*this);

      // Make sure locally cached partition count
      this->recalculate_n_partitions();

      // Make sure any other locally cached data is correct
      this->update_post_partitioning();
    }
}

unsigned int MeshBase::recalculate_n_partitions()
{
  // This requires an inspection on every processor
  parallel_object_only();

  const_element_iterator el  = this->active_local_elements_begin();
  const_element_iterator end = this->active_local_elements_end();

  unsigned int max_proc_id=0;

  for (; el!=end; ++el)
    max_proc_id = std::max(max_proc_id, static_cast<unsigned int>((*el)->processor_id()));

  // The number of partitions is one more than the max processor ID.
  _n_parts = max_proc_id+1;

  this->comm().max(_n_parts);

  return _n_parts;
}

const PointLocatorBase& MeshBase::point_locator () const
{
  libmesh_deprecated();

  if (_point_locator.get() == NULL)
    {
      // PointLocator construction may not be safe within threads
      libmesh_assert(!Threads::in_threads);

      _point_locator.reset (PointLocatorBase::build(TREE_ELEMENTS, *this).release());
    }

  return *_point_locator;
}

AutoPtr<PointLocatorBase> MeshBase::sub_point_locator () const
{
  if (_point_locator.get() == NULL)
    {
      // PointLocator construction may not be safe within threads
      libmesh_assert(!Threads::in_threads);

      _point_locator.reset (PointLocatorBase::build(TREE_ELEMENTS, *this).release());
    }

  return PointLocatorBase::build(TREE_ELEMENTS, *this, _point_locator.get());
}

void MeshBase::clear_point_locator ()
{
  _point_locator.reset(NULL);
}

std::string& MeshBase::subdomain_name(subdomain_id_type id)
{
  return _block_id_to_name[id];
}

const std::string& MeshBase::subdomain_name(subdomain_id_type id) const
{
  // An empty string to return when no matching subdomain name is found
  static const std::string empty;

  std::map<subdomain_id_type, std::string>::const_iterator iter = _block_id_to_name.find(id);
  if (iter == _block_id_to_name.end())
    return empty;
  else
    return iter->second;
}

subdomain_id_type MeshBase::get_id_by_name(const std::string& name) const
{
  // Linear search over the map values.
  std::map<subdomain_id_type, std::string>::const_iterator
    iter = _block_id_to_name.begin(),
    end_iter = _block_id_to_name.end();

  for ( ; iter != end_iter; ++iter)
    if (iter->second == name)
      return iter->first;

  // If we made it here without returning, we don't have a subdomain
  // with the requested name, so return Elem::invalid_subdomain_id.
  return Elem::invalid_subdomain_id;
}

void MeshBase::cache_elem_dims()
{
  // This requires an inspection on every processor
  parallel_object_only();

  const_element_iterator el  = this->active_local_elements_begin();
  const_element_iterator end = this->active_local_elements_end();

  for (; el!=end; ++el)
    _elem_dims.insert((*el)->dim());

  // Some different dimension elements may only live on other processors
  this->comm().set_union(_elem_dims);
}

} // namespace libMesh
<|endoftext|>


<commit_before>#include "../test.h"

#if !defined(_MSC_VER) || _MSC_VER >= 1800 // Before VC2013 do not support C99 variable declaration

#include "json-c/json.h"

static void GenStat(Stat* s, json_object* v) {
    switch (json_object_get_type(v)) {
    case json_type_object:
        {
            json_object_object_foreach(v, key, val) {
                GenStat(s, val);
                s->stringCount++;
                s->stringLength += strlen(key);
                s->memberCount++;
            }
            s->objectCount++;
        }
        break;

    case json_type_array:
        for (int i = 0; i < json_object_array_length(v); i++)
            GenStat(s, json_object_array_get_idx(v, i));
        s->elementCount += json_object_array_length(v);
        s->arrayCount++;
        break;

    case json_type_string:
        s->stringCount++;
        s->stringLength += json_object_get_string_len(v);
        break;

    case json_type_int:
    case json_type_double:
        s->numberCount++;
        break;

    case json_type_boolean:
        if (json_object_get_boolean(v))
            s->trueCount++;
        else
            s->falseCount++;
        break;

        break;

    case json_type_null:
        s->nullCount++;
        break;
    }
}

class JsoncParseResult : public ParseResultBase {
public:
    JsoncParseResult() : root() {}
    ~JsoncParseResult() { json_object_put(root); }

    json_object *root;
};

class JsoncStringResult : public StringResultBase {
public:
    JsoncStringResult() : s() {}
    ~JsoncStringResult() { free(s); }

    virtual const char* c_str() const { return s; }

    char* s;
};

class JsoncTest : public TestBase {
public:
#if TEST_INFO
    virtual const char* GetName() const { return "json-c (C)"; }
    virtual const char* GetFilename() const { return __FILE__; }
#endif

#if TEST_PARSE
    virtual ParseResultBase* Parse(const char* json, size_t length) const {
        (void)length;
        JsoncParseResult* pr = new JsoncParseResult;
        pr->root = json_tokener_parse(json);
        if (!pr->root) {
            delete pr;
            return 0;
        }
    	return pr;
    }
#endif

#if TEST_STRINGIFY
    virtual StringResultBase* Stringify(const ParseResultBase* parseResult) const {
        const JsoncParseResult* pr = static_cast<const JsoncParseResult*>(parseResult);
        JsoncStringResult* sr = new JsoncStringResult;
        sr->s = StrDup(json_object_to_json_string_ext(pr->root, JSON_C_TO_STRING_PLAIN));
        return sr;
    }
#endif

#if TEST_PRETTIFY
    virtual StringResultBase* Prettify(const ParseResultBase* parseResult) const {
        const JsoncParseResult* pr = static_cast<const JsoncParseResult*>(parseResult);
        JsoncStringResult* sr = new JsoncStringResult;
        sr->s = StrDup(json_object_to_json_string_ext(pr->root, JSON_C_TO_STRING_PRETTY));
        return sr;
    }
#endif

#if TEST_STATISTICS
    virtual bool Statistics(const ParseResultBase* parseResult, Stat* stat) const {
        const JsoncParseResult* pr = static_cast<const JsoncParseResult*>(parseResult);
        memset(stat, 0, sizeof(Stat));
        GenStat(stat, (json_object*)pr->root);
        return true;
    }
#endif

#if TEST_CONFORMANCE
    virtual bool ParseDouble(const char* json, double* d) const {
        JsoncParseResult pr;
        pr.root = json_tokener_parse(json);
        if (pr.root &&
            json_object_get_type(pr.root) == json_type_array &&
            json_object_array_length(pr.root) == 1 &&
            json_object_get_type(json_object_array_get_idx(pr.root, 0)) == json_type_double)
        {
            *d = json_object_get_double(json_object_array_get_idx(pr.root, 0));
            return true;
        }
        else
            return false;
    }

    virtual bool ParseString(const char* json, std::string& s) const {
        JsoncParseResult pr;
        pr.root = json_tokener_parse(json);
        if (pr.root &&
            json_object_get_type(pr.root) == json_type_array &&
            json_object_array_length(pr.root) == 1 &&
            json_object_get_type(json_object_array_get_idx(pr.root, 0)) == json_type_string)
        {
            s = std::string(
                json_object_get_string(json_object_array_get_idx(pr.root, 0)),
                json_object_get_string_len(json_object_array_get_idx(pr.root, 0)));
            return true;
        }
        else
            return false;
    }
#endif
};

REGISTER_TEST(JsoncTest);

#endif<commit_msg>Ignore json-c on cygwin 32-bit (due to crash)<commit_after>#include "../test.h"

#if (!defined(_MSC_VER) || _MSC_VER >= 1800) && !(defined(__CYGWIN__) && defined(__i386__)) // Before VC2013 do not support C99 variable declaration, and crash in cygwin 32-bit

#include "json-c/json.h"

static void GenStat(Stat* s, json_object* v) {
    switch (json_object_get_type(v)) {
    case json_type_object:
        {
            json_object_object_foreach(v, key, val) {
                GenStat(s, val);
                s->stringCount++;
                s->stringLength += strlen(key);
                s->memberCount++;
            }
            s->objectCount++;
        }
        break;

    case json_type_array:
        for (int i = 0; i < json_object_array_length(v); i++)
            GenStat(s, json_object_array_get_idx(v, i));
        s->elementCount += json_object_array_length(v);
        s->arrayCount++;
        break;

    case json_type_string:
        s->stringCount++;
        s->stringLength += json_object_get_string_len(v);
        break;

    case json_type_int:
    case json_type_double:
        s->numberCount++;
        break;

    case json_type_boolean:
        if (json_object_get_boolean(v))
            s->trueCount++;
        else
            s->falseCount++;
        break;

        break;

    case json_type_null:
        s->nullCount++;
        break;
    }
}

class JsoncParseResult : public ParseResultBase {
public:
    JsoncParseResult() : root() {}
    ~JsoncParseResult() { json_object_put(root); }

    json_object *root;
};

class JsoncStringResult : public StringResultBase {
public:
    JsoncStringResult() : s() {}
    ~JsoncStringResult() { free(s); }

    virtual const char* c_str() const { return s; }

    char* s;
};

class JsoncTest : public TestBase {
public:
#if TEST_INFO
    virtual const char* GetName() const { return "json-c (C)"; }
    virtual const char* GetFilename() const { return __FILE__; }
#endif

#if TEST_PARSE
    virtual ParseResultBase* Parse(const char* json, size_t length) const {
        (void)length;
        JsoncParseResult* pr = new JsoncParseResult;
        pr->root = json_tokener_parse(json);
        if (!pr->root) {
            delete pr;
            return 0;
        }
    	return pr;
    }
#endif

#if TEST_STRINGIFY
    virtual StringResultBase* Stringify(const ParseResultBase* parseResult) const {
        const JsoncParseResult* pr = static_cast<const JsoncParseResult*>(parseResult);
        JsoncStringResult* sr = new JsoncStringResult;
        sr->s = StrDup(json_object_to_json_string_ext(pr->root, JSON_C_TO_STRING_PLAIN));
        return sr;
    }
#endif

#if TEST_PRETTIFY
    virtual StringResultBase* Prettify(const ParseResultBase* parseResult) const {
        const JsoncParseResult* pr = static_cast<const JsoncParseResult*>(parseResult);
        JsoncStringResult* sr = new JsoncStringResult;
        sr->s = StrDup(json_object_to_json_string_ext(pr->root, JSON_C_TO_STRING_PRETTY));
        return sr;
    }
#endif

#if TEST_STATISTICS
    virtual bool Statistics(const ParseResultBase* parseResult, Stat* stat) const {
        const JsoncParseResult* pr = static_cast<const JsoncParseResult*>(parseResult);
        memset(stat, 0, sizeof(Stat));
        GenStat(stat, (json_object*)pr->root);
        return true;
    }
#endif

#if TEST_CONFORMANCE
    virtual bool ParseDouble(const char* json, double* d) const {
        JsoncParseResult pr;
        pr.root = json_tokener_parse(json);
        if (pr.root &&
            json_object_get_type(pr.root) == json_type_array &&
            json_object_array_length(pr.root) == 1 &&
            json_object_get_type(json_object_array_get_idx(pr.root, 0)) == json_type_double)
        {
            *d = json_object_get_double(json_object_array_get_idx(pr.root, 0));
            return true;
        }
        else
            return false;
    }

    virtual bool ParseString(const char* json, std::string& s) const {
        JsoncParseResult pr;
        pr.root = json_tokener_parse(json);
        if (pr.root &&
            json_object_get_type(pr.root) == json_type_array &&
            json_object_array_length(pr.root) == 1 &&
            json_object_get_type(json_object_array_get_idx(pr.root, 0)) == json_type_string)
        {
            s = std::string(
                json_object_get_string(json_object_array_get_idx(pr.root, 0)),
                json_object_get_string_len(json_object_array_get_idx(pr.root, 0)));
            return true;
        }
        else
            return false;
    }
#endif
};

REGISTER_TEST(JsoncTest);

#endif<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id$

//mapnik
#include <mapnik/text_symbolizer.hpp>
// boost
#include <boost/scoped_ptr.hpp>
#include <mapnik/text_processing.hpp>

namespace mapnik
{

static const char * label_placement_strings[] = {
    "point",
    "line",
    "vertex",
    "interior",
    ""
};

IMPLEMENT_ENUM( label_placement_e, label_placement_strings )

static const char * vertical_alignment_strings[] = {
    "top",
    "middle",
    "bottom",
    "auto",
    ""
};

IMPLEMENT_ENUM( vertical_alignment_e, vertical_alignment_strings )

static const char * horizontal_alignment_strings[] = {
    "left",
    "middle",
    "right",
    "auto",
    ""
};

IMPLEMENT_ENUM( horizontal_alignment_e, horizontal_alignment_strings )

static const char * justify_alignment_strings[] = {
    "left",
    "center",
    "right",
    ""
};

IMPLEMENT_ENUM( justify_alignment_e, justify_alignment_strings )

static const char * text_transform_strings[] = {
    "none",
    "uppercase",
    "lowercase",
    "capitalize",
    ""
};

IMPLEMENT_ENUM( text_transform_e, text_transform_strings )

text_symbolizer::text_symbolizer(text_placements_ptr placements)
    : symbolizer_base(),
      placement_options_(placements)
{

}

text_symbolizer::text_symbolizer(expression_ptr name, std::string const& face_name,
                                 float size, color const& fill,
                                 text_placements_ptr placements)
    : symbolizer_base(),
      placement_options_(placements)
{
    set_name(name);
    set_face_name(face_name);
    set_text_size(size);
    set_fill(fill);
}

text_symbolizer::text_symbolizer(expression_ptr name, float size, color const& fill,
                                 text_placements_ptr placements)
    : symbolizer_base(),
      placement_options_(placements)
{
    set_name(name);
    set_text_size(size);
    set_fill(fill);
}

text_symbolizer::text_symbolizer(text_symbolizer const& rhs)
    : symbolizer_base(rhs),
      placement_options_(rhs.placement_options_) /*TODO: Copy options! */
{
}

text_symbolizer& text_symbolizer::operator=(text_symbolizer const& other)
{
    if (this == &other)
        return *this;
    placement_options_ = other.placement_options_; /*TODO: Copy options? */
    std::clog << "TODO: Metawriter (text_symbolizer::operator=)\n";
    return *this;
}

expression_ptr text_symbolizer::get_name() const
{
    return expression_ptr();
}

void text_symbolizer::set_name(expression_ptr name)
{
    placement_options_->properties.processor.set_old_style_expression(name);
}

expression_ptr text_symbolizer::get_orientation() const
{
    return placement_options_->properties.orientation;
}

void text_symbolizer::set_orientation(expression_ptr orientation)
{
    placement_options_->properties.orientation = orientation;
}

std::string const&  text_symbolizer::get_face_name() const
{
    return placement_options_->properties.processor.defaults.face_name;
}

void text_symbolizer::set_face_name(std::string face_name)
{
    placement_options_->properties.processor.defaults.face_name = face_name;
}

void text_symbolizer::set_fontset(font_set const& fontset)
{
    placement_options_->properties.processor.defaults.fontset = fontset;
}

font_set const& text_symbolizer::get_fontset() const
{
    return placement_options_->properties.processor.defaults.fontset;
}

unsigned  text_symbolizer::get_text_ratio() const
{
    return placement_options_->properties.text_ratio;
}

void  text_symbolizer::set_text_ratio(unsigned ratio)
{
    placement_options_->properties.text_ratio = ratio;
}

unsigned  text_symbolizer::get_wrap_width() const
{
    return placement_options_->properties.wrap_width;
}

void  text_symbolizer::set_wrap_width(unsigned width)
{
    placement_options_->properties.wrap_width = width;
}

bool  text_symbolizer::get_wrap_before() const
{
    return placement_options_->properties.processor.defaults.wrap_before;
}

void  text_symbolizer::set_wrap_before(bool wrap_before)
{
    placement_options_->properties.processor.defaults.wrap_before = wrap_before;
}

unsigned char text_symbolizer::get_wrap_char() const
{
    return placement_options_->properties.processor.defaults.wrap_char;
}

std::string text_symbolizer::get_wrap_char_string() const
{
    return std::string(1, placement_options_->properties.processor.defaults.wrap_char);
}

void  text_symbolizer::set_wrap_char(unsigned char character)
{
    placement_options_->properties.processor.defaults.wrap_char = character;
}

void  text_symbolizer::set_wrap_char_from_string(std::string const& character)
{
    placement_options_->properties.processor.defaults.wrap_char = (character)[0];
}

text_transform_e  text_symbolizer::get_text_transform() const
{
    return placement_options_->properties.processor.defaults.text_transform;
}

void  text_symbolizer::set_text_transform(text_transform_e convert)
{
    placement_options_->properties.processor.defaults.text_transform = convert;
}

unsigned  text_symbolizer::get_line_spacing() const
{
    return placement_options_->properties.processor.defaults.line_spacing;
}

void  text_symbolizer::set_line_spacing(unsigned spacing)
{
    placement_options_->properties.processor.defaults.line_spacing = spacing;
}

unsigned  text_symbolizer::get_character_spacing() const
{
    return placement_options_->properties.processor.defaults.character_spacing;
}

void  text_symbolizer::set_character_spacing(unsigned spacing)
{
    placement_options_->properties.processor.defaults.character_spacing = spacing;
}

unsigned  text_symbolizer::get_label_spacing() const
{
    return placement_options_->properties.label_spacing;
}

void  text_symbolizer::set_label_spacing(unsigned spacing)
{
    placement_options_->properties.label_spacing = spacing;
}

unsigned  text_symbolizer::get_label_position_tolerance() const
{
    return placement_options_->properties.label_position_tolerance;
}

void  text_symbolizer::set_label_position_tolerance(unsigned tolerance)
{
    placement_options_->properties.label_position_tolerance = tolerance;
}

bool  text_symbolizer::get_force_odd_labels() const
{
    return placement_options_->properties.force_odd_labels;
}

void  text_symbolizer::set_force_odd_labels(bool force)
{
    placement_options_->properties.force_odd_labels = force;
}

double text_symbolizer::get_max_char_angle_delta() const
{
    return placement_options_->properties.max_char_angle_delta;
}

void text_symbolizer::set_max_char_angle_delta(double angle)
{
    placement_options_->properties.max_char_angle_delta = angle;
}

void text_symbolizer::set_text_size(float size)
{
    placement_options_->properties.processor.defaults.text_size = size;
}

float text_symbolizer::get_text_size() const
{
    return placement_options_->properties.processor.defaults.text_size;
}

void text_symbolizer::set_fill(color const& fill)
{
    placement_options_->properties.processor.defaults.fill = fill;
}

color const&  text_symbolizer::get_fill() const
{
    return placement_options_->properties.processor.defaults.fill;
}

void  text_symbolizer::set_halo_fill(color const& fill)
{
    placement_options_->properties.processor.defaults.halo_fill = fill;
}

color const&  text_symbolizer::get_halo_fill() const
{
    return placement_options_->properties.processor.defaults.halo_fill;
}

void  text_symbolizer::set_halo_radius(double radius)
{
    placement_options_->properties.processor.defaults.halo_radius = radius;
}

double text_symbolizer::get_halo_radius() const
{
    return placement_options_->properties.processor.defaults.halo_radius;
}

void  text_symbolizer::set_label_placement(label_placement_e label_p)
{
    placement_options_->properties.label_placement = label_p;
}

label_placement_e  text_symbolizer::get_label_placement() const
{
    return placement_options_->properties.label_placement;
}

void  text_symbolizer::set_displacement(double x, double y)
{
    placement_options_->properties.displacement = boost::make_tuple(x,y);
}

void text_symbolizer::set_displacement(position const& p)
{
    placement_options_->set_default_displacement(p);
}

position const& text_symbolizer::get_displacement() const
{
    return placement_options_->properties.displacement;
}

bool text_symbolizer::get_avoid_edges() const
{
    return placement_options_->properties.avoid_edges;
}

void text_symbolizer::set_avoid_edges(bool avoid)
{
    placement_options_->properties.avoid_edges = avoid;
}

double text_symbolizer::get_minimum_distance() const
{
    return placement_options_->properties.minimum_distance;
}

void text_symbolizer::set_minimum_distance(double distance)
{
    placement_options_->properties.minimum_distance = distance;
}

double text_symbolizer::get_minimum_padding() const
{
    return placement_options_->properties.minimum_padding;
}

void text_symbolizer::set_minimum_padding(double distance)
{
    placement_options_->properties.minimum_padding = distance;
}

double text_symbolizer::get_minimum_path_length() const
{
    return placement_options_->properties.minimum_path_length;
}

void text_symbolizer::set_minimum_path_length(double size)
{
    placement_options_->properties.minimum_path_length = size;
}

void text_symbolizer::set_allow_overlap(bool overlap)
{
    placement_options_->properties.allow_overlap = overlap;
}

bool text_symbolizer::get_allow_overlap() const
{
    return placement_options_->properties.allow_overlap;
}

void text_symbolizer::set_text_opacity(double text_opacity)
{
    placement_options_->properties.processor.defaults.text_opacity = text_opacity;
}

double text_symbolizer::get_text_opacity() const
{
    return placement_options_->properties.processor.defaults.text_opacity;
}

void text_symbolizer::set_vertical_alignment(vertical_alignment_e valign)
{
    placement_options_->properties.valign = valign;
}

vertical_alignment_e text_symbolizer::get_vertical_alignment() const
{
    return placement_options_->properties.valign;
}

void text_symbolizer::set_horizontal_alignment(horizontal_alignment_e halign)
{
    placement_options_->properties.halign = halign;
}

horizontal_alignment_e text_symbolizer::get_horizontal_alignment() const
{
    return placement_options_->properties.halign;
}

void text_symbolizer::set_justify_alignment(justify_alignment_e jalign)
{
    placement_options_->properties.jalign = jalign;
}

justify_alignment_e text_symbolizer::get_justify_alignment() const
{
    return placement_options_->properties.jalign;
}

text_placements_ptr text_symbolizer::get_placement_options() const
{
    return placement_options_;
}

void text_symbolizer::set_placement_options(text_placements_ptr placement_options)
{
    placement_options_ = placement_options;
}

}
<commit_msg>Fix set_displacement().<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id$

//mapnik
#include <mapnik/text_symbolizer.hpp>
// boost
#include <boost/scoped_ptr.hpp>
#include <mapnik/text_processing.hpp>

namespace mapnik
{

static const char * label_placement_strings[] = {
    "point",
    "line",
    "vertex",
    "interior",
    ""
};

IMPLEMENT_ENUM( label_placement_e, label_placement_strings )

static const char * vertical_alignment_strings[] = {
    "top",
    "middle",
    "bottom",
    "auto",
    ""
};

IMPLEMENT_ENUM( vertical_alignment_e, vertical_alignment_strings )

static const char * horizontal_alignment_strings[] = {
    "left",
    "middle",
    "right",
    "auto",
    ""
};

IMPLEMENT_ENUM( horizontal_alignment_e, horizontal_alignment_strings )

static const char * justify_alignment_strings[] = {
    "left",
    "center",
    "right",
    ""
};

IMPLEMENT_ENUM( justify_alignment_e, justify_alignment_strings )

static const char * text_transform_strings[] = {
    "none",
    "uppercase",
    "lowercase",
    "capitalize",
    ""
};

IMPLEMENT_ENUM( text_transform_e, text_transform_strings )

text_symbolizer::text_symbolizer(text_placements_ptr placements)
    : symbolizer_base(),
      placement_options_(placements)
{

}

text_symbolizer::text_symbolizer(expression_ptr name, std::string const& face_name,
                                 float size, color const& fill,
                                 text_placements_ptr placements)
    : symbolizer_base(),
      placement_options_(placements)
{
    set_name(name);
    set_face_name(face_name);
    set_text_size(size);
    set_fill(fill);
}

text_symbolizer::text_symbolizer(expression_ptr name, float size, color const& fill,
                                 text_placements_ptr placements)
    : symbolizer_base(),
      placement_options_(placements)
{
    set_name(name);
    set_text_size(size);
    set_fill(fill);
}

text_symbolizer::text_symbolizer(text_symbolizer const& rhs)
    : symbolizer_base(rhs),
      placement_options_(rhs.placement_options_) /*TODO: Copy options! */
{
}

text_symbolizer& text_symbolizer::operator=(text_symbolizer const& other)
{
    if (this == &other)
        return *this;
    placement_options_ = other.placement_options_; /*TODO: Copy options? */
    std::clog << "TODO: Metawriter (text_symbolizer::operator=)\n";
    return *this;
}

expression_ptr text_symbolizer::get_name() const
{
    return expression_ptr();
}

void text_symbolizer::set_name(expression_ptr name)
{
    placement_options_->properties.processor.set_old_style_expression(name);
}

expression_ptr text_symbolizer::get_orientation() const
{
    return placement_options_->properties.orientation;
}

void text_symbolizer::set_orientation(expression_ptr orientation)
{
    placement_options_->properties.orientation = orientation;
}

std::string const&  text_symbolizer::get_face_name() const
{
    return placement_options_->properties.processor.defaults.face_name;
}

void text_symbolizer::set_face_name(std::string face_name)
{
    placement_options_->properties.processor.defaults.face_name = face_name;
}

void text_symbolizer::set_fontset(font_set const& fontset)
{
    placement_options_->properties.processor.defaults.fontset = fontset;
}

font_set const& text_symbolizer::get_fontset() const
{
    return placement_options_->properties.processor.defaults.fontset;
}

unsigned  text_symbolizer::get_text_ratio() const
{
    return placement_options_->properties.text_ratio;
}

void  text_symbolizer::set_text_ratio(unsigned ratio)
{
    placement_options_->properties.text_ratio = ratio;
}

unsigned  text_symbolizer::get_wrap_width() const
{
    return placement_options_->properties.wrap_width;
}

void  text_symbolizer::set_wrap_width(unsigned width)
{
    placement_options_->properties.wrap_width = width;
}

bool  text_symbolizer::get_wrap_before() const
{
    return placement_options_->properties.processor.defaults.wrap_before;
}

void  text_symbolizer::set_wrap_before(bool wrap_before)
{
    placement_options_->properties.processor.defaults.wrap_before = wrap_before;
}

unsigned char text_symbolizer::get_wrap_char() const
{
    return placement_options_->properties.processor.defaults.wrap_char;
}

std::string text_symbolizer::get_wrap_char_string() const
{
    return std::string(1, placement_options_->properties.processor.defaults.wrap_char);
}

void  text_symbolizer::set_wrap_char(unsigned char character)
{
    placement_options_->properties.processor.defaults.wrap_char = character;
}

void  text_symbolizer::set_wrap_char_from_string(std::string const& character)
{
    placement_options_->properties.processor.defaults.wrap_char = (character)[0];
}

text_transform_e  text_symbolizer::get_text_transform() const
{
    return placement_options_->properties.processor.defaults.text_transform;
}

void  text_symbolizer::set_text_transform(text_transform_e convert)
{
    placement_options_->properties.processor.defaults.text_transform = convert;
}

unsigned  text_symbolizer::get_line_spacing() const
{
    return placement_options_->properties.processor.defaults.line_spacing;
}

void  text_symbolizer::set_line_spacing(unsigned spacing)
{
    placement_options_->properties.processor.defaults.line_spacing = spacing;
}

unsigned  text_symbolizer::get_character_spacing() const
{
    return placement_options_->properties.processor.defaults.character_spacing;
}

void  text_symbolizer::set_character_spacing(unsigned spacing)
{
    placement_options_->properties.processor.defaults.character_spacing = spacing;
}

unsigned  text_symbolizer::get_label_spacing() const
{
    return placement_options_->properties.label_spacing;
}

void  text_symbolizer::set_label_spacing(unsigned spacing)
{
    placement_options_->properties.label_spacing = spacing;
}

unsigned  text_symbolizer::get_label_position_tolerance() const
{
    return placement_options_->properties.label_position_tolerance;
}

void  text_symbolizer::set_label_position_tolerance(unsigned tolerance)
{
    placement_options_->properties.label_position_tolerance = tolerance;
}

bool  text_symbolizer::get_force_odd_labels() const
{
    return placement_options_->properties.force_odd_labels;
}

void  text_symbolizer::set_force_odd_labels(bool force)
{
    placement_options_->properties.force_odd_labels = force;
}

double text_symbolizer::get_max_char_angle_delta() const
{
    return placement_options_->properties.max_char_angle_delta;
}

void text_symbolizer::set_max_char_angle_delta(double angle)
{
    placement_options_->properties.max_char_angle_delta = angle;
}

void text_symbolizer::set_text_size(float size)
{
    placement_options_->properties.processor.defaults.text_size = size;
}

float text_symbolizer::get_text_size() const
{
    return placement_options_->properties.processor.defaults.text_size;
}

void text_symbolizer::set_fill(color const& fill)
{
    placement_options_->properties.processor.defaults.fill = fill;
}

color const&  text_symbolizer::get_fill() const
{
    return placement_options_->properties.processor.defaults.fill;
}

void  text_symbolizer::set_halo_fill(color const& fill)
{
    placement_options_->properties.processor.defaults.halo_fill = fill;
}

color const&  text_symbolizer::get_halo_fill() const
{
    return placement_options_->properties.processor.defaults.halo_fill;
}

void  text_symbolizer::set_halo_radius(double radius)
{
    placement_options_->properties.processor.defaults.halo_radius = radius;
}

double text_symbolizer::get_halo_radius() const
{
    return placement_options_->properties.processor.defaults.halo_radius;
}

void  text_symbolizer::set_label_placement(label_placement_e label_p)
{
    placement_options_->properties.label_placement = label_p;
}

label_placement_e  text_symbolizer::get_label_placement() const
{
    return placement_options_->properties.label_placement;
}

void  text_symbolizer::set_displacement(double x, double y)
{
    placement_options_->properties.displacement = boost::make_tuple(x,y);
}

void text_symbolizer::set_displacement(position const& p)
{
    placement_options_->properties.displacement = p;
}

position const& text_symbolizer::get_displacement() const
{
    return placement_options_->properties.displacement;
}

bool text_symbolizer::get_avoid_edges() const
{
    return placement_options_->properties.avoid_edges;
}

void text_symbolizer::set_avoid_edges(bool avoid)
{
    placement_options_->properties.avoid_edges = avoid;
}

double text_symbolizer::get_minimum_distance() const
{
    return placement_options_->properties.minimum_distance;
}

void text_symbolizer::set_minimum_distance(double distance)
{
    placement_options_->properties.minimum_distance = distance;
}

double text_symbolizer::get_minimum_padding() const
{
    return placement_options_->properties.minimum_padding;
}

void text_symbolizer::set_minimum_padding(double distance)
{
    placement_options_->properties.minimum_padding = distance;
}

double text_symbolizer::get_minimum_path_length() const
{
    return placement_options_->properties.minimum_path_length;
}

void text_symbolizer::set_minimum_path_length(double size)
{
    placement_options_->properties.minimum_path_length = size;
}

void text_symbolizer::set_allow_overlap(bool overlap)
{
    placement_options_->properties.allow_overlap = overlap;
}

bool text_symbolizer::get_allow_overlap() const
{
    return placement_options_->properties.allow_overlap;
}

void text_symbolizer::set_text_opacity(double text_opacity)
{
    placement_options_->properties.processor.defaults.text_opacity = text_opacity;
}

double text_symbolizer::get_text_opacity() const
{
    return placement_options_->properties.processor.defaults.text_opacity;
}

void text_symbolizer::set_vertical_alignment(vertical_alignment_e valign)
{
    placement_options_->properties.valign = valign;
}

vertical_alignment_e text_symbolizer::get_vertical_alignment() const
{
    return placement_options_->properties.valign;
}

void text_symbolizer::set_horizontal_alignment(horizontal_alignment_e halign)
{
    placement_options_->properties.halign = halign;
}

horizontal_alignment_e text_symbolizer::get_horizontal_alignment() const
{
    return placement_options_->properties.halign;
}

void text_symbolizer::set_justify_alignment(justify_alignment_e jalign)
{
    placement_options_->properties.jalign = jalign;
}

justify_alignment_e text_symbolizer::get_justify_alignment() const
{
    return placement_options_->properties.jalign;
}

text_placements_ptr text_symbolizer::get_placement_options() const
{
    return placement_options_;
}

void text_symbolizer::set_placement_options(text_placements_ptr placement_options)
{
    placement_options_ = placement_options;
}

}
<|endoftext|>


<commit_before>// model.cpp
#include "model.h"

#include <assimp/Importer.hpp>
#include <assimp/postprocess.h>

namespace demo
{

namespace rndr
{

// OPERATORS
Model& Model::operator=( Model&& other )
{
    if ( isOnGpu() )
    {
        remove();
    }

    _meshes = std::move( other._meshes );
    _isOnGpu = other._isOnGpu;

    other._isOnGpu = false;

    return *this;
}

// MEMBER FUNCTIONS
void Model::load( const String& path )
{
    if ( isLoaded() )
    {
        return;
    }

    if ( path.empty() )
    {
        throw std::runtime_error( "File not specified!" );
    }

    // load file
    Assimp::Importer importer;
    const aiScene* data = importer.ReadFile( path, aiProcess_SortByPType );

    if ( !data )
    {
        throw std::runtime_error( importer.GetErrorString() );
    }

    // generate meshes
    for ( uint32 i = 0; i < data->mNumMeshes; ++i )
    {
        _meshes.push( std::move( Mesh( *( data->mMeshes[i] ) ) ) );
    }
}

void Model::push( const Shader& shader )
{
    if ( isOnGpu() )
    {
        return;
    }

    for ( auto iter = _meshes.begin(); iter != _meshes.end(); ++iter )
    {
        iter->push( shader );
    }

    _isOnGpu = true;
}

void Model::render( const Shader& shader )
{
    if ( !isLoaded() || !isOnGpu() )
    {
        return;
    }

    for ( auto iter = _meshes.begin(); iter != _meshes.end(); ++iter )
    {
        iter->render( shader );
    }
}

void Model::remove()
{
    if ( !isOnGpu() )
    {
        return;
    }

    for ( auto iter = _meshes.begin(); iter != _meshes.end(); ++iter )
    {
        iter->remove();
    }

    _isOnGpu = false;
}

} // End nspc rndr

} // End nspc demo<commit_msg>Ensure path is not empty.<commit_after>// model.cpp
#include "model.h"

#include <assimp/Importer.hpp>
#include <assimp/postprocess.h>

namespace demo
{

namespace rndr
{

// OPERATORS
Model& Model::operator=( Model&& other )
{
    if ( isOnGpu() )
    {
        remove();
    }

    _meshes = std::move( other._meshes );
    _isOnGpu = other._isOnGpu;

    other._isOnGpu = false;

    return *this;
}

// MEMBER FUNCTIONS
void Model::load( const String& path )
{
    if ( isLoaded() )
    {
        return;
    }

	assert( !path.empty() );

    // load file
    Assimp::Importer importer;
    const aiScene* data = importer.ReadFile( path, aiProcess_SortByPType );

    if ( data == nullptr )
    {
        throw std::runtime_error( importer.GetErrorString() );
    }

    // generate meshes
    for ( uint32 i = 0; i < data->mNumMeshes; ++i )
    {
        _meshes.push( std::move( Mesh( *( data->mMeshes[i] ) ) ) );
    }
}

void Model::push( const Shader& shader )
{
    if ( isOnGpu() )
    {
        return;
    }

    for ( auto iter = _meshes.begin(); iter != _meshes.end(); ++iter )
    {
        iter->push( shader );
    }

    _isOnGpu = true;
}

void Model::render( const Shader& shader )
{
    if ( !isLoaded() || !isOnGpu() )
    {
        return;
    }

    for ( auto iter = _meshes.begin(); iter != _meshes.end(); ++iter )
    {
        iter->render( shader );
    }
}

void Model::remove()
{
    if ( !isOnGpu() )
    {
        return;
    }

    for ( auto iter = _meshes.begin(); iter != _meshes.end(); ++iter )
    {
        iter->remove();
    }

    _isOnGpu = false;
}

} // End nspc rndr

} // End nspc demo<|endoftext|>


<commit_before>#include <silicium/http/http.hpp>
#include <silicium/http/receive_request.hpp>
#include <silicium/asio/tcp_acceptor.hpp>
#include <silicium/asio/writing_observable.hpp>
#include <silicium/observable/transform.hpp>
#include <silicium/observable/spawn_coroutine.hpp>
#include <silicium/observable/coroutine.hpp>
#include <silicium/observable/constant.hpp>
#include <silicium/observable/spawn_observable.hpp>
#include <silicium/sink/iterator_sink.hpp>
#include <silicium/memory_range.hpp>

template <class YieldContext>
void serve_client(boost::asio::ip::tcp::socket &client, YieldContext &&yield)
{
	auto request = Si::http::receive_request(client, yield);
	if (request.is_error())
	{
		//The header was incomplete, maybe the connecting was closed.
		//If we want to know the reason, the error_extracting_source remembered it:
		boost::system::error_code error = request.error();
		boost::ignore_unused_variable_warning(error);
		return;
	}

	if (!request.get())
	{
		//syntax error in the request
		return;
	}

	std::vector<char> response;
	{
		auto response_writer = Si::make_container_sink(response);
		Si::http::generate_status_line(response_writer, "HTTP/1.0", "200", "OK");
		std::string const content = "Hello";
		Si::http::generate_header(response_writer, "Content-Length", boost::lexical_cast<Si::noexcept_string>(content.size()));
		Si::append(response_writer, "\r\n");
		Si::append(response_writer, content);
	}

	//you can handle the error if you want
	boost::system::error_code error = Si::asio::write(client, Si::make_memory_range(response), yield);

	//ignore shutdown failures, they do not matter here
	client.shutdown(boost::asio::ip::tcp::socket::shutdown_both, error);
}

int main()
{
	boost::asio::io_service io;
	boost::asio::ip::tcp::acceptor acceptor(io, boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4(), 8080));
	Si::spawn_observable(
		Si::transform(
			Si::asio::make_tcp_acceptor(&acceptor),
			[](Si::asio::tcp_acceptor_result maybe_client)
			{
				auto client = maybe_client.get();
				Si::spawn_coroutine([client](Si::spawn_context yield)
				{
					serve_client(*client, yield);
				});
				return Si::nothing();
			}
		)
	);
	io.run();
}
<commit_msg>remove unused includes<commit_after>#include <silicium/http/receive_request.hpp>
#include <silicium/http/generate_response.hpp>
#include <silicium/asio/writing_observable.hpp>
#include <silicium/asio/tcp_acceptor.hpp>
#include <silicium/observable/transform.hpp>
#include <silicium/observable/spawn_coroutine.hpp>
#include <silicium/observable/spawn_observable.hpp>
#include <silicium/sink/iterator_sink.hpp>

template <class YieldContext>
void serve_client(boost::asio::ip::tcp::socket &client, YieldContext &&yield)
{
	auto request = Si::http::receive_request(client, yield);
	if (request.is_error())
	{
		//The header was incomplete, maybe the connecting was closed.
		//If we want to know the reason, the error_extracting_source remembered it:
		boost::system::error_code error = request.error();
		boost::ignore_unused_variable_warning(error);
		return;
	}

	if (!request.get())
	{
		//syntax error in the request
		return;
	}

	std::vector<char> response;
	{
		auto response_writer = Si::make_container_sink(response);
		Si::http::generate_status_line(response_writer, "HTTP/1.0", "200", "OK");
		std::string const content = "Hello";
		Si::http::generate_header(response_writer, "Content-Length", boost::lexical_cast<Si::noexcept_string>(content.size()));
		Si::append(response_writer, "\r\n");
		Si::append(response_writer, content);
	}

	//you can handle the error if you want
	boost::system::error_code error = Si::asio::write(client, Si::make_memory_range(response), yield);

	//ignore shutdown failures, they do not matter here
	client.shutdown(boost::asio::ip::tcp::socket::shutdown_both, error);
}

int main()
{
	boost::asio::io_service io;
	boost::asio::ip::tcp::acceptor acceptor(io, boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4(), 8080));
	Si::spawn_observable(
		Si::transform(
			Si::asio::make_tcp_acceptor(&acceptor),
			[](Si::asio::tcp_acceptor_result maybe_client)
			{
				auto client = maybe_client.get();
				Si::spawn_coroutine([client](Si::spawn_context yield)
				{
					serve_client(*client, yield);
				});
				return Si::nothing();
			}
		)
	);
	io.run();
}
<|endoftext|>