<commit_before>/*
 * Copyright (c) 2019 Tuukka Norri
 * This code is licensed under MIT license (see LICENSE for details).
 */

#ifndef VCF2MULTIALIGN_VARIANT_GRAPH_VARIANT_GRAPH_GENERATOR_HH
#define VCF2MULTIALIGN_VARIANT_GRAPH_VARIANT_GRAPH_GENERATOR_HH

#include <libbio/copyable_atomic.hh>
#include <libbio/int_matrix.hh>
#include <libbio/matrix.hh>
#include <libbio/vcf/subfield.hh>
#include <libbio/vcf/variant.hh>
#include <ostream>
#include <queue>
#include <string>
#include <vcf2multialign/variant_graph/variant_graph.hh>
#include <vcf2multialign/preprocess/path_sorted_variant.hh>
#include <vcf2multialign/preprocess/sample_indexer.hh>
#include <vcf2multialign/preprocess/sample_sorter.hh>
#include <vcf2multialign/preprocess/types.hh>
#include <vcf2multialign/preprocess/variant_partitioner.hh>
#include <vcf2multialign/types.hh>
#include <vcf2multialign/variant_processor.hh>
#include <vcf2multialign/variant_processor_delegate.hh>
#include <vector>

namespace vcf2multialign {  namespace variant_graphs {
	class variant_graph_generator; // Fwd.

	struct variant_graph_generator_delegate
	{
		virtual ~variant_graph_generator_delegate() {}
		virtual void variant_graph_generator_will_handle_subgraph(libbio::vcf::variant const &first_var, std::size_t const variant_count, std::size_t const path_count) = 0;
	};

	struct variant_graph_single_pass_generator_delegate :	public virtual variant_graph_generator_delegate,
															public virtual variant_processor_delegate // For the case where processing was not done.
	{
	};
}}

namespace vcf2multialign { namespace variant_graphs { namespace detail {

	struct generator_node_description
	{
		std::size_t node_index{};
		std::size_t ref_position{};
		std::size_t alt_edge_start{};
		std::size_t alt_edge_count{};

		generator_node_description() = default;

		explicit generator_node_description(std::size_t ref_position_):
			ref_position(ref_position_)
		{
		}
	};
}}}

namespace vcf2multialign { namespace variant_graphs {

	// Generate a variant graph from a set of VCF records.
	class variant_graph_generator :	public sample_sorter_delegate
	{
	protected:
		typedef std::vector <libbio::vcf::variant>					variant_vector;
		typedef std::vector <detail::generator_node_description>	node_description_vector;
		typedef std::vector <std::size_t>							position_vector;

	protected:
		libbio::vcf::info_field_end const				*m_end_field{};
		variant_graph									m_graph;
		variant_vector									m_subgraph_variants;
		sample_indexer									m_sample_indexer;
		sample_sorter									m_sample_sorter;
		std::vector <std::string>						m_sample_names;
		node_description_vector							m_sorted_nodes;
		position_vector									m_start_positions;
		position_vector									m_end_positions;
		position_vector									m_end_positions_by_sample;
		std::vector <bool>								m_can_handle_alt;
		std::vector <std::uint16_t>						m_unhandled_alt_csum;
		std::size_t										m_output_lineno{};
		libbio::copyable_atomic <std::size_t>			m_processed_count{};

	public:
		variant_graph_generator() = default;

		variant_graph_generator(
			libbio::vcf::reader &reader,
			std::size_t const donor_count,
			std::uint8_t const chr_count
		):
			m_end_field(reader.get_end_field_ptr()),
			m_sample_indexer(donor_count, chr_count), // donor_count and chr_count should be set in all cases.
			m_sample_sorter(*this, reader, m_sample_indexer)
		{
		}

		class variant_graph const &variant_graph() const { return m_graph; }
		class variant_graph &variant_graph() { return m_graph; }
		class sample_sorter &sample_sorter() { return m_sample_sorter; }
		class sample_sorter const &sample_sorter() const { return m_sample_sorter; }
		class sample_indexer &sample_indexer() { return m_sample_indexer; }
		class sample_indexer const &sample_indexer() const { return m_sample_indexer; }

		std::size_t processed_count() const { return m_processed_count.load(std::memory_order_relaxed); }

		virtual void sample_sorter_found_overlapping_variant(
			libbio::vcf::variant const &var,
			std::size_t const sample_idx,
			std::size_t const prev_end_pos
		) override {}

		virtual libbio::vcf::reader &vcf_reader() = 0;
		virtual vector_type const &reference() = 0;
		virtual variant_graph_generator_delegate &delegate() = 0;

	protected:
		void update_sample_names();
		void process_subgraph(std::size_t const prev_overlap_end);
		void combine_subgraph_variants_by_pos_and_ref();
		void reset_genotype_values_for_samples_with_overlapping_variants();
		std::tuple <std::size_t, std::size_t> create_subgraph_and_nodes();
		void generate_graph_setup();
		void finalize_graph();
	};

	class variant_graph_precalculated_generator final :	public variant_graph_generator
	{
	protected:
		variant_graph_generator_delegate				*m_delegate{};
		libbio::vcf::reader								*m_reader{};
		vector_type const								*m_reference{};
		preprocessing_result const						*m_preprocessing_result{};

	public:
		variant_graph_precalculated_generator() = default;

		variant_graph_precalculated_generator(
			variant_graph_generator_delegate &delegate,
			libbio::vcf::reader &reader,
			vector_type const &reference,
			preprocessing_result const &preprocessing_result
		):
			variant_graph_generator(reader, preprocessing_result.donor_count, preprocessing_result.chr_count),
			m_delegate(&delegate),
			m_reader(&reader),
			m_reference(&reference),
			m_preprocessing_result(&preprocessing_result)
		{
		}

		libbio::vcf::reader &vcf_reader() override { return *m_reader; }
		vector_type const &reference() override { return *m_reference; }
		variant_graph_generator_delegate &delegate() override { return *m_delegate; }

		void generate_graph(bool const should_start_from_current_variant);
	};

	class variant_graph_single_pass_generator final :	public variant_graph_generator,
														public variant_processor
	{
	protected:
		variant_graph_single_pass_generator_delegate	*m_delegate{};
		std::size_t										m_minimum_bridge_length{};

	public:
		variant_graph_single_pass_generator() = default;

		variant_graph_single_pass_generator(
			variant_graph_single_pass_generator_delegate &delegate,
			libbio::vcf::reader &reader,
			vector_type const &reference,
			std::string const &chr_name,
			std::size_t const donor_count,
			std::uint8_t const chr_count,
			std::size_t const minimum_bridge_length
		):
			variant_graph_generator(reader, donor_count, chr_count),
			variant_processor(reader, reference, chr_name),
			m_delegate(&delegate),
			m_minimum_bridge_length(minimum_bridge_length)
		{
		}

		libbio::vcf::reader &vcf_reader() override { return *this->m_reader; }
		vector_type const &reference() override { return *this->m_reference; }
		variant_graph_single_pass_generator_delegate &delegate() override { return *m_delegate; }

		void generate_graph(
			std::vector <std::string> const &field_names_for_filter_by_assigned,
			bool const should_start_from_current_variant
		);
	};
}}

#endif
<commit_msg>Use std::deque for buffering variant records<commit_after>/*
 * Copyright (c) 2019 Tuukka Norri
 * This code is licensed under MIT license (see LICENSE for details).
 */

#ifndef VCF2MULTIALIGN_VARIANT_GRAPH_VARIANT_GRAPH_GENERATOR_HH
#define VCF2MULTIALIGN_VARIANT_GRAPH_VARIANT_GRAPH_GENERATOR_HH

#include <deque>
#include <libbio/copyable_atomic.hh>
#include <libbio/int_matrix.hh>
#include <libbio/matrix.hh>
#include <libbio/vcf/subfield.hh>
#include <libbio/vcf/variant.hh>
#include <ostream>
#include <queue>
#include <string>
#include <vcf2multialign/variant_graph/variant_graph.hh>
#include <vcf2multialign/preprocess/path_sorted_variant.hh>
#include <vcf2multialign/preprocess/sample_indexer.hh>
#include <vcf2multialign/preprocess/sample_sorter.hh>
#include <vcf2multialign/preprocess/types.hh>
#include <vcf2multialign/preprocess/variant_partitioner.hh>
#include <vcf2multialign/types.hh>
#include <vcf2multialign/variant_processor.hh>
#include <vcf2multialign/variant_processor_delegate.hh>
#include <vector>

namespace vcf2multialign {  namespace variant_graphs {
	class variant_graph_generator; // Fwd.

	struct variant_graph_generator_delegate
	{
		virtual ~variant_graph_generator_delegate() {}
		virtual void variant_graph_generator_will_handle_subgraph(libbio::vcf::variant const &first_var, std::size_t const variant_count, std::size_t const path_count) = 0;
	};

	struct variant_graph_single_pass_generator_delegate :	public virtual variant_graph_generator_delegate,
															public virtual variant_processor_delegate // For the case where processing was not done.
	{
	};
}}

namespace vcf2multialign { namespace variant_graphs { namespace detail {

	struct generator_node_description
	{
		std::size_t node_index{};
		std::size_t ref_position{};
		std::size_t alt_edge_start{};
		std::size_t alt_edge_count{};

		generator_node_description() = default;

		explicit generator_node_description(std::size_t ref_position_):
			ref_position(ref_position_)
		{
		}
	};
}}}

namespace vcf2multialign { namespace variant_graphs {

	// Generate a variant graph from a set of VCF records.
	class variant_graph_generator :	public sample_sorter_delegate
	{
	protected:
		typedef std::deque <libbio::vcf::variant>					variant_vector;
		typedef std::vector <detail::generator_node_description>	node_description_vector;
		typedef std::vector <std::size_t>							position_vector;

	protected:
		libbio::vcf::info_field_end const				*m_end_field{};
		variant_graph									m_graph;
		variant_vector									m_subgraph_variants;
		sample_indexer									m_sample_indexer;
		sample_sorter									m_sample_sorter;
		std::vector <std::string>						m_sample_names;
		node_description_vector							m_sorted_nodes;
		position_vector									m_start_positions;
		position_vector									m_end_positions;
		position_vector									m_end_positions_by_sample;
		std::vector <bool>								m_can_handle_alt;
		std::vector <std::uint16_t>						m_unhandled_alt_csum;
		std::size_t										m_output_lineno{};
		libbio::copyable_atomic <std::size_t>			m_processed_count{};

	public:
		variant_graph_generator() = default;

		variant_graph_generator(
			libbio::vcf::reader &reader,
			std::size_t const donor_count,
			std::uint8_t const chr_count
		):
			m_end_field(reader.get_end_field_ptr()),
			m_sample_indexer(donor_count, chr_count), // donor_count and chr_count should be set in all cases.
			m_sample_sorter(*this, reader, m_sample_indexer)
		{
		}

		class variant_graph const &variant_graph() const { return m_graph; }
		class variant_graph &variant_graph() { return m_graph; }
		class sample_sorter &sample_sorter() { return m_sample_sorter; }
		class sample_sorter const &sample_sorter() const { return m_sample_sorter; }
		class sample_indexer &sample_indexer() { return m_sample_indexer; }
		class sample_indexer const &sample_indexer() const { return m_sample_indexer; }

		std::size_t processed_count() const { return m_processed_count.load(std::memory_order_relaxed); }

		virtual void sample_sorter_found_overlapping_variant(
			libbio::vcf::variant const &var,
			std::size_t const sample_idx,
			std::size_t const prev_end_pos
		) override {}

		virtual libbio::vcf::reader &vcf_reader() = 0;
		virtual vector_type const &reference() = 0;
		virtual variant_graph_generator_delegate &delegate() = 0;

	protected:
		void update_sample_names();
		void process_subgraph(std::size_t const prev_overlap_end);
		void combine_subgraph_variants_by_pos_and_ref();
		void reset_genotype_values_for_samples_with_overlapping_variants();
		std::tuple <std::size_t, std::size_t> create_subgraph_and_nodes();
		void generate_graph_setup();
		void finalize_graph();
	};

	class variant_graph_precalculated_generator final :	public variant_graph_generator
	{
	protected:
		variant_graph_generator_delegate				*m_delegate{};
		libbio::vcf::reader								*m_reader{};
		vector_type const								*m_reference{};
		preprocessing_result const						*m_preprocessing_result{};

	public:
		variant_graph_precalculated_generator() = default;

		variant_graph_precalculated_generator(
			variant_graph_generator_delegate &delegate,
			libbio::vcf::reader &reader,
			vector_type const &reference,
			preprocessing_result const &preprocessing_result
		):
			variant_graph_generator(reader, preprocessing_result.donor_count, preprocessing_result.chr_count),
			m_delegate(&delegate),
			m_reader(&reader),
			m_reference(&reference),
			m_preprocessing_result(&preprocessing_result)
		{
		}

		libbio::vcf::reader &vcf_reader() override { return *m_reader; }
		vector_type const &reference() override { return *m_reference; }
		variant_graph_generator_delegate &delegate() override { return *m_delegate; }

		void generate_graph(bool const should_start_from_current_variant);
	};

	class variant_graph_single_pass_generator final :	public variant_graph_generator,
														public variant_processor
	{
	protected:
		variant_graph_single_pass_generator_delegate	*m_delegate{};
		std::size_t										m_minimum_bridge_length{};

	public:
		variant_graph_single_pass_generator() = default;

		variant_graph_single_pass_generator(
			variant_graph_single_pass_generator_delegate &delegate,
			libbio::vcf::reader &reader,
			vector_type const &reference,
			std::string const &chr_name,
			std::size_t const donor_count,
			std::uint8_t const chr_count,
			std::size_t const minimum_bridge_length
		):
			variant_graph_generator(reader, donor_count, chr_count),
			variant_processor(reader, reference, chr_name),
			m_delegate(&delegate),
			m_minimum_bridge_length(minimum_bridge_length)
		{
		}

		libbio::vcf::reader &vcf_reader() override { return *this->m_reader; }
		vector_type const &reference() override { return *this->m_reference; }
		variant_graph_single_pass_generator_delegate &delegate() override { return *m_delegate; }

		void generate_graph(
			std::vector <std::string> const &field_names_for_filter_by_assigned,
			bool const should_start_from_current_variant
		);
	};
}}

#endif
<|endoftext|>


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

#include "scene_triangle_mesh.h"
#include "scene.h"

namespace embree
{
  TriangleMesh::TriangleMesh (Scene* parent, RTCGeometryFlags flags, size_t numTriangles, size_t numVertices, size_t numTimeSteps)
    : Geometry(parent,TRIANGLE_MESH,numTriangles,numTimeSteps,flags), mask(-1)
  {
    triangles.init(numTriangles,sizeof(Triangle));
    for (size_t i=0; i<numTimeSteps; i++) {
      vertices[i].init(numVertices,sizeof(Vec3fa));
    }
    enabling();
  }

  void TriangleMesh::enabling()
  {
    if (numTimeSteps == 1) atomic_add(&parent->numTriangles ,triangles.size());
    else                   atomic_add(&parent->numTriangles2,triangles.size());
  }

  void TriangleMesh::disabling()
  {
    if (numTimeSteps == 1) atomic_add(&parent->numTriangles ,-(ssize_t)triangles.size());
    else                   atomic_add(&parent->numTriangles2,-(ssize_t)triangles.size());
  }

  void TriangleMesh::setMask (unsigned mask)
  {
    if (parent->isStatic() && parent->isBuild())
      throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");

    this->mask = mask;
  }

  void TriangleMesh::setBuffer(RTCBufferType type, void* ptr, size_t offset, size_t stride)
  {
    if (parent->isStatic() && parent->isBuild())
      throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");

    /* verify that all accesses are 4 bytes aligned */
    if (((size_t(ptr) + offset) & 0x3) || (stride & 0x3))
      throw_RTCError(RTC_INVALID_OPERATION,"data must be 4 bytes aligned");

    switch (type) {
    case RTC_INDEX_BUFFER  :
      triangles.set(ptr,offset,stride);
      break;
    case RTC_VERTEX_BUFFER0:
      vertices[0].set(ptr,offset,stride);
      if (vertices[0].size()) {
        /* test if array is properly padded */
        volatile int w = *((int*)vertices[0].getPtr(vertices[0].size()-1)+3); // FIXME: is failing hard avoidable?
      }
      break;
    case RTC_VERTEX_BUFFER1:
      vertices[1].set(ptr,offset,stride);
      if (vertices[1].size()) {
        /* test if array is properly padded */
        volatile int w = *((int*)vertices[1].getPtr(vertices[1].size()-1)+3); // FIXME: is failing hard avoidable?
      }
      break;
    default:
      throw_RTCError(RTC_INVALID_ARGUMENT,"unknown buffer type");
    }
  }

  void* TriangleMesh::map(RTCBufferType type)
  {
    if (parent->isStatic() && parent->isBuild())
      throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");

    switch (type) {
    case RTC_INDEX_BUFFER  : return triangles  .map(parent->numMappedBuffers);
    case RTC_VERTEX_BUFFER0: return vertices[0].map(parent->numMappedBuffers);
    case RTC_VERTEX_BUFFER1: return vertices[1].map(parent->numMappedBuffers);
    default                : throw_RTCError(RTC_INVALID_ARGUMENT,"unknown buffer type"); return nullptr;
    }
  }

  void TriangleMesh::unmap(RTCBufferType type)
  {
    if (parent->isStatic() && parent->isBuild())
      throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");

    switch (type) {
    case RTC_INDEX_BUFFER  : triangles  .unmap(parent->numMappedBuffers); break;
    case RTC_VERTEX_BUFFER0: vertices[0].unmap(parent->numMappedBuffers); break;
    case RTC_VERTEX_BUFFER1: vertices[1].unmap(parent->numMappedBuffers); break;
    default                : throw_RTCError(RTC_INVALID_ARGUMENT,"unknown buffer type"); break;
    }
  }

  void TriangleMesh::immutable ()
  {
    bool freeTriangles = !parent->needTriangles;
    bool freeVertices  = !parent->needTriangleVertices;
    if (freeTriangles) triangles.free();
    if (freeVertices ) vertices[0].free();
    if (freeVertices ) vertices[1].free();
  }

  bool TriangleMesh::verify ()
  {
    if (numTimeSteps == 2 && vertices[0].size() != vertices[1].size())
        return false;

    for (size_t i=0; i<triangles.size(); i++) {
      if (triangles[i].v[0] >= numVertices()) return false;
      if (triangles[i].v[1] >= numVertices()) return false;
      if (triangles[i].v[2] >= numVertices()) return false;
    }
    for (size_t j=0; j<numTimeSteps; j++) {
      BufferT<Vec3fa>& verts = vertices[j];
      for (size_t i=0; i<verts.size(); i++) {
	if (!isvalid(verts[i]))
	  return false;
      }
    }
    return true;
  }

  void TriangleMesh::write(std::ofstream& file)
  {
    int type = TRIANGLE_MESH;
    file.write((char*)&type,sizeof(int));
    file.write((char*)&numTimeSteps,sizeof(int));
    int numVerts = numVertices();
    file.write((char*)&numVerts,sizeof(int));
    int numTriangles = triangles.size();
    file.write((char*)&numTriangles,sizeof(int));

    for (size_t j=0; j<numTimeSteps; j++) {
      while ((file.tellp() % 16) != 0) { char c = 0; file.write(&c,1); }
      for (size_t i=0; i<numVerts; i++) file.write((char*)vertexPtr(i,j),sizeof(Vec3fa));
    }

    while ((file.tellp() % 16) != 0) { char c = 0; file.write(&c,1); }
    for (size_t i=0; i<numTriangles; i++) file.write((char*)&triangle(i),sizeof(Triangle));

    while ((file.tellp() % 16) != 0) { char c = 0; file.write(&c,1); }
    for (size_t i=0; i<numTriangles; i++) file.write((char*)&triangle(i),sizeof(Triangle));   // FIXME: why is this written twice?
  }
}
<commit_msg>cleanups to trianglemesh<commit_after>// ======================================================================== //
// Copyright 2009-2015 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#include "scene_triangle_mesh.h"
#include "scene.h"

namespace embree
{
  TriangleMesh::TriangleMesh (Scene* parent, RTCGeometryFlags flags, size_t numTriangles, size_t numVertices, size_t numTimeSteps)
    : Geometry(parent,TRIANGLE_MESH,numTriangles,numTimeSteps,flags), mask(-1)
  {
    triangles.init(numTriangles,sizeof(Triangle));
    for (size_t i=0; i<numTimeSteps; i++) {
      vertices[i].init(numVertices,sizeof(Vec3fa));
    }
    enabling();
  }

  void TriangleMesh::enabling()
  {
    if (numTimeSteps == 1) atomic_add(&parent->numTriangles ,triangles.size());
    else                   atomic_add(&parent->numTriangles2,triangles.size());
  }

  void TriangleMesh::disabling()
  {
    if (numTimeSteps == 1) atomic_add(&parent->numTriangles ,-(ssize_t)triangles.size());
    else                   atomic_add(&parent->numTriangles2,-(ssize_t)triangles.size());
  }

  void TriangleMesh::setMask (unsigned mask)
  {
    if (parent->isStatic() && parent->isBuild())
      throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");

    this->mask = mask;
  }

  void TriangleMesh::setBuffer(RTCBufferType type, void* ptr, size_t offset, size_t stride)
  {
    if (parent->isStatic() && parent->isBuild())
      throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");

    /* verify that all accesses are 4 bytes aligned */
    if (((size_t(ptr) + offset) & 0x3) || (stride & 0x3))
      throw_RTCError(RTC_INVALID_OPERATION,"data must be 4 bytes aligned");

    switch (type) {
    case RTC_INDEX_BUFFER  :
      triangles.set(ptr,offset,stride);
      break;
    case RTC_VERTEX_BUFFER0:
      vertices[0].set(ptr,offset,stride);

      /* test if array is properly padded */
      if (vertices[0].size())
        volatile int w = *((int*)vertices[0].getPtr(vertices[0].size()-1)+3); // FIXME: is failing hard avoidable?

      break;
    case RTC_VERTEX_BUFFER1:
      vertices[1].set(ptr,offset,stride);

      /* test if array is properly padded */
      if (vertices[1].size())
        volatile int w = *((int*)vertices[1].getPtr(vertices[1].size()-1)+3); // FIXME: is failing hard avoidable?

      break;
    default:
      throw_RTCError(RTC_INVALID_ARGUMENT,"unknown buffer type");
    }
  }

  void* TriangleMesh::map(RTCBufferType type)
  {
    if (parent->isStatic() && parent->isBuild())
      throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");

    switch (type) {
    case RTC_INDEX_BUFFER  : return triangles  .map(parent->numMappedBuffers);
    case RTC_VERTEX_BUFFER0: return vertices[0].map(parent->numMappedBuffers);
    case RTC_VERTEX_BUFFER1: return vertices[1].map(parent->numMappedBuffers);
    default                : throw_RTCError(RTC_INVALID_ARGUMENT,"unknown buffer type"); return nullptr;
    }
  }

  void TriangleMesh::unmap(RTCBufferType type)
  {
    if (parent->isStatic() && parent->isBuild())
      throw_RTCError(RTC_INVALID_OPERATION,"static scenes cannot get modified");

    switch (type) {
    case RTC_INDEX_BUFFER  : triangles  .unmap(parent->numMappedBuffers); break;
    case RTC_VERTEX_BUFFER0: vertices[0].unmap(parent->numMappedBuffers); break;
    case RTC_VERTEX_BUFFER1: vertices[1].unmap(parent->numMappedBuffers); break;
    default                : throw_RTCError(RTC_INVALID_ARGUMENT,"unknown buffer type"); break;
    }
  }

  void TriangleMesh::immutable ()
  {
    bool freeTriangles = !parent->needTriangles;
    bool freeVertices  = !parent->needTriangleVertices;
    if (freeTriangles) triangles.free();
    if (freeVertices ) vertices[0].free();
    if (freeVertices ) vertices[1].free();
  }

  bool TriangleMesh::verify ()
  {
    /*! verify consistent size of vertex arrays */
    if (numTimeSteps == 2 && vertices[0].size() != vertices[1].size())
        return false;

    /*! verify proper triangle indices */
    for (size_t i=0; i<triangles.size(); i++) {
      if (triangles[i].v[0] >= numVertices()) return false;
      if (triangles[i].v[1] >= numVertices()) return false;
      if (triangles[i].v[2] >= numVertices()) return false;
    }

    /*! verify proper triangle vertices */
    for (size_t j=0; j<numTimeSteps; j++)
    {
      BufferT<Vec3fa>& verts = vertices[j];
      for (size_t i=0; i<verts.size(); i++) {
	if (!isvalid(verts[i]))
	  return false;
      }
    }
    return true;
  }

  void TriangleMesh::write(std::ofstream& file)
  {
    int type = TRIANGLE_MESH;
    file.write((char*)&type,sizeof(int));
    file.write((char*)&numTimeSteps,sizeof(int));
    int numVerts = numVertices();
    file.write((char*)&numVerts,sizeof(int));
    int numTriangles = triangles.size();
    file.write((char*)&numTriangles,sizeof(int));

    for (size_t j=0; j<numTimeSteps; j++) {
      while ((file.tellp() % 16) != 0) { char c = 0; file.write(&c,1); }
      for (size_t i=0; i<numVerts; i++) file.write((char*)vertexPtr(i,j),sizeof(Vec3fa));
    }

    while ((file.tellp() % 16) != 0) { char c = 0; file.write(&c,1); }
    for (size_t i=0; i<numTriangles; i++) file.write((char*)&triangle(i),sizeof(Triangle));

    while ((file.tellp() % 16) != 0) { char c = 0; file.write(&c,1); }
    for (size_t i=0; i<numTriangles; i++) file.write((char*)&triangle(i),sizeof(Triangle));   // FIXME: why is this written twice?
  }
}
<|endoftext|>


<commit_before>/*
  Copyright 2007 Google Inc.

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

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

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

#include "image.h"
#include "canvas_interface.h"
#include "graphics_interface.h"
#include "file_manager_interface.h"

namespace ggadget {

class Image::Impl {
 public:
  Impl(const GraphicsInterface *graphics,
       FileManagerInterface *file_manager,
       const char *filename, bool is_mask)
      : graphics_(graphics),
        file_manager_(file_manager),
        filename_(filename),
        is_mask_(is_mask),
        canvas_(NULL),
        failed_(false) {
    ASSERT(graphics);
    ASSERT(file_manager);
    ASSERT(filename);
    // canvas_ will be lazy initialized when it is used.
  }

  Impl(const GraphicsInterface *graphics,
       const char *data, size_t data_size, bool is_mask)
      : graphics_(graphics),
        file_manager_(NULL),
        is_mask_(is_mask),
        canvas_(NULL),
        failed_(false) {
    ASSERT(graphics);
    ASSERT(data);
    // TODO: Remove IMG_JPEG.
    canvas_ = is_mask_ ?
              graphics->NewMask(data, data_size) :
              graphics->NewImage(data, data_size);
  }

  Impl(const Impl &another)
      : graphics_(another.graphics_),
        filename_(another.filename_),
        is_mask_(another.is_mask_),
        canvas_(NULL),
        failed_(another.failed_) {
    if (!failed_ && another.canvas_) {
      canvas_ = graphics_->NewCanvas(another.canvas_->GetWidth(),
                                     another.canvas_->GetHeight());
      canvas_->DrawCanvas(0, 0, another.canvas_);
    }
  }

  Impl::~Impl() {
    if (canvas_) {
      canvas_->Destroy();
      canvas_ = NULL;
    }
  }

  const CanvasInterface *GetCanvas() {
    if (!failed_ && !canvas_ && !filename_.empty() && file_manager_) {
      std::string data;
      std::string real_path;
      failed_ = !file_manager_->GetFileContents(filename_.c_str(),
                                                &data, &real_path);
      if (!failed_) {
        canvas_ = is_mask_ ?
                  graphics_->NewMask(data.c_str(), data.size()) :
                  graphics_->NewImage(data.c_str(), data.size());
      }
    }
    return canvas_;
  }

  const GraphicsInterface *graphics_;
  FileManagerInterface *file_manager_;
  std::string filename_;
  bool is_mask_;
  CanvasInterface *canvas_;
  bool failed_;
};

Image::Image(const GraphicsInterface *graphics,
             FileManagerInterface *file_manager,
             const char *filename, bool is_mask)
    : impl_(new Impl(graphics, file_manager, filename, is_mask)) {
}

Image::Image(const GraphicsInterface *graphics,
             const char *data, size_t data_size, bool is_mask)
    : impl_(new Impl(graphics, data, data_size, is_mask)) {
}

Image::Image(const Image &another)
    : impl_(new Impl(*another.impl_)) {
}

const CanvasInterface *Image::GetCanvas() {
  return impl_->GetCanvas();
}

} // namespace ggadget
<commit_msg>Fixed the build break under Debian Lenny.<commit_after>/*
  Copyright 2007 Google Inc.

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

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

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

#include "image.h"
#include "canvas_interface.h"
#include "graphics_interface.h"
#include "file_manager_interface.h"

namespace ggadget {

class Image::Impl {
 public:
  Impl(const GraphicsInterface *graphics,
       FileManagerInterface *file_manager,
       const char *filename, bool is_mask)
      : graphics_(graphics),
        file_manager_(file_manager),
        filename_(filename),
        is_mask_(is_mask),
        canvas_(NULL),
        failed_(false) {
    ASSERT(graphics);
    ASSERT(file_manager);
    ASSERT(filename);
    // canvas_ will be lazy initialized when it is used.
  }

  Impl(const GraphicsInterface *graphics,
       const char *data, size_t data_size, bool is_mask)
      : graphics_(graphics),
        file_manager_(NULL),
        is_mask_(is_mask),
        canvas_(NULL),
        failed_(false) {
    ASSERT(graphics);
    ASSERT(data);
    // TODO: Remove IMG_JPEG.
    canvas_ = is_mask_ ?
              graphics->NewMask(data, data_size) :
              graphics->NewImage(data, data_size);
  }

  Impl(const Impl &another)
      : graphics_(another.graphics_),
        filename_(another.filename_),
        is_mask_(another.is_mask_),
        canvas_(NULL),
        failed_(another.failed_) {
    if (!failed_ && another.canvas_) {
      canvas_ = graphics_->NewCanvas(another.canvas_->GetWidth(),
                                     another.canvas_->GetHeight());
      canvas_->DrawCanvas(0, 0, another.canvas_);
    }
  }

  ~Impl() {
    if (canvas_) {
      canvas_->Destroy();
      canvas_ = NULL;
    }
  }

  const CanvasInterface *GetCanvas() {
    if (!failed_ && !canvas_ && !filename_.empty() && file_manager_) {
      std::string data;
      std::string real_path;
      failed_ = !file_manager_->GetFileContents(filename_.c_str(),
                                                &data, &real_path);
      if (!failed_) {
        canvas_ = is_mask_ ?
                  graphics_->NewMask(data.c_str(), data.size()) :
                  graphics_->NewImage(data.c_str(), data.size());
      }
    }
    return canvas_;
  }

  const GraphicsInterface *graphics_;
  FileManagerInterface *file_manager_;
  std::string filename_;
  bool is_mask_;
  CanvasInterface *canvas_;
  bool failed_;
};

Image::Image(const GraphicsInterface *graphics,
             FileManagerInterface *file_manager,
             const char *filename, bool is_mask)
    : impl_(new Impl(graphics, file_manager, filename, is_mask)) {
}

Image::Image(const GraphicsInterface *graphics,
             const char *data, size_t data_size, bool is_mask)
    : impl_(new Impl(graphics, data, data_size, is_mask)) {
}

Image::Image(const Image &another)
    : impl_(new Impl(*another.impl_)) {
}

const CanvasInterface *Image::GetCanvas() {
  return impl_->GetCanvas();
}

} // namespace ggadget
<|endoftext|>


<commit_before>#ifndef GLHPP_OPENGL_HPP
#define GLHPP_OPENGL_HPP

#include "Exception.hpp"
#include "Formats.hpp"
#include "Object.hpp"
#include "Sync.hpp"
#include "Query.hpp"
#include "Buffer.hpp"
#include "Shader.hpp"
#include "Program.hpp"
#include "ProgramPipeline.hpp"
#include "Texture.hpp"
#include "Sampler.hpp"
#include "Framebuffer.hpp"
#include "Renderbuffer.hpp"
#include "VertexAttrib.hpp"

namespace gl
{

};

#endif
<commit_msg>Fix temporary bug<commit_after>#ifndef GLHPP_OPENGL_HPP
#define GLHPP_OPENGL_HPP

#include "Exception.hpp"
#include "Formats.hpp"
#include "Object.hpp"
#include "Sync.hpp"
#include "Query.hpp"
#include "Buffer.hpp"
#include "Shader.hpp"
#include "Program.hpp"
#include "ProgramPipeline.hpp"
#include "Texture.hpp"
#include "Sampler.hpp"
#include "Framebuffer.hpp"
#include "Renderbuffer.hpp"
//#include "VertexAttrib.hpp"

namespace gl
{

};

#endif
<|endoftext|>


<commit_before>/* Max Flow Problem, by Abreto<m@abreto.net> */

#define MAXV    (100000)
#define MAXE    (1000000)
struct edge
{
    static int N;
    int v, w;
    edge *n;
    edge(void):v(0),w(0),n(NULL){}
    edge(int vv, int ww, edge *nn):v(vv),w(ww),n(nn){}
};
int nE;
edge E[MAXE];
edge *front[MAXV];
void add_edge(int u, int v, int w)
{
    int ne = ++nE;
    E[ne] = edge(v, w, u[front]);
    u[front] = &(E[ne]);
}
edge *find_edge(int u, int v)
{
    for(edge *e = u[front];e != NULL;e = e->n)
        if(e->v == v)
            return e;
    return NULL;
}
void grant_e(int u, int v, int w)
{
    edge *e = find_edge(u, v);
    if(NULL == e) add_edge(u,v,w);
    else e->w += w;
}

int vis[MAXV];
int path[MAXV];
int dfs(int u, int t)
{
    vis[u] = 1;
    if(u == t) return 1;
    for(edge *e = u[front];e != NULL;e = e->n)
    {
        int v = e->v;
        if(!vis[v] && e->w && dfs(v,t))
        {
            path[u] = v;
            return 1;
        }
    }
    return 0;
}
int find_path(int s, int t)
{
    memset(vis, 0, sizeof(vis));
    return dfs(s,t);
}
int max_flow(int s, int t)
{
    int flow = 0;
    while(find_path(s,t))
    {
        int i = 0;
        int minf = find_edge(s,path[s])->w;
        for(i = path[s];i != t;i = path[i])
            minf = min(minf, find_edge(i,path[i])->w);
        for(i = s;i != t;i = path[i])
        {
            grant_e(i, path[i], -minf);
            grant_e(path[i], i, minf);
        }
        flow += minf;
    }
    return flow;
}
<commit_msg>maxflow Dinic<commit_after>/* Max Flow Problem, by Abreto<m@abreto.net> */

#define MAXV    (100000)
#define MAXE    (1000000)
struct edge
{
    static int N;
    int v, w;
    edge *n;
    edge(void):v(0),w(0),n(NULL){}
    edge(int vv, int ww, edge *nn):v(vv),w(ww),n(nn){}
};
int nE;
edge E[MAXE];
edge *front[MAXV];
void add_edge(int u, int v, int w)
{
    int ne = ++nE;
    E[ne] = edge(v, w, u[front]);
    u[front] = &(E[ne]);
}
edge *find_edge(int u, int v)
{
    for(edge *e = u[front];e != NULL;e = e->n)
        if(e->v == v)
            return e;
    return NULL;
}
void grant_e(int u, int v, int w)
{
    edge *e = find_edge(u, v);
    if(NULL == e) add_edge(u,v,w);
    else e->w += w;
}

int vis[MAXV];
int path[MAXV];
int dfs(int u, int t)
{
    vis[u] = 1;
    if(u == t) return 1;
    for(edge *e = u[front];e != NULL;e = e->n)
    {
        int v = e->v;
        if(!vis[v] && e->w && dfs(v,t))
        {
            path[u] = v;
            return 1;
        }
    }
    return 0;
}
int find_path(int s, int t)
{
    memset(vis, 0, sizeof(vis));
    return dfs(s,t);
}
int max_flow(int s, int t)
{
    int flow = 0;
    while(find_path(s,t))
    {
        int i = 0;
        int minf = find_edge(s,path[s])->w;
        for(i = path[s];i != t;i = path[i])
            minf = min(minf, find_edge(i,path[i])->w);
        for(i = s;i != t;i = path[i])
        {
            grant_e(i, path[i], -minf);
            grant_e(path[i], i, minf);
        }
        flow += minf;
    }
    return flow;
}

/* Dinic */
#define N 1000
#define INF 100000000

struct Edge
{
    int from,to,cap,flow;
    Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
};

struct Dinic
{
    int n,m,s,t;//结点数，边数（包括反向弧），源点编号，汇点编号
    vector<Edge>edges;//边表，dges[e]和dges[e^1]互为反向弧
    vector<int>G[N];//邻接表，G[i][j]表示结点i的第j条边在e数组中的编号
    bool vis[N]; //BFS的使用
    int d[N]; //从起点到i的距离
    int cur[N]; //当前弧下标

    void addedge(int from,int to,int cap)
    {
        edges.push_back(Edge(from,to,cap,0));
        edges.push_back(Edge(to,from,0,0));
        int  m=edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }

    bool bfs()
    {
        memset(vis,0,sizeof(vis));
        queue<int>Q;
        Q.push(s);
        d[s]=0;
        vis[s]=1;
        while(!Q.empty())
        {
            int x=Q.front();Q.pop();
            for(int i=0;i<G[x].size();i++)
            {
                Edge&e=edges[G[x][i]];
                if(!vis[e.to]&&e.cap>e.flow)//只考虑残量网络中的弧
                {
                    vis[e.to]=1;
                    d[e.to]=d[x]+1;
                    Q.push(e.to);
                }
            }

        }
        return vis[t];
    }

    int dfs(int x,int a)//x表示当前结点，a表示目前为止的最小残量
    {
        if(x==t||a==0)return a;//a等于0时及时退出，此时相当于断路了
        int flow=0,f;
        for(int&i=cur[x];i<G[x].size();i++)//从上次考虑的弧开始，注意要使用引用，同时修改cur[x]
        {
            Edge&e=edges[G[x][i]];//e是一条边
            if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0)
            {
                e.flow+=f;
                edges[G[x][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if(!a)break;//a等于0及时退出，当a!=0,说明当前节点还存在另一个曾广路分支。

            }
        }
        return flow;
    }

    int Maxflow(int s,int t)//主过程
    {
        this->s=s,this->t=t;
        int flow=0;
        while(bfs())//不停地用bfs构造分层网络，然后用dfs沿着阻塞流增广
        {
            memset(cur,0,sizeof(cur));
            flow+=dfs(s,INF);
        }
        return flow;
    }
};

/* ISAP */
<|endoftext|>


<commit_before>// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/vespalib/util/stringfmt.h>

#include <vespa/eval/tensor/default_tensor_engine.h>
#include <vespa/eval/tensor/dense/dense_tensor.h>
#include <vespa/eval/tensor/tensor.h>
#include <vespa/searchlib/common/feature.h>
#include <vespa/searchlib/fef/matchdata.h>
#include <vespa/searchlib/queryeval/nearest_neighbor_iterator.h>
#include <vespa/searchlib/queryeval/simpleresult.h>
#include <vespa/searchlib/tensor/dense_tensor_attribute.h>
#include <vespa/vespalib/test/insertion_operators.h>

#include <vespa/log/log.h>
LOG_SETUP("nearest_neighbor_test");

using search::feature_t;
using search::tensor::DenseTensorAttribute;
using search::AttributeVector;
using vespalib::eval::ValueType;
using vespalib::eval::TensorSpec;
using vespalib::tensor::Tensor;
using vespalib::tensor::DenseTensorView;
using vespalib::tensor::DefaultTensorEngine;

using namespace search::fef;
using namespace search::queryeval;

vespalib::string denseSpec("tensor(x[2])");

std::unique_ptr<DenseTensorView> createTensor(const TensorSpec &spec) {
    auto value = DefaultTensorEngine::ref().from_spec(spec);
    DenseTensorView *tensor = dynamic_cast<DenseTensorView*>(value.get());
    ASSERT_TRUE(tensor != nullptr);
    value.release();
    return std::unique_ptr<DenseTensorView>(tensor);
}

struct Fixture
{
    using BasicType = search::attribute::BasicType;
    using CollectionType = search::attribute::CollectionType;
    using Config = search::attribute::Config;

    Config _cfg;
    vespalib::string _name;
    vespalib::string _typeSpec;
    std::shared_ptr<DenseTensorAttribute> _tensorAttr;
    std::shared_ptr<AttributeVector> _attr;

    Fixture(const vespalib::string &typeSpec)
        : _cfg(BasicType::TENSOR, CollectionType::SINGLE),
          _name("test"),
          _typeSpec(typeSpec),
          _tensorAttr(),
          _attr()
    {
        _cfg.setTensorType(ValueType::from_spec(typeSpec));
        _tensorAttr = makeAttr();
        _attr = _tensorAttr;
        _attr->addReservedDoc();
    }

    ~Fixture() {}

    std::shared_ptr<DenseTensorAttribute> makeAttr() {
        return std::make_shared<DenseTensorAttribute>(_name, _cfg);
    }

    void ensureSpace(uint32_t docId) {
        while (_attr->getNumDocs() <= docId) {
            uint32_t newDocId = 0u;
            _attr->addDoc(newDocId);
            _attr->commit();
        }
    }

    void setTensor(uint32_t docId, const Tensor &tensor) {
        ensureSpace(docId);
        _tensorAttr->setTensor(docId, tensor);
        _attr->commit();
    }

    void setTensor(uint32_t docId, double v1, double v2) {
        auto t = createTensor(TensorSpec(denseSpec)
                              .add({{"x", 0}}, v1)
                              .add({{"x", 1}}, v2));
        setTensor(docId, *t);
    }
};

template <bool strict>
SimpleResult find_matches(Fixture &env) {
    auto md = MatchData::makeTestInstance(2, 2);
    auto qt = createTensor(TensorSpec(denseSpec));

    auto &tfmd = *(md->resolveTermField(0));
    const DenseTensorView &qtv = *qt;
    auto &attr = *(env._tensorAttr);

    NearestNeighborDistanceHeap dh(2);
    auto search = NearestNeighborIteratorFactory::createIterator(strict, tfmd, qtv, attr, dh);
    if (strict) {
        return SimpleResult().searchStrict(*search, attr.getNumDocs());
    } else {
        return SimpleResult().search(*search, attr.getNumDocs());
    }
}

TEST("require that NearestNeighborIterator returns expected results") {
    Fixture fixture(denseSpec);
    fixture.ensureSpace(6);
    fixture.setTensor(1, 3.0, 4.0);
    fixture.setTensor(2, 6.0, 8.0);
    fixture.setTensor(3, 5.0, 12.0);
    fixture.setTensor(4, 4.0, 3.0);
    fixture.setTensor(5, 8.0, 6.0);
    fixture.setTensor(6, 4.0, 3.0);
    SimpleResult result = find_matches<true>(fixture);
    SimpleResult expect({1,2,4,6});
    EXPECT_EQUAL(result, expect);
    result = find_matches<false>(fixture);
    EXPECT_EQUAL(result, expect);
}

template <bool strict>
std::vector<feature_t> get_rawscores(Fixture &env) {
    auto md = MatchData::makeTestInstance(2, 2);
    auto qt = createTensor(TensorSpec(denseSpec));
    auto &tfmd = *(md->resolveTermField(0));
    const DenseTensorView &qtv = *qt;
    auto &attr = *(env._tensorAttr);
    NearestNeighborDistanceHeap dh(2);
    auto search = NearestNeighborIteratorFactory::createIterator(strict, tfmd, qtv, attr, dh);
    uint32_t limit = attr.getNumDocs();
    uint32_t docid = 1;
    search->initRange(docid, limit);
    std::vector<feature_t> rv;
    while (docid < limit) {
        if (strict) {
            search->seek(docid);
            if (search->isAtEnd()) break;
            docid = search->getDocId();
            search->unpack(docid);
            rv.push_back(tfmd.getRawScore());
        } else {
            if (search->seek(docid)) {
                search->unpack(docid);
                rv.push_back(tfmd.getRawScore());
            }
        }
        ++docid;
    }
    return rv;
}

TEST("require that NearestNeighborIterator sets expected rawscore") {
    Fixture fixture(denseSpec);
    fixture.ensureSpace(6);
    fixture.setTensor(1, 3.0, 4.0);
    fixture.setTensor(2, 5.0, 12.0);
    fixture.setTensor(3, 6.0, 8.0);
    fixture.setTensor(4, 5.0, 12.0);
    fixture.setTensor(5, 8.0, 6.0);
    fixture.setTensor(6, 4.0, 3.0);
    std::vector<feature_t> got = get_rawscores<true>(fixture);
    std::vector<feature_t> expected{5.0, 13.0, 10.0, 10.0, 5.0};
    EXPECT_EQUAL(got, expected);
    got = get_rawscores<false>(fixture);
    EXPECT_EQUAL(got, expected);
}

TEST_MAIN() { TEST_RUN_ALL(); }
<commit_msg>refactor and check with non-null tensor<commit_after>// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/vespalib/util/stringfmt.h>

#include <vespa/eval/tensor/default_tensor_engine.h>
#include <vespa/eval/tensor/dense/dense_tensor.h>
#include <vespa/eval/tensor/tensor.h>
#include <vespa/searchlib/common/feature.h>
#include <vespa/searchlib/fef/matchdata.h>
#include <vespa/searchlib/queryeval/nearest_neighbor_iterator.h>
#include <vespa/searchlib/queryeval/simpleresult.h>
#include <vespa/searchlib/tensor/dense_tensor_attribute.h>
#include <vespa/vespalib/test/insertion_operators.h>

#include <vespa/log/log.h>
LOG_SETUP("nearest_neighbor_test");

using search::feature_t;
using search::tensor::DenseTensorAttribute;
using search::AttributeVector;
using vespalib::eval::ValueType;
using vespalib::eval::TensorSpec;
using vespalib::tensor::Tensor;
using vespalib::tensor::DenseTensorView;
using vespalib::tensor::DefaultTensorEngine;

using namespace search::fef;
using namespace search::queryeval;

vespalib::string denseSpec("tensor(x[2])");

std::unique_ptr<DenseTensorView> createTensor(const TensorSpec &spec) {
    auto value = DefaultTensorEngine::ref().from_spec(spec);
    DenseTensorView *tensor = dynamic_cast<DenseTensorView*>(value.get());
    ASSERT_TRUE(tensor != nullptr);
    value.release();
    return std::unique_ptr<DenseTensorView>(tensor);
}

std::unique_ptr<DenseTensorView> createTensor(double v1, double v2) {
    return createTensor(TensorSpec(denseSpec).add({{"x", 0}}, v1)
                                             .add({{"x", 1}}, v2));
}

struct Fixture
{
    using BasicType = search::attribute::BasicType;
    using CollectionType = search::attribute::CollectionType;
    using Config = search::attribute::Config;

    Config _cfg;
    vespalib::string _name;
    vespalib::string _typeSpec;
    std::shared_ptr<DenseTensorAttribute> _tensorAttr;
    std::shared_ptr<AttributeVector> _attr;

    Fixture(const vespalib::string &typeSpec)
        : _cfg(BasicType::TENSOR, CollectionType::SINGLE),
          _name("test"),
          _typeSpec(typeSpec),
          _tensorAttr(),
          _attr()
    {
        _cfg.setTensorType(ValueType::from_spec(typeSpec));
        _tensorAttr = makeAttr();
        _attr = _tensorAttr;
        _attr->addReservedDoc();
    }

    ~Fixture() {}

    std::shared_ptr<DenseTensorAttribute> makeAttr() {
        return std::make_shared<DenseTensorAttribute>(_name, _cfg);
    }

    void ensureSpace(uint32_t docId) {
        while (_attr->getNumDocs() <= docId) {
            uint32_t newDocId = 0u;
            _attr->addDoc(newDocId);
            _attr->commit();
        }
    }

    void setTensor(uint32_t docId, const Tensor &tensor) {
        ensureSpace(docId);
        _tensorAttr->setTensor(docId, tensor);
        _attr->commit();
    }

    void setTensor(uint32_t docId, double v1, double v2) {
        auto t = createTensor(v1, v2);
        setTensor(docId, *t);
    }
};

template <bool strict>
SimpleResult find_matches(Fixture &env, const DenseTensorView &qtv) {
    auto md = MatchData::makeTestInstance(2, 2);
    auto &tfmd = *(md->resolveTermField(0));
    auto &attr = *(env._tensorAttr);
    NearestNeighborDistanceHeap dh(2);
    auto search = NearestNeighborIteratorFactory::createIterator(strict, tfmd, qtv, attr, dh);
    if (strict) {
        return SimpleResult().searchStrict(*search, attr.getNumDocs());
    } else {
        return SimpleResult().search(*search, attr.getNumDocs());
    }
}

TEST("require that NearestNeighborIterator returns expected results") {
    Fixture fixture(denseSpec);
    fixture.ensureSpace(6);
    fixture.setTensor(1, 3.0, 4.0);
    fixture.setTensor(2, 6.0, 8.0);
    fixture.setTensor(3, 5.0, 12.0);
    fixture.setTensor(4, 4.0, 3.0);
    fixture.setTensor(5, 8.0, 6.0);
    fixture.setTensor(6, 4.0, 3.0);
    auto nullTensor = createTensor(0.0, 0.0);
    SimpleResult result = find_matches<true>(fixture, *nullTensor);
    SimpleResult nullExpect({1,2,4,6});
    EXPECT_EQUAL(result, nullExpect);
    result = find_matches<false>(fixture, *nullTensor);
    EXPECT_EQUAL(result, nullExpect);
    auto farTensor = createTensor(9.0, 9.0);
    SimpleResult farExpect({1,2,3,5});
    result = find_matches<true>(fixture, *farTensor);
    EXPECT_EQUAL(result, farExpect);
    result = find_matches<false>(fixture, *farTensor);
    EXPECT_EQUAL(result, farExpect);
}

template <bool strict>
std::vector<feature_t> get_rawscores(Fixture &env, const DenseTensorView &qtv) {
    auto md = MatchData::makeTestInstance(2, 2);
    auto &tfmd = *(md->resolveTermField(0));
    auto &attr = *(env._tensorAttr);
    NearestNeighborDistanceHeap dh(2);
    auto search = NearestNeighborIteratorFactory::createIterator(strict, tfmd, qtv, attr, dh);
    uint32_t limit = attr.getNumDocs();
    uint32_t docid = 1;
    search->initRange(docid, limit);
    std::vector<feature_t> rv;
    while (docid < limit) {
        if (strict) {
            search->seek(docid);
            if (search->isAtEnd()) break;
            docid = search->getDocId();
            search->unpack(docid);
            rv.push_back(tfmd.getRawScore());
        } else {
            if (search->seek(docid)) {
                search->unpack(docid);
                rv.push_back(tfmd.getRawScore());
            }
        }
        ++docid;
    }
    return rv;
}

TEST("require that NearestNeighborIterator sets expected rawscore") {
    Fixture fixture(denseSpec);
    fixture.ensureSpace(6);
    fixture.setTensor(1, 3.0, 4.0);
    fixture.setTensor(2, 5.0, 12.0);
    fixture.setTensor(3, 6.0, 8.0);
    fixture.setTensor(4, 5.0, 12.0);
    fixture.setTensor(5, 8.0, 6.0);
    fixture.setTensor(6, 4.0, 3.0);
    auto nullTensor = createTensor(0.0, 0.0);
    std::vector<feature_t> got = get_rawscores<true>(fixture, *nullTensor);
    std::vector<feature_t> expected{5.0, 13.0, 10.0, 10.0, 5.0};
    EXPECT_EQUAL(got, expected);
    got = get_rawscores<false>(fixture, *nullTensor);
    EXPECT_EQUAL(got, expected);
}

TEST_MAIN() { TEST_RUN_ALL(); }
<|endoftext|>


<commit_before><commit_msg>fix mem leak; fixes #3<commit_after><|endoftext|>


<commit_before>
#include <iostream>

#ifdef __cplusplus
extern "C"
{
#endif

int xerbla_(const char * msg, int *info, int)
{
  std::cerr << "Eigen BLAS ERROR #" << *info << ": " << msg << "\n";
  return 0;
}

#ifdef __cplusplus
}
#endif
<commit_msg>enforce weak linking of xerbla<commit_after>
#include <iostream>

#if (defined __GNUC__)
#define EIGEN_WEAK_LINKING __attribute__ ((weak))
#else
#define EIGEN_WEAK_LINKING
#endif

#ifdef __cplusplus
extern "C"
{
#endif

EIGEN_WEAK_LINKING int xerbla_(const char * msg, int *info, int)
{
  std::cerr << "Eigen BLAS ERROR #" << *info << ": " << msg << "\n";
  return 0;
}

#ifdef __cplusplus
}
#endif
<|endoftext|>


<commit_before>#include "StdAfx.h"
#include "CameraMetaData.h"
/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2014 Klaus Post

    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 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 Street, Fifth Floor, Boston, MA 02110-1301 USA

    http://www.klauspost.com
*/

namespace RawSpeed {

CameraMetaData::CameraMetaData() {
}

CameraMetaData::CameraMetaData(const char *docname) {
  xml_document doc;
  xml_parse_result result = doc.load_file(docname);

  if (!result) {
    ThrowCME("CameraMetaData: XML Document could not be parsed successfully. Error was: %s in %s",
      result.description(), doc.child("node").attribute("attr").value());
  }
  xml_node cameras = doc.child("Cameras");

  for (xml_node camera = cameras.child("Camera"); camera; camera = camera.next_sibling("Camera")) {
    Camera *cam = new Camera(camera);

    if(!addCamera(cam)) continue;

    // Create cameras for aliases.
    for (uint32 i = 0; i < cam->aliases.size(); i++) {
      addCamera(new Camera(cam, i));
    }
  }
}

CameraMetaData::~CameraMetaData(void) {
  map<string, Camera*>::iterator i = cameras.begin();
  for (; i != cameras.end(); ++i) {
    delete((*i).second);
  }
}

Camera* CameraMetaData::getCamera(string make, string model, string mode) {
  string id = string(make).append(model).append(mode);
  if (cameras.end() == cameras.find(id))
    return NULL;
  return cameras[id];
}

bool CameraMetaData::hasCamera(string make, string model, string mode) {
  string id = string(make).append(model).append(mode);
  if (cameras.end() == cameras.find(id))
    return FALSE;
  return TRUE;
}

Camera* CameraMetaData::getChdkCamera(uint32 filesize) {
  if (chdkCameras.end() == chdkCameras.find(filesize))
    return NULL;
  return chdkCameras[filesize];
}

bool CameraMetaData::hasChdkCamera(uint32 filesize) {
  return chdkCameras.end() != chdkCameras.find(filesize);
}

bool CameraMetaData::addCamera( Camera* cam )
{
  string id = string(cam->make).append(cam->model).append(cam->mode);
  if (cameras.end() != cameras.find(id)) {
    writeLog(DEBUG_PRIO_WARNING, "CameraMetaData: Duplicate entry found for camera: %s %s, Skipping!\n", cam->make.c_str(), cam->model.c_str());
    delete(cam);
    return false;
  } else {
    cameras[id] = cam;
  }
  if (string::npos != cam->mode.find("chdk")) {
    if (cam->hints.find("filesize") == cam->hints.end()) {
      writeLog(DEBUG_PRIO_WARNING, "CameraMetaData: CHDK camera: %s %s, no \"filesize\" hint set!\n", cam->make.c_str(), cam->model.c_str());
    } else {
      uint32 size;
      stringstream fsize(cam->hints.find("filesize")->second);
      fsize >> size;
      chdkCameras[size] = cam;
      // writeLog(DEBUG_PRIO_WARNING, "CHDK camera: %s %s size:%u\n", cam->make.c_str(), cam->model.c_str(), size);
    }
  }
  return true;
}

void CameraMetaData::disableMake( string make )
{
  map<string, Camera*>::iterator i = cameras.begin();
  for (; i != cameras.end(); ++i) {
    Camera* cam = (*i).second;
    if (0 == cam->make.compare(make)) {
      cam->supported = FALSE;
    }
  }
}

void CameraMetaData::disableCamera( string make, string model )
{
  map<string, Camera*>::iterator i = cameras.begin();
  for (; i != cameras.end(); ++i) {
    Camera* cam = (*i).second;
    if (0 == cam->make.compare(make) && 0 == cam->model.compare(model)) {
      cam->supported = FALSE;
    }
  }
}

} // namespace RawSpeed
<commit_msg>CameraMetaData(): properly compute "id"<commit_after>#include "StdAfx.h"
#include "CameraMetaData.h"
/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2014 Klaus Post

    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 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 Street, Fifth Floor, Boston, MA 02110-1301 USA

    http://www.klauspost.com
*/

namespace RawSpeed {

CameraMetaData::CameraMetaData() {
}

CameraMetaData::CameraMetaData(const char *docname) {
  xml_document doc;
  xml_parse_result result = doc.load_file(docname);

  if (!result) {
    ThrowCME("CameraMetaData: XML Document could not be parsed successfully. Error was: %s in %s",
      result.description(), doc.child("node").attribute("attr").value());
  }
  xml_node cameras = doc.child("Cameras");

  for (xml_node camera = cameras.child("Camera"); camera; camera = camera.next_sibling("Camera")) {
    Camera *cam = new Camera(camera);

    if(!addCamera(cam)) continue;

    // Create cameras for aliases.
    for (uint32 i = 0; i < cam->aliases.size(); i++) {
      addCamera(new Camera(cam, i));
    }
  }
}

CameraMetaData::~CameraMetaData(void) {
  map<string, Camera*>::iterator i = cameras.begin();
  for (; i != cameras.end(); ++i) {
    delete((*i).second);
  }
}

static inline string getId(string make, string model, string mode)
{
  TrimSpaces(make);
  TrimSpaces(model);
  TrimSpaces(mode);

  return string(make).append(model).append(mode);
}

static inline string getId(Camera* cam)
{
  return getId(cam->make, cam->model, cam->mode);
}

Camera* CameraMetaData::getCamera(string make, string model, string mode) {
  string id = getId(make, model, mode);
  if (cameras.end() == cameras.find(id))
    return NULL;
  return cameras[id];
}

bool CameraMetaData::hasCamera(string make, string model, string mode) {
  string id = getId(make, model, mode);
  if (cameras.end() == cameras.find(id))
    return FALSE;
  return TRUE;
}

Camera* CameraMetaData::getChdkCamera(uint32 filesize) {
  if (chdkCameras.end() == chdkCameras.find(filesize))
    return NULL;
  return chdkCameras[filesize];
}

bool CameraMetaData::hasChdkCamera(uint32 filesize) {
  return chdkCameras.end() != chdkCameras.find(filesize);
}

bool CameraMetaData::addCamera( Camera* cam )
{
  string id = getId(cam);
  if (cameras.end() != cameras.find(id)) {
    writeLog(DEBUG_PRIO_WARNING, "CameraMetaData: Duplicate entry found for camera: %s %s, Skipping!\n", cam->make.c_str(), cam->model.c_str());
    delete(cam);
    return false;
  } else {
    cameras[id] = cam;
  }
  if (string::npos != cam->mode.find("chdk")) {
    if (cam->hints.find("filesize") == cam->hints.end()) {
      writeLog(DEBUG_PRIO_WARNING, "CameraMetaData: CHDK camera: %s %s, no \"filesize\" hint set!\n", cam->make.c_str(), cam->model.c_str());
    } else {
      uint32 size;
      stringstream fsize(cam->hints.find("filesize")->second);
      fsize >> size;
      chdkCameras[size] = cam;
      // writeLog(DEBUG_PRIO_WARNING, "CHDK camera: %s %s size:%u\n", cam->make.c_str(), cam->model.c_str(), size);
    }
  }
  return true;
}

void CameraMetaData::disableMake( string make )
{
  map<string, Camera*>::iterator i = cameras.begin();
  for (; i != cameras.end(); ++i) {
    Camera* cam = (*i).second;
    if (0 == cam->make.compare(make)) {
      cam->supported = FALSE;
    }
  }
}

void CameraMetaData::disableCamera( string make, string model )
{
  map<string, Camera*>::iterator i = cameras.begin();
  for (; i != cameras.end(); ++i) {
    Camera* cam = (*i).second;
    if (0 == cam->make.compare(make) && 0 == cam->model.compare(model)) {
      cam->supported = FALSE;
    }
  }
}

} // namespace RawSpeed
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2013-2014.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <types.hpp>
#include <unique_ptr.hpp>
#include <algorithms.hpp>
#include <errors.hpp>

#include "fs/sysfs.hpp"

#include "console.hpp"
#include "rtc.hpp"

namespace {

struct sys_value {
    std::string name;
    std::string value;
};

struct sys_folder {
    std::string name;
    std::vector<sys_folder> folders;
    std::vector<sys_value> values;
};

std::vector<sys_folder> root_folders;

} //end of anonymous namespace

sysfs::sysfs_file_system::sysfs_file_system(std::string mp) : mount_point(mp) {
    //Nothing to init
}

sysfs::sysfs_file_system::~sysfs_file_system(){
    //Nothing to delete
}

size_t sysfs::sysfs_file_system::get_file(const std::vector<std::string>& file_path, vfs::file& file){
    //TODO
    return std::ERROR_NOT_EXISTS;
}

size_t sysfs::sysfs_file_system::read(const std::vector<std::string>& file_path, std::string& content){
    //TODO
    return 0;
}

size_t sysfs::sysfs_file_system::ls(const std::vector<std::string>& file_path, std::vector<vfs::file>& contents){
    //TODO
    return 0;
}

size_t sysfs::sysfs_file_system::touch(const std::vector<std::string>& file_path){
    return std::ERROR_PERMISSION_DENIED;
}

size_t sysfs::sysfs_file_system::mkdir(const std::vector<std::string>& file_path){
    return std::ERROR_PERMISSION_DENIED;
}

size_t sysfs::sysfs_file_system::rm(const std::vector<std::string>& file_path){
    return std::ERROR_PERMISSION_DENIED;
}

size_t sysfs::sysfs_file_system::statfs(statfs_info& file){
    file.total_size = 0;
    file.free_size = 0;

    return 0;
}

void set_value(const std::string& mount_point, const std::string& path, const std::string& value){
    //TODO
}

void delete_value(const std::string& mount_point, const std::string& path){
    //TODO
}
<commit_msg>Add a way for the system to set values<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2013-2014.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <types.hpp>
#include <unique_ptr.hpp>
#include <algorithms.hpp>
#include <errors.hpp>

#include "fs/sysfs.hpp"

#include "console.hpp"
#include "rtc.hpp"

namespace {

struct sys_value {
    std::string name;
    std::string value;

    sys_value(){}
    sys_value(std::string name, std::string value) : name(name), value(value){
        //Nothing else to init
    }
};

struct sys_folder {
    std::string name;
    std::vector<sys_folder> folders;
    std::vector<sys_value> values;

    sys_folder(){}

    sys_folder(std::string name) : name(name) {
        //Nothing else to init
    }
};

std::vector<sys_folder> root_folders;

sys_folder& find_root_folder(const std::string& mount_point){
    for(auto& sys_folder : root_folders){
        if(sys_folder.name == mount_point){
            return sys_folder;
        }
    }

    root_folders.emplace_back(mount_point);

    return root_folders.back();
}

sys_folder& find_folder(sys_folder& root, const std::vector<std::string>& path, size_t i = 0){
    auto& name = path[i];

    for(auto& folder : root.folders){
        if(folder.name == name){
            if(i == path.size() - 1){
                return folder;
            } else {
                return find_folder(folder, path, i + 1);
            }
        }
    }

    root.folders.emplace_back(name);

    if(i == path.size() - 1){
        return root.folders.back();
    } else {
        return find_folder(root.folders.back(), path, i + 1);
    }
}

} //end of anonymous namespace

sysfs::sysfs_file_system::sysfs_file_system(std::string mp) : mount_point(mp) {
    //Nothing to init
}

sysfs::sysfs_file_system::~sysfs_file_system(){
    //Nothing to delete
}

size_t sysfs::sysfs_file_system::get_file(const std::vector<std::string>& file_path, vfs::file& file){
    //TODO
    return std::ERROR_NOT_EXISTS;
}

size_t sysfs::sysfs_file_system::read(const std::vector<std::string>& file_path, std::string& content){
    //TODO
    return 0;
}

size_t sysfs::sysfs_file_system::ls(const std::vector<std::string>& file_path, std::vector<vfs::file>& contents){
    //TODO
    return 0;
}

size_t sysfs::sysfs_file_system::touch(const std::vector<std::string>& ){
    return std::ERROR_PERMISSION_DENIED;
}

size_t sysfs::sysfs_file_system::mkdir(const std::vector<std::string>& ){
    return std::ERROR_PERMISSION_DENIED;
}

size_t sysfs::sysfs_file_system::rm(const std::vector<std::string>& ){
    return std::ERROR_PERMISSION_DENIED;
}

size_t sysfs::sysfs_file_system::statfs(statfs_info& file){
    file.total_size = 0;
    file.free_size = 0;

    return 0;
}

void set_value(const std::string& mount_point, const std::string& path, const std::string& value){
    auto& root_folder = find_root_folder(mount_point);

    auto file_path = std::split(path, '/');
    auto last = file_path.back();
    file_path.pop_back();

    auto& folder = find_folder(root_folder, file_path);

    for(auto& v : folder.values){
        if(v.name == last){
            v.value = value;
            return;
        }
    }

    folder.values.emplace_back(last, value);
}

void delete_value(const std::string& mount_point, const std::string& path){
    //TODO
}
<|endoftext|>


<commit_before>// <insert copyright>

/*! \mainpage CAMP C++ library documentation
 *
 * \image html logo_camp.png
 *
 * \section overview Overview
 *
 * CAMP is a C++ library which provides runtime reflection for types.
 * It provides an abstraction for most of the high-level concepts of C++:
 *
 * \li Classes
 * \li Enumerations
 * \li Properties
 * \li Functions
 * \li Objects
 * \li Variables
 *
 * By wrapping all these concepts into abstract structures, CAMP provides an extra layer of
 * flexibility to programs, and allow them to fully expose their data structures at runtime.
 *
 * Many applications can take advantage of CAMP, in order to automate tasks which would
 * otherwise require a huge amount of work. For example, CAMP can be used to expose and edit
 * objects' attributes into a graphical user interface. It can also be used to do
 * automatic binding of C++ classes to script languages such as Python or Lua.
 * Another possible application would be the serialization of objects to XML, text or
 * binary formats. Or you can even combine all these examples to provide a powerful
 * and consistent interface for manipulating your objects outside C++ code.
 *
 * \section example Quick example
 *
 * Here is a simple example of how to use CAMP:
 *
 * \code
 * #include <camp/camptype.hpp>
 * #include <camp/class.hpp>
 * #include <string>
 * #include <iostream>
 *
 * // Let's define a class for handling persons
 * class Person
 * {
 * public:
 *
 *     // Construct a person from its name
 *     Person(const std::string& name) : m_name(name), m_age(0)
 *     {
 *     }
 *
 *     // Retrieve the name of a person
 *     std::string name() const
 *     {
 *         return m_name;
 *     }
 *
 *     // Retrieve the age of a person
 *     unsigned int age() const
 *     {
 *         return m_age;
 *     }
 *
 *     // Set the age of a person
 *     void setAge(unsigned int age)
 *    {
 *         m_age = age;
 *     }
 *
 *     // Make a person speak (tell about its name and age)
 *     void speak()
 *     {
 *         std::cout << "Hi! My name is " << m_name << " and I'm " << m_age << " years old." << std::endl;
 *     }
 *
 * private:
 *
 *     std::string m_name;
 *     unsigned int m_age;
 * };
 *
 * // Make the Person type available to CAMP
 * CAMP_TYPE(Person);
 *
 *
 * int main()
 * {
 *     // Bind our Person class to CAMP
 *     camp::Class::declare<Person>("Person")
 *         .constructor1<std::string>()
 *         .property("name", &Person::name)
 *         .property("age", &Person::age, &Person::setAge)
 *         .function("speak", &Person::speak);
 *
 *     // Retrieve it by its name
 *     const camp::Class& metaclass = camp::classByName("Person");
 *
 *     // Construct a new person named John
 *     Person* john = metaclass.construct<Person>(camp::Args("John"));
 *
 *     // Print its name
 *     std::string name = metaclass.property("name").get(john);
 *     std::cout << "John's name is: " << name << std::endl;
 *
 *     // Set its age to 24
 *     metaclass.property("age").set(john, 24);
 *
 *     // Make John say something
 *     metaclass.function("speak").call(john);
 *
 *     // Kill John
 *     metaclass.destroy(john);
 *
 *     return 0;
 * }
 * \endcode
 *
 * \section licence Licence
 *
 * CAMP is distributed under the terms of the GPL v3 licence:
 *
 * \verbatim
 *   CAMP - dynamic reflexion C++ library
 *   Copyright (C) 2009 TechnoGerma Systems France
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * \endverbatim
 *
 * \section contact Contact
 *
 * Blah blah Tegesoft...
 *
 */
<commit_msg>Updated API documentation<commit_after>// <insert copyright>

/*! \mainpage CAMP C++ library documentation
 *
 * \image html logo_camp.png
 *
 * \section overview Overview
 *
 * CAMP is a C++ library which provides runtime reflection for types.
 * It provides an abstraction for most of the high-level concepts of C++:
 *
 * \li Classes
 * \li Enumerations
 * \li Properties
 * \li Functions
 * \li Objects
 * \li Variables
 *
 * By wrapping all these concepts into abstract structures, CAMP provides an extra layer of
 * flexibility to programs, and allow them to fully expose their data structures at runtime.
 *
 * Many applications can take advantage of CAMP, in order to automate tasks which would
 * otherwise require a huge amount of work. For example, CAMP can be used to expose and edit
 * objects' attributes into a graphical user interface. It can also be used to do
 * automatic binding of C++ classes to script languages such as Python or Lua.
 * Another possible application would be the serialization of objects to XML, text or
 * binary formats. Or you can even combine all these examples to provide a powerful
 * and consistent interface for manipulating your objects outside C++ code.
 *
 * \section example Quick example
 *
 * Here is a simple example of how to use CAMP:
 *
 * \code
 * #include <camp/camptype.hpp>
 * #include <camp/class.hpp>
 * #include <string>
 * #include <iostream>
 *
 * // Let's define a class for handling persons
 * class Person
 * {
 * public:
 *
 *     // Construct a person from its name
 *     Person(const std::string& name) : m_name(name), m_age(0)
 *     {
 *     }
 *
 *     // Retrieve the name of a person
 *     std::string name() const
 *     {
 *         return m_name;
 *     }
 *
 *     // Retrieve the age of a person
 *     unsigned int age() const
 *     {
 *         return m_age;
 *     }
 *
 *     // Set the age of a person
 *     void setAge(unsigned int age)
 *    {
 *         m_age = age;
 *     }
 *
 *     // Make a person speak (tell about its name and age)
 *     void speak()
 *     {
 *         std::cout << "Hi! My name is " << m_name << " and I'm " << m_age << " years old." << std::endl;
 *     }
 *
 * private:
 *
 *     std::string m_name;
 *     unsigned int m_age;
 * };
 *
 * // Make the Person type available to CAMP
 * CAMP_TYPE(Person);
 *
 *
 * int main()
 * {
 *     // Bind our Person class to CAMP
 *     camp::Class::declare<Person>("Person")
 *         .constructor1<std::string>()
 *         .property("name", &Person::name)
 *         .property("age", &Person::age, &Person::setAge)
 *         .function("speak", &Person::speak);
 *
 *     // Retrieve it by its name
 *     const camp::Class& metaclass = camp::classByName("Person");
 *
 *     // Construct a new person named John
 *     Person* john = metaclass.construct<Person>(camp::Args("John"));
 *
 *     // Print its name
 *     std::string name = metaclass.property("name").get(john);
 *     std::cout << "John's name is: " << name << std::endl;
 *
 *     // Set its age to 24
 *     metaclass.property("age").set(john, 24);
 *
 *     // Make John say something
 *     metaclass.function("speak").call(john);
 *
 *     // Kill John
 *     metaclass.destroy(john);
 *
 *     return 0;
 * }
 * \endcode
 *
 * \section licence Licence
 *
 * CAMP is distributed under the terms of the GPL v3 licence:
 *
 * \verbatim
 *   CAMP - dynamic reflexion C++ library
 *   Copyright (C) 2009 TechnoGerma Systems France
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * \endverbatim
 *
 */
<|endoftext|>


<commit_before>/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.

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

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

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

#include "tensorflow/core/platform/error.h"

#include <errno.h>
#include <string.h>

#include "tensorflow/core/platform/status.h"
#include "tensorflow/core/platform/strcat.h"

namespace tensorflow {

error::Code ErrnoToCode(int err_number) {
  error::Code code;
  switch (err_number) {
    case 0:
      code = error::OK;
      break;
    case EINVAL:        // Invalid argument
    case ENAMETOOLONG:  // Filename too long
    case E2BIG:         // Argument list too long
    case EDESTADDRREQ:  // Destination address required
    case EDOM:          // Mathematics argument out of domain of function
    case EFAULT:        // Bad address
    case EILSEQ:        // Illegal byte sequence
    case ENOPROTOOPT:   // Protocol not available
    case ENOSTR:        // Not a STREAM
    case ENOTSOCK:      // Not a socket
    case ENOTTY:        // Inappropriate I/O control operation
    case EPROTOTYPE:    // Protocol wrong type for socket
    case ESPIPE:        // Invalid seek
      code = error::INVALID_ARGUMENT;
      break;
    case ETIMEDOUT:  // Connection timed out
    case ETIME:      // Timer expired
      code = error::DEADLINE_EXCEEDED;
      break;
    case ENODEV:  // No such device
    case ENOENT:  // No such file or directory
    case ENXIO:   // No such device or address
    case ESRCH:   // No such process
      code = error::NOT_FOUND;
      break;
    case EEXIST:         // File exists
    case EADDRNOTAVAIL:  // Address not available
    case EALREADY:       // Connection already in progress
      code = error::ALREADY_EXISTS;
      break;
    case EPERM:   // Operation not permitted
    case EACCES:  // Permission denied
    case EROFS:   // Read only file system
      code = error::PERMISSION_DENIED;
      break;
    case ENOTEMPTY:   // Directory not empty
    case EISDIR:      // Is a directory
    case ENOTDIR:     // Not a directory
    case EADDRINUSE:  // Address already in use
    case EBADF:       // Invalid file descriptor
    case EBUSY:       // Device or resource busy
    case ECHILD:      // No child processes
    case EISCONN:     // Socket is connected
#if !defined(_WIN32) && !defined(__HAIKU__)
    case ENOTBLK:  // Block device required
#endif
    case ENOTCONN:  // The socket is not connected
    case EPIPE:     // Broken pipe
#if !defined(_WIN32)
    case ESHUTDOWN:  // Cannot send after transport endpoint shutdown
#endif
    case ETXTBSY:  // Text file busy
      code = error::FAILED_PRECONDITION;
      break;
    case ENOSPC:  // No space left on device
#if !defined(_WIN32)
    case EDQUOT:  // Disk quota exceeded
#endif
    case EMFILE:   // Too many open files
    case EMLINK:   // Too many links
    case ENFILE:   // Too many open files in system
    case ENOBUFS:  // No buffer space available
    case ENODATA:  // No message is available on the STREAM read queue
    case ENOMEM:   // Not enough space
    case ENOSR:    // No STREAM resources
#if !defined(_WIN32) && !defined(__HAIKU__)
    case EUSERS:  // Too many users
#endif
      code = error::RESOURCE_EXHAUSTED;
      break;
    case EFBIG:      // File too large
    case EOVERFLOW:  // Value too large to be stored in data type
    case ERANGE:     // Result too large
      code = error::OUT_OF_RANGE;
      break;
    case ENOSYS:        // Function not implemented
    case ENOTSUP:       // Operation not supported
    case EAFNOSUPPORT:  // Address family not supported
#if !defined(_WIN32)
    case EPFNOSUPPORT:  // Protocol family not supported
#endif
    case EPROTONOSUPPORT:  // Protocol not supported
#if !defined(_WIN32) && !defined(__HAIKU__)
    case ESOCKTNOSUPPORT:  // Socket type not supported
#endif
    case EXDEV:  // Improper link
      code = error::UNIMPLEMENTED;
      break;
    case EAGAIN:        // Resource temporarily unavailable
    case ECONNREFUSED:  // Connection refused
    case ECONNABORTED:  // Connection aborted
    case ECONNRESET:    // Connection reset
    case EINTR:         // Interrupted function call
#if !defined(_WIN32)
    case EHOSTDOWN:  // Host is down
#endif
    case EHOSTUNREACH:  // Host is unreachable
    case ENETDOWN:      // Network is down
    case ENETRESET:     // Connection aborted by network
    case ENETUNREACH:   // Network unreachable
    case ENOLCK:        // No locks available
    case ENOLINK:       // Link has been severed
#if !(defined(__APPLE__) || defined(__FreeBSD__) || defined(_WIN32) || \
      defined(__HAIKU__))
    case ENONET:  // Machine is not on the network
#endif
      code = error::UNAVAILABLE;
      break;
    case EDEADLK:  // Resource deadlock avoided
#if !defined(_WIN32)
    case ESTALE:  // Stale file handle
#endif
      code = error::ABORTED;
      break;
    case ECANCELED:  // Operation cancelled
      code = error::CANCELLED;
      break;
    // NOTE: If you get any of the following (especially in a
    // reproducible way) and can propose a better mapping,
    // please email the owners about updating this mapping.
    case EBADMSG:      // Bad message
    case EIDRM:        // Identifier removed
    case EINPROGRESS:  // Operation in progress
    case EIO:          // I/O error
    case ELOOP:        // Too many levels of symbolic links
    case ENOEXEC:      // Exec format error
    case ENOMSG:       // No message of the desired type
    case EPROTO:       // Protocol error
#if !defined(_WIN32) && !defined(__HAIKU__)
    case EREMOTE:  // Object is remote
#endif
      code = error::UNKNOWN;
      break;
    default: {
      code = error::UNKNOWN;
      break;
    }
  }
  return code;
}

Status IOError(const string& context, int err_number) {
  auto code = ErrnoToCode(err_number);
  return Status(code, strings::StrCat(context, "; ", strerror(err_number)));
}

#if defined(_WIN32)
namespace internal {

std::string GetWindowsErrorMessage(DWORD err) {
  LPSTR buffer = NULL;
  DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
                FORMAT_MESSAGE_IGNORE_INSERTS;
  FormatMessageA(flags, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                 reinterpret_cast<LPSTR>(&buffer), 0, NULL);
  std::string message = buffer;
  LocalFree(buffer);
  return message;
}

}  // namespace internal
#endif

}  // namespace tensorflow
<commit_msg>tensorflow::ErrornoToCode should only have internal linkage.<commit_after>/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.

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

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

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

#include "tensorflow/core/platform/error.h"

#include <errno.h>
#include <string.h>

#include "tensorflow/core/platform/status.h"
#include "tensorflow/core/platform/strcat.h"

namespace tensorflow {
namespace {

error::Code ErrnoToCode(int err_number) {
  error::Code code;
  switch (err_number) {
    case 0:
      code = error::OK;
      break;
    case EINVAL:        // Invalid argument
    case ENAMETOOLONG:  // Filename too long
    case E2BIG:         // Argument list too long
    case EDESTADDRREQ:  // Destination address required
    case EDOM:          // Mathematics argument out of domain of function
    case EFAULT:        // Bad address
    case EILSEQ:        // Illegal byte sequence
    case ENOPROTOOPT:   // Protocol not available
    case ENOSTR:        // Not a STREAM
    case ENOTSOCK:      // Not a socket
    case ENOTTY:        // Inappropriate I/O control operation
    case EPROTOTYPE:    // Protocol wrong type for socket
    case ESPIPE:        // Invalid seek
      code = error::INVALID_ARGUMENT;
      break;
    case ETIMEDOUT:  // Connection timed out
    case ETIME:      // Timer expired
      code = error::DEADLINE_EXCEEDED;
      break;
    case ENODEV:  // No such device
    case ENOENT:  // No such file or directory
    case ENXIO:   // No such device or address
    case ESRCH:   // No such process
      code = error::NOT_FOUND;
      break;
    case EEXIST:         // File exists
    case EADDRNOTAVAIL:  // Address not available
    case EALREADY:       // Connection already in progress
      code = error::ALREADY_EXISTS;
      break;
    case EPERM:   // Operation not permitted
    case EACCES:  // Permission denied
    case EROFS:   // Read only file system
      code = error::PERMISSION_DENIED;
      break;
    case ENOTEMPTY:   // Directory not empty
    case EISDIR:      // Is a directory
    case ENOTDIR:     // Not a directory
    case EADDRINUSE:  // Address already in use
    case EBADF:       // Invalid file descriptor
    case EBUSY:       // Device or resource busy
    case ECHILD:      // No child processes
    case EISCONN:     // Socket is connected
#if !defined(_WIN32) && !defined(__HAIKU__)
    case ENOTBLK:  // Block device required
#endif
    case ENOTCONN:  // The socket is not connected
    case EPIPE:     // Broken pipe
#if !defined(_WIN32)
    case ESHUTDOWN:  // Cannot send after transport endpoint shutdown
#endif
    case ETXTBSY:  // Text file busy
      code = error::FAILED_PRECONDITION;
      break;
    case ENOSPC:  // No space left on device
#if !defined(_WIN32)
    case EDQUOT:  // Disk quota exceeded
#endif
    case EMFILE:   // Too many open files
    case EMLINK:   // Too many links
    case ENFILE:   // Too many open files in system
    case ENOBUFS:  // No buffer space available
    case ENODATA:  // No message is available on the STREAM read queue
    case ENOMEM:   // Not enough space
    case ENOSR:    // No STREAM resources
#if !defined(_WIN32) && !defined(__HAIKU__)
    case EUSERS:  // Too many users
#endif
      code = error::RESOURCE_EXHAUSTED;
      break;
    case EFBIG:      // File too large
    case EOVERFLOW:  // Value too large to be stored in data type
    case ERANGE:     // Result too large
      code = error::OUT_OF_RANGE;
      break;
    case ENOSYS:        // Function not implemented
    case ENOTSUP:       // Operation not supported
    case EAFNOSUPPORT:  // Address family not supported
#if !defined(_WIN32)
    case EPFNOSUPPORT:  // Protocol family not supported
#endif
    case EPROTONOSUPPORT:  // Protocol not supported
#if !defined(_WIN32) && !defined(__HAIKU__)
    case ESOCKTNOSUPPORT:  // Socket type not supported
#endif
    case EXDEV:  // Improper link
      code = error::UNIMPLEMENTED;
      break;
    case EAGAIN:        // Resource temporarily unavailable
    case ECONNREFUSED:  // Connection refused
    case ECONNABORTED:  // Connection aborted
    case ECONNRESET:    // Connection reset
    case EINTR:         // Interrupted function call
#if !defined(_WIN32)
    case EHOSTDOWN:  // Host is down
#endif
    case EHOSTUNREACH:  // Host is unreachable
    case ENETDOWN:      // Network is down
    case ENETRESET:     // Connection aborted by network
    case ENETUNREACH:   // Network unreachable
    case ENOLCK:        // No locks available
    case ENOLINK:       // Link has been severed
#if !(defined(__APPLE__) || defined(__FreeBSD__) || defined(_WIN32) || \
      defined(__HAIKU__))
    case ENONET:  // Machine is not on the network
#endif
      code = error::UNAVAILABLE;
      break;
    case EDEADLK:  // Resource deadlock avoided
#if !defined(_WIN32)
    case ESTALE:  // Stale file handle
#endif
      code = error::ABORTED;
      break;
    case ECANCELED:  // Operation cancelled
      code = error::CANCELLED;
      break;
    // NOTE: If you get any of the following (especially in a
    // reproducible way) and can propose a better mapping,
    // please email the owners about updating this mapping.
    case EBADMSG:      // Bad message
    case EIDRM:        // Identifier removed
    case EINPROGRESS:  // Operation in progress
    case EIO:          // I/O error
    case ELOOP:        // Too many levels of symbolic links
    case ENOEXEC:      // Exec format error
    case ENOMSG:       // No message of the desired type
    case EPROTO:       // Protocol error
#if !defined(_WIN32) && !defined(__HAIKU__)
    case EREMOTE:  // Object is remote
#endif
      code = error::UNKNOWN;
      break;
    default: {
      code = error::UNKNOWN;
      break;
    }
  }
  return code;
}

}  // namespace

Status IOError(const string& context, int err_number) {
  auto code = ErrnoToCode(err_number);
  return Status(code, strings::StrCat(context, "; ", strerror(err_number)));
}

#if defined(_WIN32)
namespace internal {

std::string GetWindowsErrorMessage(DWORD err) {
  LPSTR buffer = NULL;
  DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
                FORMAT_MESSAGE_IGNORE_INSERTS;
  FormatMessageA(flags, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                 reinterpret_cast<LPSTR>(&buffer), 0, NULL);
  std::string message = buffer;
  LocalFree(buffer);
  return message;
}

}  // namespace internal
#endif

}  // namespace tensorflow
<|endoftext|>