<commit_before>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file sgd_context.hpp
 * \brief Stochastic Gradient Descent (SGD) context Implementation.
 */

#pragma once

#include "etl/etl.hpp"

#include "dll/layer_traits.hpp"
#include "dll/dbn_traits.hpp"

namespace dll {

/*!
 * \copydoc sgd_context
 */
template <typename DBN, typename Layer>
struct sgd_context<DBN, Layer, std::enable_if_t<layer_traits<Layer>::is_dense_layer() && !layer_traits<Layer>::is_dynamic()>> {
    using layer_t = Layer;
    using weight  = typename layer_t::weight;

    static constexpr const auto num_visible = layer_t::num_visible;
    static constexpr const auto num_hidden  = layer_t::num_hidden;

    static constexpr const auto batch_size = DBN::batch_size;

    etl::fast_matrix<weight, num_visible, num_hidden> w_grad;
    etl::fast_matrix<weight, num_hidden> b_grad;

    etl::fast_matrix<weight, num_visible, num_hidden> w_inc;
    etl::fast_matrix<weight, num_hidden> b_inc;

    etl::fast_matrix<weight, batch_size, num_visible> input;
    etl::fast_matrix<weight, batch_size, num_hidden> output;
    etl::fast_matrix<weight, batch_size, num_hidden> errors;

    sgd_context()
            : w_inc(0.0), b_inc(0.0), output(0.0), errors(0.0) {}
};

/*!
 * \copydoc sgd_context
 */
template <typename DBN, typename Layer>
struct sgd_context<DBN, Layer, std::enable_if_t<layer_traits<Layer>::is_dense_layer() && layer_traits<Layer>::is_dynamic()>> {
    using layer_t = Layer;
    using weight  = typename layer_t::weight;

    static constexpr const auto batch_size = DBN::batch_size;

    etl::dyn_matrix<weight, 2> w_grad;
    etl::dyn_matrix<weight, 1> b_grad;

    etl::dyn_matrix<weight, 2> w_inc;
    etl::dyn_matrix<weight, 1> b_inc;

    etl::dyn_matrix<weight, 2> input;
    etl::dyn_matrix<weight, 2> output;
    etl::dyn_matrix<weight, 2> errors;

    sgd_context(std::size_t num_visible, std::size_t num_hidden)
            : w_grad(num_visible, num_hidden), b_grad(num_hidden),
              w_inc(num_visible, num_hidden, 0.0), b_inc(num_hidden, 0.0),
              input(batch_size, num_visible, 0.0), output(batch_size, num_hidden, 0.0), errors(batch_size, num_hidden, 0.0) {}
};

/*!
 * \copydoc sgd_context
 */
template <typename DBN, typename Layer>
struct sgd_context<DBN, Layer, std::enable_if_t<layer_traits<Layer>::is_convolutional_layer() && !layer_traits<Layer>::is_dynamic()>> {
    using layer_t = Layer;
    using weight  = typename layer_t::weight;

    static_assert(!layer_traits<layer_t>::has_probabilistic_max_pooling(), "Probabilistic Max Pooling is not supported in backpropagation");

    static constexpr const std::size_t NV1 = layer_t::NV1;
    static constexpr const std::size_t NV2 = layer_t::NV2;
    static constexpr const std::size_t NH1 = layer_t::NH1;
    static constexpr const std::size_t NH2 = layer_t::NH2;
    static constexpr const std::size_t NW1 = layer_t::NW1;
    static constexpr const std::size_t NW2 = layer_t::NW2;
    static constexpr const std::size_t NC  = layer_t::NC;
    static constexpr const std::size_t K   = layer_t::K;

    static constexpr const auto batch_size = DBN::batch_size;

    etl::fast_matrix<weight, K, NC, NW1, NW2> w_grad;
    etl::fast_matrix<weight, K> b_grad;

    etl::fast_matrix<weight, K, NC, NW1, NW2> w_inc;
    etl::fast_matrix<weight, K> b_inc;

    etl::fast_matrix<weight, batch_size, NC, NV1, NV2> input;
    etl::fast_matrix<weight, batch_size, K, NH1, NH2> output;
    etl::fast_matrix<weight, batch_size, K, NH1, NH2> errors;

    sgd_context()
            : w_inc(0.0), b_inc(0.0), output(0.0), errors(0.0) {}
};

/*!
 * \copydoc sgd_context
 */
template <typename DBN, typename Layer>
struct sgd_context<DBN, Layer, std::enable_if_t<layer_traits<Layer>::is_convolutional_layer() && layer_traits<Layer>::is_dynamic()>> {
    using layer_t = Layer;
    using weight  = typename layer_t::weight;

    static_assert(!layer_traits<layer_t>::has_probabilistic_max_pooling(), "Probabilistic Max Pooling is not supported in backpropagation");

    static constexpr const auto batch_size = DBN::batch_size;

    etl::dyn_matrix<weight, 4> w_grad;
    etl::dyn_matrix<weight, 1> b_grad;

    etl::dyn_matrix<weight, 4> w_inc;
    etl::dyn_matrix<weight, 1> b_inc;

    etl::dyn_matrix<weight, 4> input;
    etl::dyn_matrix<weight, 4> output;
    etl::dyn_matrix<weight, 4> errors;

    sgd_context(size_t nc, size_t nv1, size_t nv2, size_t k, size_t nh1, size_t nh2)
            : w_grad(k, nc, nv1 - nh1 + 1, nv2 - nh2 + 1), b_grad(k),
              w_inc(k, nc, nv1 - nh1 + 1, nv2 - nh2 + 1), b_inc(k),
              input(batch_size, nc, nv1, nv2),
              output(batch_size, k, nh1, nh2), errors(batch_size, k, nh1, nh2) {}
};

/*!
 * \copydoc sgd_context
 */
template <typename DBN, typename Layer>
struct sgd_context<DBN, Layer, std::enable_if_t<layer_traits<Layer>::is_pooling_layer() && !layer_traits<Layer>::is_dynamic()>> {
    using layer_t = Layer;
    using weight  = typename layer_t::weight;

    static constexpr const std::size_t I1 = layer_t::I1;
    static constexpr const std::size_t I2 = layer_t::I2;
    static constexpr const std::size_t I3 = layer_t::I3;

    static constexpr const std::size_t O1 = layer_t::O1;
    static constexpr const std::size_t O2 = layer_t::O2;
    static constexpr const std::size_t O3 = layer_t::O3;

    static constexpr const auto batch_size = DBN::batch_size;

    etl::fast_matrix<weight, batch_size, I1, I2, I3> input;
    etl::fast_matrix<weight, batch_size, O1, O2, O3> output;
    etl::fast_matrix<weight, batch_size, O1, O2, O3> errors;
};

/*!
 * \copydoc sgd_context
 */
template <typename DBN, typename Layer>
struct sgd_context<DBN, Layer, std::enable_if_t<layer_traits<Layer>::is_pooling_layer() && layer_traits<Layer>::is_dynamic()>> {
    using layer_t = Layer;
    using weight  = typename layer_t::weight;

    static constexpr const auto batch_size = DBN::batch_size;

    etl::dyn_matrix<weight, 4> input;
    etl::dyn_matrix<weight, 4> output;
    etl::dyn_matrix<weight, 4> errors;

    sgd_context(size_t i1, size_t i2, size_t i3, size_t c1, size_t c2, size_t c3)
            : input(batch_size, i1, i2, i3),
              output(batch_size, i1 / c1, i2 / c2, i3 / c3),
              errors(batch_size, i1 / c1, i2 / c2, i3 / c3) {}
};

template <typename DBN, typename Layer>
struct transform_output_type {
    static constexpr const auto dimensions = dbn_traits<DBN>::is_convolutional() ? 4 : 2;

    using weight  = typename DBN::weight;
    using type = etl::dyn_matrix<weight, dimensions>;
};

template <typename DBN, typename Layer>
using transform_output_type_t = typename transform_output_type<DBN, Layer>::type;

/*!
 * \copydoc sgd_context
 */
template <typename DBN, typename Layer>
struct sgd_context<DBN, Layer, std::enable_if_t<layer_traits<Layer>::is_transform_layer()>> {
    using layer_t = Layer;
    using weight  = typename DBN::weight;

    using inputs_t = transform_output_type_t<DBN, Layer>;

    inputs_t input;
    inputs_t output;
    inputs_t errors;
};

} //end of dll namespace
<commit_msg>SGD context support<commit_after>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file sgd_context.hpp
 * \brief Stochastic Gradient Descent (SGD) context Implementation.
 */

#pragma once

#include "etl/etl.hpp"

#include "dll/layer_traits.hpp"
#include "dll/dbn_traits.hpp"

namespace dll {

/*!
 * \copydoc sgd_context
 */
template <typename DBN, typename Layer>
struct sgd_context<DBN, Layer, std::enable_if_t<layer_traits<Layer>::is_dense_layer() && !layer_traits<Layer>::is_dynamic()>> {
    using layer_t = Layer;
    using weight  = typename layer_t::weight;

    static constexpr const auto num_visible = layer_t::num_visible;
    static constexpr const auto num_hidden  = layer_t::num_hidden;

    static constexpr const auto batch_size = DBN::batch_size;

    etl::fast_matrix<weight, num_visible, num_hidden> w_grad;
    etl::fast_matrix<weight, num_hidden> b_grad;

    etl::fast_matrix<weight, num_visible, num_hidden> w_inc;
    etl::fast_matrix<weight, num_hidden> b_inc;

    etl::fast_matrix<weight, batch_size, num_visible> input;
    etl::fast_matrix<weight, batch_size, num_hidden> output;
    etl::fast_matrix<weight, batch_size, num_hidden> errors;

    sgd_context()
            : w_inc(0.0), b_inc(0.0), output(0.0), errors(0.0) {}
};

/*!
 * \copydoc sgd_context
 */
template <typename DBN, typename Layer>
struct sgd_context<DBN, Layer, std::enable_if_t<layer_traits<Layer>::is_dense_layer() && layer_traits<Layer>::is_dynamic()>> {
    using layer_t = Layer;
    using weight  = typename layer_t::weight;

    static constexpr const auto batch_size = DBN::batch_size;

    etl::dyn_matrix<weight, 2> w_grad;
    etl::dyn_matrix<weight, 1> b_grad;

    etl::dyn_matrix<weight, 2> w_inc;
    etl::dyn_matrix<weight, 1> b_inc;

    etl::dyn_matrix<weight, 2> input;
    etl::dyn_matrix<weight, 2> output;
    etl::dyn_matrix<weight, 2> errors;

    sgd_context(std::size_t num_visible, std::size_t num_hidden)
            : w_grad(num_visible, num_hidden), b_grad(num_hidden),
              w_inc(num_visible, num_hidden, 0.0), b_inc(num_hidden, 0.0),
              input(batch_size, num_visible, 0.0), output(batch_size, num_hidden, 0.0), errors(batch_size, num_hidden, 0.0) {}
};

/*!
 * \copydoc sgd_context
 */
template <typename DBN, typename Layer>
struct sgd_context<DBN, Layer, std::enable_if_t<(layer_traits<Layer>::is_convolutional_layer() || layer_traits<Layer>::is_deconvolutional_layer()) && !layer_traits<Layer>::is_dynamic()>> {
    using layer_t = Layer;
    using weight  = typename layer_t::weight;

    static_assert(!layer_traits<layer_t>::has_probabilistic_max_pooling(), "Probabilistic Max Pooling is not supported in backpropagation");

    static constexpr const std::size_t NV1 = layer_t::NV1;
    static constexpr const std::size_t NV2 = layer_t::NV2;
    static constexpr const std::size_t NH1 = layer_t::NH1;
    static constexpr const std::size_t NH2 = layer_t::NH2;
    static constexpr const std::size_t NW1 = layer_t::NW1;
    static constexpr const std::size_t NW2 = layer_t::NW2;
    static constexpr const std::size_t NC  = layer_t::NC;
    static constexpr const std::size_t K   = layer_t::K;

    static constexpr const auto batch_size = DBN::batch_size;

    etl::fast_matrix<weight, K, NC, NW1, NW2> w_grad;
    etl::fast_matrix<weight, K> b_grad;

    etl::fast_matrix<weight, K, NC, NW1, NW2> w_inc;
    etl::fast_matrix<weight, K> b_inc;

    etl::fast_matrix<weight, batch_size, NC, NV1, NV2> input;
    etl::fast_matrix<weight, batch_size, K, NH1, NH2> output;
    etl::fast_matrix<weight, batch_size, K, NH1, NH2> errors;

    sgd_context()
            : w_inc(0.0), b_inc(0.0), output(0.0), errors(0.0) {}
};

/*!
 * \copydoc sgd_context
 */
template <typename DBN, typename Layer>
struct sgd_context<DBN, Layer, std::enable_if_t<(layer_traits<Layer>::is_convolutional_layer() || layer_traits<Layer>::is_deconvolutional_layer()) && layer_traits<Layer>::is_dynamic()>> {
    using layer_t = Layer;
    using weight  = typename layer_t::weight;

    static_assert(!layer_traits<layer_t>::has_probabilistic_max_pooling(), "Probabilistic Max Pooling is not supported in backpropagation");

    static constexpr const auto batch_size = DBN::batch_size;

    etl::dyn_matrix<weight, 4> w_grad;
    etl::dyn_matrix<weight, 1> b_grad;

    etl::dyn_matrix<weight, 4> w_inc;
    etl::dyn_matrix<weight, 1> b_inc;

    etl::dyn_matrix<weight, 4> input;
    etl::dyn_matrix<weight, 4> output;
    etl::dyn_matrix<weight, 4> errors;

    sgd_context(size_t nc, size_t nv1, size_t nv2, size_t k, size_t nh1, size_t nh2)
            : w_grad(k, nc, nv1 - nh1 + 1, nv2 - nh2 + 1), b_grad(k),
              w_inc(k, nc, nv1 - nh1 + 1, nv2 - nh2 + 1), b_inc(k),
              input(batch_size, nc, nv1, nv2),
              output(batch_size, k, nh1, nh2), errors(batch_size, k, nh1, nh2) {}
};

/*!
 * \copydoc sgd_context
 */
template <typename DBN, typename Layer>
struct sgd_context<DBN, Layer, std::enable_if_t<layer_traits<Layer>::is_pooling_layer() && !layer_traits<Layer>::is_dynamic()>> {
    using layer_t = Layer;
    using weight  = typename layer_t::weight;

    static constexpr const std::size_t I1 = layer_t::I1;
    static constexpr const std::size_t I2 = layer_t::I2;
    static constexpr const std::size_t I3 = layer_t::I3;

    static constexpr const std::size_t O1 = layer_t::O1;
    static constexpr const std::size_t O2 = layer_t::O2;
    static constexpr const std::size_t O3 = layer_t::O3;

    static constexpr const auto batch_size = DBN::batch_size;

    etl::fast_matrix<weight, batch_size, I1, I2, I3> input;
    etl::fast_matrix<weight, batch_size, O1, O2, O3> output;
    etl::fast_matrix<weight, batch_size, O1, O2, O3> errors;
};

/*!
 * \copydoc sgd_context
 */
template <typename DBN, typename Layer>
struct sgd_context<DBN, Layer, std::enable_if_t<layer_traits<Layer>::is_pooling_layer() && layer_traits<Layer>::is_dynamic()>> {
    using layer_t = Layer;
    using weight  = typename layer_t::weight;

    static constexpr const auto batch_size = DBN::batch_size;

    etl::dyn_matrix<weight, 4> input;
    etl::dyn_matrix<weight, 4> output;
    etl::dyn_matrix<weight, 4> errors;

    sgd_context(size_t i1, size_t i2, size_t i3, size_t c1, size_t c2, size_t c3)
            : input(batch_size, i1, i2, i3),
              output(batch_size, i1 / c1, i2 / c2, i3 / c3),
              errors(batch_size, i1 / c1, i2 / c2, i3 / c3) {}
};

template <typename DBN, typename Layer>
struct transform_output_type {
    static constexpr const auto dimensions = dbn_traits<DBN>::is_convolutional() ? 4 : 2;

    using weight  = typename DBN::weight;
    using type = etl::dyn_matrix<weight, dimensions>;
};

template <typename DBN, typename Layer>
using transform_output_type_t = typename transform_output_type<DBN, Layer>::type;

/*!
 * \copydoc sgd_context
 */
template <typename DBN, typename Layer>
struct sgd_context<DBN, Layer, std::enable_if_t<layer_traits<Layer>::is_transform_layer()>> {
    using layer_t = Layer;
    using weight  = typename DBN::weight;

    using inputs_t = transform_output_type_t<DBN, Layer>;

    inputs_t input;
    inputs_t output;
    inputs_t errors;
};

} //end of dll namespace
<|endoftext|>


<commit_before>/*
 * eos - A 3D Morphable Model fitting library written in modern C++11/14.
 *
 * File: include/eos/core/LandmarkMapper.hpp
 *
 * Copyright 2014-2017 Patrik Huber
 *
 * 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.
 */
#pragma once

#ifndef LANDMARKMAPPER_HPP_
#define LANDMARKMAPPER_HPP_

#include <string>
#include <map>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <algorithm>
#include <optional>

namespace eos {
	namespace core {

/**
 * @brief Represents a mapping from one kind of landmarks
 * to a different format (e.g. model vertices).
 *
 * When fitting the 3D model to an image, a correspondence must
 * be known from the 2D image landmarks to 3D vertex points in
 * the Morphable Model. The 3D model defines all its points in
 * the form of vertex ids.
 * These mappings are stored in a file, see the \c share/ folder for
 * an example for mapping 2D ibug landmarks to 3D model vertex indices.
 *
 * The LandmarkMapper thus has two main use cases:
 * - Mapping 2D landmark points to 3D vertices
 * - Converting one set of 2D landmarks into another set of 2D
 *   landmarks with different identifiers.
 */
class LandmarkMapper {
public:
	/**
	 * @brief Constructs a new landmark mapper that performs an identity
	 * mapping, that is, its output is the same as the input.
	 */
	LandmarkMapper() = default;

	/**
	 * @brief Constructs a new landmark mapper from a file containing
	 * mappings from one set of landmark identifiers to another.
	 *
	 * In case the file contains no mappings, a landmark mapper
	 * that performs an identity mapping is constructed.
	 *
	 * @param[in] filename A file with landmark mappings.
	 * @throws runtime_error if there is an error loading the mappings from the file.
	 */
	LandmarkMapper(std::string filename)
	{
		using std::string;
		using std::getline;

		std::ifstream file(filename);
		if (!file.is_open()) {
			throw std::runtime_error(string("LandmarkMapper: Could not open landmark mappings file: " + filename));
		}

		// We'll need these helper functions for the parsing:
		auto starts_with = [](const std::string& input, const std::string& match)
		{
			return input.size() >= match.size() && std::equal(match.begin(), match.end(), input.begin());
		};

		auto trim_left = [](const std::string& input, std::string pattern = " \t")
		{
			auto first = input.find_first_not_of(pattern);
			if (first == std::string::npos)
			{
				return input;
			}
			return input.substr(first, input.size());
		};

		// Read the actual file:
		string line;
		// Skip any comments (";") or empty lines at the beginning:
		while (getline(file, line)) {
			if (!starts_with(line, ";") && line != "")
			{
				// not a commented or not an empty line
				break;
			}
		}
		// First actual line should be "landmarkMappings"
		if (!starts_with(line, "landmarkMappings")) {
			throw std::runtime_error("LandmarkMapper error: First non-comment line should be \"landmarkMappings\".");
		}
		getline(file, line);
		// The next line has to be "{":
		if (line != "{") {
			throw std::runtime_error("LandmarkMapper error: Expected a \"{\" on the line following the \"landmarkMappings\" statement.");
		}

		while (getline(file, line))
		{
			if (line == "}") { // end of the landmarkMappings block
				break;
			}
			// on comment, continue:
			if (starts_with(trim_left(line), ";"))
			{
				continue;
			}
			std::stringstream line_stream(line);
			string lhs, rhs;
			if (!(line_stream >> lhs >> rhs)) {
				throw std::runtime_error(string("Landmark mappings format error while parsing the line: " + line));
			}
			landmark_mappings.insert(std::make_pair(lhs, rhs));
		}
		// We're at the end of the "landmarkMappings { ... }" block. Something else may follow, but we don't care.
	};

	/**
	 * @brief Converts the given landmark name to the mapped name.
	 *
	 * @param[in] landmark_name A landmark name to convert.
	 * @return The mapped landmark name if a mapping exists, an empty optional otherwise.
	 * @throws out_of_range exception if there is no mapping
	 *         for the given landmarkName.
	 */
	std::optional<std::string> convert(std::string landmark_name) const
	{
		if (landmark_mappings.empty()) {
			// perform identity mapping, i.e. return the input
			return landmark_name;
		}

		auto&& converted_landmark = landmark_mappings.find(landmark_name);
		if (converted_landmark != std::end(landmark_mappings)) {
			// landmark mapping found, return it
			return converted_landmark->second;
		}
		else { // landmark_name does not match the key of any element in the map
			return std::nullopt;
		}
	};

	/**
	 * @brief Returns the number of loaded landmark mappings.
	 *
	 * @return The number of landmark mappings.
	 */
	auto num_mappings() const
	{
		return landmark_mappings.size();
	};

private:
	std::map<std::string, std::string> landmark_mappings; ///< Mapping from one landmark name to a name in a different format.
};

	} /* namespace core */
} /* namespace eos */

#endif /* LANDMARKMAPPER_HPP_ */
<commit_msg>Removed old comment<commit_after>/*
 * eos - A 3D Morphable Model fitting library written in modern C++11/14.
 *
 * File: include/eos/core/LandmarkMapper.hpp
 *
 * Copyright 2014-2017 Patrik Huber
 *
 * 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.
 */
#pragma once

#ifndef LANDMARKMAPPER_HPP_
#define LANDMARKMAPPER_HPP_

#include <string>
#include <map>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <algorithm>
#include <optional>

namespace eos {
	namespace core {

/**
 * @brief Represents a mapping from one kind of landmarks
 * to a different format (e.g. model vertices).
 *
 * When fitting the 3D model to an image, a correspondence must
 * be known from the 2D image landmarks to 3D vertex points in
 * the Morphable Model. The 3D model defines all its points in
 * the form of vertex ids.
 * These mappings are stored in a file, see the \c share/ folder for
 * an example for mapping 2D ibug landmarks to 3D model vertex indices.
 *
 * The LandmarkMapper thus has two main use cases:
 * - Mapping 2D landmark points to 3D vertices
 * - Converting one set of 2D landmarks into another set of 2D
 *   landmarks with different identifiers.
 */
class LandmarkMapper {
public:
	/**
	 * @brief Constructs a new landmark mapper that performs an identity
	 * mapping, that is, its output is the same as the input.
	 */
	LandmarkMapper() = default;

	/**
	 * @brief Constructs a new landmark mapper from a file containing
	 * mappings from one set of landmark identifiers to another.
	 *
	 * In case the file contains no mappings, a landmark mapper
	 * that performs an identity mapping is constructed.
	 *
	 * @param[in] filename A file with landmark mappings.
	 * @throws runtime_error if there is an error loading the mappings from the file.
	 */
	LandmarkMapper(std::string filename)
	{
		using std::string;
		using std::getline;

		std::ifstream file(filename);
		if (!file.is_open()) {
			throw std::runtime_error(string("LandmarkMapper: Could not open landmark mappings file: " + filename));
		}

		// We'll need these helper functions for the parsing:
		auto starts_with = [](const std::string& input, const std::string& match)
		{
			return input.size() >= match.size() && std::equal(match.begin(), match.end(), input.begin());
		};

		auto trim_left = [](const std::string& input, std::string pattern = " \t")
		{
			auto first = input.find_first_not_of(pattern);
			if (first == std::string::npos)
			{
				return input;
			}
			return input.substr(first, input.size());
		};

		// Read the actual file:
		string line;
		// Skip any comments (";") or empty lines at the beginning:
		while (getline(file, line)) {
			if (!starts_with(line, ";") && line != "")
			{
				// not a commented or not an empty line
				break;
			}
		}
		// First actual line should be "landmarkMappings"
		if (!starts_with(line, "landmarkMappings")) {
			throw std::runtime_error("LandmarkMapper error: First non-comment line should be \"landmarkMappings\".");
		}
		getline(file, line);
		// The next line has to be "{":
		if (line != "{") {
			throw std::runtime_error("LandmarkMapper error: Expected a \"{\" on the line following the \"landmarkMappings\" statement.");
		}

		while (getline(file, line))
		{
			if (line == "}") { // end of the landmarkMappings block
				break;
			}
			// on comment, continue:
			if (starts_with(trim_left(line), ";"))
			{
				continue;
			}
			std::stringstream line_stream(line);
			string lhs, rhs;
			if (!(line_stream >> lhs >> rhs)) {
				throw std::runtime_error(string("Landmark mappings format error while parsing the line: " + line));
			}
			landmark_mappings.insert(std::make_pair(lhs, rhs));
		}
		// We're at the end of the "landmarkMappings { ... }" block. Something else may follow, but we don't care.
	};

	/**
	 * @brief Converts the given landmark name to the mapped name.
	 *
	 * @param[in] landmark_name A landmark name to convert.
	 * @return The mapped landmark name if a mapping exists, an empty optional otherwise.
	 */
	std::optional<std::string> convert(std::string landmark_name) const
	{
		if (landmark_mappings.empty()) {
			// perform identity mapping, i.e. return the input
			return landmark_name;
		}

		auto&& converted_landmark = landmark_mappings.find(landmark_name);
		if (converted_landmark != std::end(landmark_mappings)) {
			// landmark mapping found, return it
			return converted_landmark->second;
		}
		else { // landmark_name does not match the key of any element in the map
			return std::nullopt;
		}
	};

	/**
	 * @brief Returns the number of loaded landmark mappings.
	 *
	 * @return The number of landmark mappings.
	 */
	auto num_mappings() const
	{
		return landmark_mappings.size();
	};

private:
	std::map<std::string, std::string> landmark_mappings; ///< Mapping from one landmark name to a name in a different format.
};

	} /* namespace core */
} /* namespace eos */

#endif /* LANDMARKMAPPER_HPP_ */
<|endoftext|>


<commit_before>#include "data-id.hpp"

ID::ID() {
	init(Department(NONE), 0, "");
}
ID::ID(const ID& c) {
	copy(c);
}
ID& ID::operator= (const ID &c) {
	if (this == &c) return *this;
	copy(c);
	return *this;
}

ID::ID(string str) {
	string d, d1, d2, n, s;
	int num;
	long firstSpace, firstDigit, lastDigit, lastChar;
	// cout << "Called ID::ID() with string '" << str << "'" << endl;

	// Make sure everything is uppercase
	std::transform(str.begin(), str.end(), str.begin(), ::toupper);

	// Remove extraneous spaces
	if (str.at(0) == ' ')
		str.erase(0, 1);
	if (str.at(str.length()-1) == ' ')
		str = str.substr(0, str.length()-1);

	firstSpace = str.find_first_of(" ");

	firstDigit = str.find_first_of("0123456789");
	lastDigit  =  str.find_last_of("0123456789");

	lastChar   =  str.find_last_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ");

	// Split into Department, Number, and Section

	// pull out the department string
	if (firstSpace == string::npos) // if there is no space
		d = str.substr(0, firstDigit);
	else
		d = str.substr(0, firstSpace); // there is a space

	// check for one of those dastardly split departments
	if (d.find('/') != string::npos) {
		d1 = d.substr(0,2);
		d2 = d.substr(3,2);
	}

	n = str.substr(firstDigit, str.length());

	if (!isdigit(n[n.length()-1]))
		n = str.substr(firstDigit, n.length()-1);

	num = stringToInt(n);

	if (lastChar > lastDigit) // there is a section
		s = str[lastChar];

	// cout << "Parsed '" << str << "' to get '";
	// cout << d << " ";
	// if (!d1.empty() && !d2.empty())
		// cout << "(" << d1 << " " << d2 << ") ";
	// cout << n << s << "'." << endl;

	init(Department(d), num, s);
	if (!d1.empty() && !d2.empty()) {
		departments.clear();
		departments.push_back(Department(d1));
		departments.push_back(Department(d2));
	}
	// cout << *this << endl;
}
ID::ID(string dn, string s) {
	ID(dn+s);
}
ID::ID(string d, string n, string s) {
	ID(d + n + s);
}
ID::ID(Department d, int n, string s) {
	init(d, n, s);
}

void ID::init(Department d, int n, string s) {
	departments.push_back(d);
	number = n;
	section = s;
}

void ID::copy(const ID& c) {
	departments = c.departments;
	number = c.number;
	section = c.section;
}

Department ID::getDepartment(int i = 0) {
	return departments.at(i);
}

const Department ID::getDepartment_const(int i = 0) {
	return departments.at(i);
}

int ID::getNumber() {
	return number;
}

string ID::getSection() {
	return section;
}

bool operator== (const ID &i1, const ID &i2) {
    return ((i1.departments[0] == i2.departments[0]) && (i1.number == i2.number) && (i1.section == i2.section));
}

bool operator!= (ID &i1, ID &i2) {
    return !(i1 == i2);
}

bool operator< (const ID &i1, const ID &i2) {
	return (i1.departments.at(0) < i2.departments.at(0));
}

ostream& ID::getData(ostream& os) {
	for (vector<Department>::iterator i = departments.begin(); i != departments.end(); ++i) {
		if (departments.size() == 1)
			os << i->getName();
		else {
			os << i->getName();
			if (i != departments.end()-1)
				os << "/";
		}
	}
	os << " ";
	os << number;
	if (!section.empty())
		os << "[" << section << "]";
	return os;
}

ostream& operator<<(ostream& os, ID& item) {
	return item.getData(os);
}

void ID::display() {
	cout << *this << endl;
}
<commit_msg>ID::init defaults to NONE<commit_after>#include "data-id.hpp"

ID::ID() {
	init(Department(), 0, "");
}
ID::ID(const ID& c) {
	copy(c);
}
ID& ID::operator= (const ID &c) {
	if (this == &c) return *this;
	copy(c);
	return *this;
}

ID::ID(string str) {
	string d, d1, d2, n, s;
	int num;
	long firstSpace, firstDigit, lastDigit, lastChar;
	// cout << "Called ID::ID() with string '" << str << "'" << endl;

	// Make sure everything is uppercase
	std::transform(str.begin(), str.end(), str.begin(), ::toupper);

	// Remove extraneous spaces
	if (str.at(0) == ' ')
		str.erase(0, 1);
	if (str.at(str.length()-1) == ' ')
		str = str.substr(0, str.length()-1);

	firstSpace = str.find_first_of(" ");

	firstDigit = str.find_first_of("0123456789");
	lastDigit  =  str.find_last_of("0123456789");

	lastChar   =  str.find_last_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ");

	// Split into Department, Number, and Section

	// pull out the department string
	if (firstSpace == string::npos) // if there is no space
		d = str.substr(0, firstDigit);
	else
		d = str.substr(0, firstSpace); // there is a space

	// check for one of those dastardly split departments
	if (d.find('/') != string::npos) {
		d1 = d.substr(0,2);
		d2 = d.substr(3,2);
	}

	n = str.substr(firstDigit, str.length());

	if (!isdigit(n[n.length()-1]))
		n = str.substr(firstDigit, n.length()-1);

	num = stringToInt(n);

	if (lastChar > lastDigit) // there is a section
		s = str[lastChar];

	// cout << "Parsed '" << str << "' to get '";
	// cout << d << " ";
	// if (!d1.empty() && !d2.empty())
		// cout << "(" << d1 << " " << d2 << ") ";
	// cout << n << s << "'." << endl;

	init(Department(d), num, s);
	if (!d1.empty() && !d2.empty()) {
		departments.clear();
		departments.push_back(Department(d1));
		departments.push_back(Department(d2));
	}
	// cout << *this << endl;
}
ID::ID(string dn, string s) {
	ID(dn+s);
}
ID::ID(string d, string n, string s) {
	ID(d + n + s);
}
ID::ID(Department d, int n, string s) {
	init(d, n, s);
}

void ID::init(Department d, int n, string s) {
	departments.push_back(d);
	number = n;
	section = s;
}

void ID::copy(const ID& c) {
	departments = c.departments;
	number = c.number;
	section = c.section;
}

Department ID::getDepartment(int i = 0) {
	return departments.at(i);
}

const Department ID::getDepartment_const(int i = 0) {
	return departments.at(i);
}

int ID::getNumber() {
	return number;
}

string ID::getSection() {
	return section;
}

bool operator== (const ID &i1, const ID &i2) {
    return ((i1.departments[0] == i2.departments[0]) && (i1.number == i2.number) && (i1.section == i2.section));
}

bool operator!= (ID &i1, ID &i2) {
    return !(i1 == i2);
}

bool operator< (const ID &i1, const ID &i2) {
	return (i1.departments.at(0) < i2.departments.at(0));
}

ostream& ID::getData(ostream& os) {
	for (vector<Department>::iterator i = departments.begin(); i != departments.end(); ++i) {
		if (departments.size() == 1)
			os << i->getName();
		else {
			os << i->getName();
			if (i != departments.end()-1)
				os << "/";
		}
	}
	os << " ";
	os << number;
	if (!section.empty())
		os << "[" << section << "]";
	return os;
}

ostream& operator<<(ostream& os, ID& item) {
	return item.getData(os);
}

void ID::display() {
	cout << *this << endl;
}
<|endoftext|>


<commit_before>#ifndef H_EXTENSIONS_CUTEHMI_MODBUS_2_INCLUDE_CUTEHMI_MODBUS_EXCEPTION_HPP
#define H_EXTENSIONS_CUTEHMI_MODBUS_2_INCLUDE_CUTEHMI_MODBUS_EXCEPTION_HPP

#include "internal/common.hpp"

#include <cutehmi/ExceptionMixin.hpp>

namespace cutehmi {
namespace modbus {

class Exception:
	public ExceptionMixin<Exception>
{
		typedef ExceptionMixin<Exception> Parent;

	public:
		using Parent::Parent;

		~Exception() override = default;
};

}
}

#endif

//(c)C: Copyright © 2019, Michał Policht <michal@policht.pl>. All rights reserved.
//(c)C: This file is a part of CuteHMI.
//(c)C: CuteHMI 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 3 of the License, or (at your option) any later version.
//(c)C: CuteHMI 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.
//(c)C: You should have received a copy of the GNU Lesser General Public License along with CuteHMI.  If not, see <https://www.gnu.org/licenses/>.
<commit_msg>Mark Exception with export API macro and remove redundant destructor entry.<commit_after>#ifndef H_EXTENSIONS_CUTEHMI_MODBUS_2_INCLUDE_CUTEHMI_MODBUS_EXCEPTION_HPP
#define H_EXTENSIONS_CUTEHMI_MODBUS_2_INCLUDE_CUTEHMI_MODBUS_EXCEPTION_HPP

#include "internal/common.hpp"

#include <cutehmi/ExceptionMixin.hpp>

namespace cutehmi {
namespace modbus {

class CUTEHMI_MODBUS_API Exception:
	public ExceptionMixin<Exception>
{
		typedef ExceptionMixin<Exception> Parent;

	public:
		using Parent::Parent;
};

}
}

#endif

//(c)C: Copyright © 2019, Michał Policht <michal@policht.pl>. All rights reserved.
//(c)C: This file is a part of CuteHMI.
//(c)C: CuteHMI 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 3 of the License, or (at your option) any later version.
//(c)C: CuteHMI 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.
//(c)C: You should have received a copy of the GNU Lesser General Public License along with CuteHMI.  If not, see <https://www.gnu.org/licenses/>.
<|endoftext|>


<commit_before>// Copyright © 2012-2014 Inria, Written by Lénaïc Bagnères, lenaic.bagneres@inria.fr

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

#ifndef HNC_SCHEDULER_ITERATION_HPP
#define HNC_SCHEDULER_ITERATION_HPP

#include <chrono>
#include <vector>
#include <algorithm>
#include <initializer_list>

namespace hnc
{
	namespace scheduler
	{
		/**
		 * @brief Excute different versions of for loop. Split iterations, benchmark versions and select the version with the min time. No useless computing, no rollback.
		 *
		 * @code
		   #include <hnc/scheduler.hpp>
		   @endcode
		 *
		 * You have:
		 * - a number of iterations (betwwen first and last with a step)
		 * - different versions of the same computing (per iteration)
		 *
		 * You do not know the best version. Worse, the best version is not the same in all contexts (the best version deplasts on another computing in the computer).
		 *
		 * This function take the number of iterations, several versions and do this until there are no iteration anymore:
		 * 1. execute all versions on few iterations (sample)
		 * 2. execute the last best version on several iterations
		 *
		 * Example with classic function:
		 * @code
		   int func_value = 0;

		   void func0(int const & first, int const & last)
		   {
		   	for (int i = first; i < last; ++i)
		   	{
		   		++func_value;
		   	}
		   }

		   void func1(int const & first, int const & last)
		   {
		   	for (int i = first; i < last; ++i)
		   	{
		   		++func_value;
		   	}
		   }

		   int main()
		   {
		   	// Compute
		   	hnc::scheduler::iteration(0, 42, {func0, func1});

		   	// func_value value is 42

		   	return 0;
		   }
		   @endcode
		 *
		 * Example with functor object and lambda :
		 * @code
		   class fonctor
		   {
		   public:
		   	fonctor(std::vector<std::vector<int>> & tab2D) : r_tab2D(tab2D) { }

		   	void operator()(std::size_t const & first, std::size_t const & last)
		   	{
		   		for (std::size_t i = first; i < last; ++i)
		   		{
		   			for (std::size_t j = 0; j < r_tab2D.size(); ++j)
		   			{
		   				r_tab2D[i][j] += i * j;
		   			}
		   		}
		   	}

		   private:
		   	std::vector<std::vector<int>> & r_tab2D;
		   };

		   int main()
		   {
		   	std::size_t const N = 200;

		   	// A 2D array [N][N]
		   	std::vector<std::vector<int>> tab2D(N, std::vector<int>(N, 0));

		   	auto lambda = [&](std::size_t const & first, std::size_t const & last) -> void
		   	{
		   		for (j = 0; j < tab2D.size(); j += 7)
		   		{
		   			for (i = first; i < last; ++i)
		   			{
		   				tab2D[i][j] += i * j;
		   			}
		   		}
		   	};

		   	// Compute
		   	hnc::scheduler::iteration(std::size_t(0), N, {fonctor(tab2D), lambda});

		   	return 0;
		   }
		   @endcode
		 *
		 * @param[in] first         First iteration
		 * @param[in] last          Last iteration (not included)
		 * @param[in] versions      Functions with a first and a last and with the same computing
		 * @param[in] nb_it_sample  Number of iterations for sample phases
		 * @param[in] nb_it_compute Number of iterations for compute phases
		 * @param[in] step          Incrementation in the loop (1 by default)
		 *
		 * Function type (in versions) is a std::function, it can be:
		 * - a function without parameter
		 * - a functor object
		 * - a lambda expression without parameter
		 *
		 * @pre The function type signature is (it_t const &, it_t const &)
		 * @pre All versions do the same computing
		 * @pre One iteration in a random version for one iteration id is the same result as another random version for the same id iteration
		 *
		 * @warning If the incrementation (step) have not the good value, the number of iterations computed is not correct
		 * @warning Be carefull about versions if you need the final iterator (you can not mix loop and reverse loop for example)
		 */
		template <class it_t, class incr_t = std::size_t>
		inline void iteration
		(
			it_t first,
			it_t const & last,
			std::vector<std::function<void(it_t const &, it_t const &)>> const & versions,
			it_t const & nb_it_sample = 2 * 4 * 6,
			it_t const & nb_it_compute = (2 * 4 * 6) * 10,
			incr_t const & step = 1
		)
		{
			while (first < last)
			{
				// Index of the best version
				auto best_time = std::numeric_limits<std::chrono::steady_clock::duration::rep>::max();
				std::size_t best_version = 0;

				// Samples
				for (std::size_t i = 0; i < versions.size() && first < last; ++i)
				{
					// Compute
					auto time_first = std::chrono::steady_clock::now();
					{
						versions[i](first, std::min(it_t(first) + it_t(nb_it_sample) * it_t(step), last));
					}
					auto time_last = std::chrono::steady_clock::now();

					// Save best version
					auto const time = (time_last - time_first).count();
					if (time < best_time)
					{
						best_time = time;
						best_version = i;
					}

					// Next iterations
					first += it_t(nb_it_sample) * it_t(step);
				}

				// Compute
				if (first < last)
				{
					// Compute
					versions[best_version](first, std::min(it_t(first) + it_t(nb_it_compute) * it_t(step), last));
					// Next iterations
					first += it_t(nb_it_compute) * it_t(step);
				}
			}
		}
	}
}

#endif
<commit_msg>Fix include in hnc/scheduler/iteration.hpp<commit_after>// Copyright © 2012-2014 Inria, Written by Lénaïc Bagnères, lenaic.bagneres@inria.fr

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

#ifndef HNC_SCHEDULER_ITERATION_HPP
#define HNC_SCHEDULER_ITERATION_HPP

#include <chrono>
#include <vector>
#include <algorithm>
#include <initializer_list>
#include <functional>

namespace hnc
{
	namespace scheduler
	{
		/**
		 * @brief Excute different versions of for loop. Split iterations, benchmark versions and select the version with the min time. No useless computing, no rollback.
		 *
		 * @code
		   #include <hnc/scheduler.hpp>
		   @endcode
		 *
		 * You have:
		 * - a number of iterations (betwwen first and last with a step)
		 * - different versions of the same computing (per iteration)
		 *
		 * You do not know the best version. Worse, the best version is not the same in all contexts (the best version deplasts on another computing in the computer).
		 *
		 * This function take the number of iterations, several versions and do this until there are no iteration anymore:
		 * 1. execute all versions on few iterations (sample)
		 * 2. execute the last best version on several iterations
		 *
		 * Example with classic function:
		 * @code
		   int func_value = 0;

		   void func0(int const & first, int const & last)
		   {
		   	for (int i = first; i < last; ++i)
		   	{
		   		++func_value;
		   	}
		   }

		   void func1(int const & first, int const & last)
		   {
		   	for (int i = first; i < last; ++i)
		   	{
		   		++func_value;
		   	}
		   }

		   int main()
		   {
		   	// Compute
		   	hnc::scheduler::iteration(0, 42, {func0, func1});

		   	// func_value value is 42

		   	return 0;
		   }
		   @endcode
		 *
		 * Example with functor object and lambda :
		 * @code
		   class fonctor
		   {
		   public:
		   	fonctor(std::vector<std::vector<int>> & tab2D) : r_tab2D(tab2D) { }

		   	void operator()(std::size_t const & first, std::size_t const & last)
		   	{
		   		for (std::size_t i = first; i < last; ++i)
		   		{
		   			for (std::size_t j = 0; j < r_tab2D.size(); ++j)
		   			{
		   				r_tab2D[i][j] += i * j;
		   			}
		   		}
		   	}

		   private:
		   	std::vector<std::vector<int>> & r_tab2D;
		   };

		   int main()
		   {
		   	std::size_t const N = 200;

		   	// A 2D array [N][N]
		   	std::vector<std::vector<int>> tab2D(N, std::vector<int>(N, 0));

		   	auto lambda = [&](std::size_t const & first, std::size_t const & last) -> void
		   	{
		   		for (j = 0; j < tab2D.size(); j += 7)
		   		{
		   			for (i = first; i < last; ++i)
		   			{
		   				tab2D[i][j] += i * j;
		   			}
		   		}
		   	};

		   	// Compute
		   	hnc::scheduler::iteration(std::size_t(0), N, {fonctor(tab2D), lambda});

		   	return 0;
		   }
		   @endcode
		 *
		 * @param[in] first         First iteration
		 * @param[in] last          Last iteration (not included)
		 * @param[in] versions      Functions with a first and a last and with the same computing
		 * @param[in] nb_it_sample  Number of iterations for sample phases
		 * @param[in] nb_it_compute Number of iterations for compute phases
		 * @param[in] step          Incrementation in the loop (1 by default)
		 *
		 * Function type (in versions) is a std::function, it can be:
		 * - a function without parameter
		 * - a functor object
		 * - a lambda expression without parameter
		 *
		 * @pre The function type signature is (it_t const &, it_t const &)
		 * @pre All versions do the same computing
		 * @pre One iteration in a random version for one iteration id is the same result as another random version for the same id iteration
		 *
		 * @warning If the incrementation (step) have not the good value, the number of iterations computed is not correct
		 * @warning Be carefull about versions if you need the final iterator (you can not mix loop and reverse loop for example)
		 */
		template <class it_t, class incr_t = std::size_t>
		inline void iteration
		(
			it_t first,
			it_t const & last,
			std::vector<std::function<void(it_t const &, it_t const &)>> const & versions,
			it_t const & nb_it_sample = 2 * 4 * 6,
			it_t const & nb_it_compute = (2 * 4 * 6) * 10,
			incr_t const & step = 1
		)
		{
			while (first < last)
			{
				// Index of the best version
				auto best_time = std::numeric_limits<std::chrono::steady_clock::duration::rep>::max();
				std::size_t best_version = 0;

				// Samples
				for (std::size_t i = 0; i < versions.size() && first < last; ++i)
				{
					// Compute
					auto time_first = std::chrono::steady_clock::now();
					{
						versions[i](first, std::min(it_t(first) + it_t(nb_it_sample) * it_t(step), last));
					}
					auto time_last = std::chrono::steady_clock::now();

					// Save best version
					auto const time = (time_last - time_first).count();
					if (time < best_time)
					{
						best_time = time;
						best_version = i;
					}

					// Next iterations
					first += it_t(nb_it_sample) * it_t(step);
				}

				// Compute
				if (first < last)
				{
					// Compute
					versions[best_version](first, std::min(it_t(first) + it_t(nb_it_compute) * it_t(step), last));
					// Next iterations
					first += it_t(nb_it_compute) * it_t(step);
				}
			}
		}
	}
}

#endif
<|endoftext|>


<commit_before>/*

Copyright (c) 2010-2014, Arvid Norberg
All rights reserved.

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

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_BUILD_CONFIG_HPP_INCLUDED
#define TORRENT_BUILD_CONFIG_HPP_INCLUDED

#include "libtorrent/config.hpp"
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/stringize.hpp>

#if TORRENT_USE_IPV6
#define TORRENT_CFG_IPV6 ipv6_
#else
#define TORRENT_CFG_IPV6 noipv6_-
#endif

#ifdef TORRENT_NO_DEPRECATE
#define TORRENT_CFG_DEPR nodeprecate_
#else
#define TORRENT_CFG_DEPR deprecated_
#endif

#define TORRENT_CFG \
	BOOST_PP_CAT(TORRENT_CFG_IPV6, \
	TORRENT_CFG_DEPR)

#define TORRENT_CFG_STRING BOOST_PP_STRINGIZE(TORRENT_CFG)

#endif

<commit_msg>fix typo<commit_after>/*

Copyright (c) 2010-2014, Arvid Norberg
All rights reserved.

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

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_BUILD_CONFIG_HPP_INCLUDED
#define TORRENT_BUILD_CONFIG_HPP_INCLUDED

#include "libtorrent/config.hpp"
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/stringize.hpp>

#if TORRENT_USE_IPV6
#define TORRENT_CFG_IPV6 ipv6_
#else
#define TORRENT_CFG_IPV6 noipv6_
#endif

#ifdef TORRENT_NO_DEPRECATE
#define TORRENT_CFG_DEPR nodeprecate_
#else
#define TORRENT_CFG_DEPR deprecated_
#endif

#define TORRENT_CFG \
	BOOST_PP_CAT(TORRENT_CFG_IPV6, \
	TORRENT_CFG_DEPR)

#define TORRENT_CFG_STRING BOOST_PP_STRINGIZE(TORRENT_CFG)

#endif

<|endoftext|>


<commit_before>//! \brief A collection of constants for Nova to use

#pragma once

#include "nova_renderer/memory/bytes.hpp"

using namespace nova::mem::operators;

namespace nova::renderer {
    constexpr const char* MODEL_MATRIX_BUFFER_NAME = "NovaModelMatrixUBO";
    constexpr const char* PER_FRAME_DATA_NAME = "NovaPerFrameUBO";

    constexpr uint32_t AMD_PCI_VENDOR_ID = 0x1022;
    constexpr uint32_t INTEL_PCI_VENDOR_ID = 8086;
    constexpr uint32_t NVIDIA_PCI_VENDOR_ID = 0x10DE;

    constexpr uint32_t NUM_IN_FLIGHT_FRAMES = 3;

    constexpr mem::Bytes PER_FRAME_MEMORY_SIZE = 2_mb;

    constexpr const char* RENDERPACK_DIRECTORY = "shaderpacks";
    constexpr const char* MATERIALS_DIRECTORY = "materials";
    constexpr const char* SHADERS_DIRECTORY = "shaders";
    constexpr const char* RENDERPACK_DESCRIPTOR_FILE = "renderpack.json";
    constexpr const char* RESOURCES_FILE = "resources.json";
    constexpr const char* MATERIAL_FILE_EXTENSION = ".mat";

    /*!
     * \brief Name of Nova's white texture
     *
     * The white texture is a 4x4 texture where each texel has the RGBA value of (1, 1, 1, 1)
     */
    constexpr const char* WHITE_TEXTURE_NAME = "NovaWhiteTexture";

    /*!
     * \brief Name of Nova's gray texture
     *
     * The gray texture is a 4x4 texture where each texel has the RGBA value of (0.5, 0.5, 0.5, 0.5)
     */
    constexpr const char* GRAY_TEXTURE_NAME = "NovaGrayTexture";

    /*!
     * \brief Name of Nova's black texture
     *
     * The black texture is a 4x4 texture where each texel has the RGBA value of (0, 0, 0, 0)
     */
    constexpr const char* BLACK_TEXTURE_NAME = "NovaBlackTexture";

    /*!
     * \brief Name of the builtin pass Nova uses to render UI
     *
     * This pass reads from the writes to the backbuffer. UI renderpasses are expected to use something like blending or the stencil butter
     * to layer the UI on top of the 3D scene.
     */
    constexpr const char* UI_RENDER_PASS_NAME = "NovaUI";

    constexpr const char* UI_MATERIAL_NAME = "BestFriendGUI";

    constexpr const char* UI_MATERIAL_PASS_NAME = "BestFriendGUI";

    /*!
     * \brief Name of the render target that renderpacks must render to
     */
    constexpr const char* SCENE_OUTPUT_RT_NAME = "NovaSceneOutput";

    /*!
     * \brief Name of the UI render target
     *
     * All UI renderpasses MUST will render to this render target
     */
    constexpr const char* UI_OUTPUT_RT_NAME = "NovaUiOutput";

    /*!
     * \brief Name of the backbuffer
     *
     * Nova presents the backbuffer to the screen every frame. The builtin UI render pass adds the UI to the backbuffer after the rest of
     * the rendergraph has finished
     */
    constexpr const char* BACKBUFFER_NAME = "NovaBackbuffer";
} // namespace nova::renderer
<commit_msg>[util] Remove a Best Friend constaant that snuck in<commit_after>//! \brief A collection of constants for Nova to use

#pragma once

#include "nova_renderer/memory/bytes.hpp"

using namespace nova::mem::operators;

namespace nova::renderer {
    constexpr const char* MODEL_MATRIX_BUFFER_NAME = "NovaModelMatrixUBO";
    constexpr const char* PER_FRAME_DATA_NAME = "NovaPerFrameUBO";

    constexpr uint32_t AMD_PCI_VENDOR_ID = 0x1022;
    constexpr uint32_t INTEL_PCI_VENDOR_ID = 8086;
    constexpr uint32_t NVIDIA_PCI_VENDOR_ID = 0x10DE;

    constexpr uint32_t NUM_IN_FLIGHT_FRAMES = 3;

    constexpr mem::Bytes PER_FRAME_MEMORY_SIZE = 2_mb;

    constexpr const char* RENDERPACK_DIRECTORY = "shaderpacks";
    constexpr const char* MATERIALS_DIRECTORY = "materials";
    constexpr const char* SHADERS_DIRECTORY = "shaders";
    constexpr const char* RENDERPACK_DESCRIPTOR_FILE = "renderpack.json";
    constexpr const char* RESOURCES_FILE = "resources.json";
    constexpr const char* MATERIAL_FILE_EXTENSION = ".mat";

    /*!
     * \brief Name of Nova's white texture
     *
     * The white texture is a 4x4 texture where each texel has the RGBA value of (1, 1, 1, 1)
     */
    constexpr const char* WHITE_TEXTURE_NAME = "NovaWhiteTexture";

    /*!
     * \brief Name of Nova's gray texture
     *
     * The gray texture is a 4x4 texture where each texel has the RGBA value of (0.5, 0.5, 0.5, 0.5)
     */
    constexpr const char* GRAY_TEXTURE_NAME = "NovaGrayTexture";

    /*!
     * \brief Name of Nova's black texture
     *
     * The black texture is a 4x4 texture where each texel has the RGBA value of (0, 0, 0, 0)
     */
    constexpr const char* BLACK_TEXTURE_NAME = "NovaBlackTexture";

    /*!
     * \brief Name of the builtin pass Nova uses to render UI
     *
     * This pass reads from the writes to the backbuffer. UI renderpasses are expected to use something like blending or the stencil butter
     * to layer the UI on top of the 3D scene.
     */
    constexpr const char* UI_RENDER_PASS_NAME = "NovaUI";

    /*!
     * \brief Name of the renderpass that outputs to the backbuffer
     */
    constexpr const char* BACKBUFFER_OUTPUT_RENDER_PASS_NAME = "BackbufferOutput";

    /*!
     * \brief Name of the render target that renderpacks must render to
     */
    constexpr const char* SCENE_OUTPUT_RT_NAME = "NovaSceneOutput";

    /*!
     * \brief Name of the UI render target
     *
     * All UI renderpasses MUST will render to this render target
     */
    constexpr const char* UI_OUTPUT_RT_NAME = "NovaUiOutput";

    /*!
     * \brief Name of the backbuffer
     *
     * Nova presents the backbuffer to the screen every frame. The builtin UI render pass adds the UI to the backbuffer after the rest of
     * the rendergraph has finished
     */
    constexpr const char* BACKBUFFER_NAME = "NovaBackbuffer";
} // namespace nova::renderer
<|endoftext|>


<commit_before>#pragma once

#include <deque>
#include <forward_list>
#include <list>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#ifdef PAJLADA_SETTINGS_BOOST_OPTIONAL
#include <boost/optional.hpp>
#else
#include <optional>
#endif

namespace pajlada {

namespace Settings {

#ifdef PAJLADA_SETTINGS_BOOST_OPTIONAL
    template <typename T>
    using OptionalType = boost::optional<T>;
    const boost::none_t OptionalNull = boost::none;
#else
    template <typename T>
    using OptionalType = std::optional<T>;
    const std::nullopt_t OptionalNull = std::nullopt;
#endif

template <typename Type>
struct ValueResult {
    OptionalType<Type> value;
    int updateIteration;
};

template <typename Type>
inline bool
operator==(const ValueResult<Type> &lhs, const ValueResult<Type> &rhs)
{
    return std::tie(lhs.value, lhs.updateIteration) ==
           std::tie(rhs.value, rhs.updateIteration);
}

enum class SettingOption : uint32_t {
    DoNotWriteToJSON = (1ull << 1ull),

    /// A remote setting is a setting that is never saved locally, nor registered locally with any callbacks or anything
    Remote = (1ull << 2ull),

    Default = 0,
};

inline SettingOption
operator|(const SettingOption &lhs, const SettingOption &rhs)
{
    return static_cast<SettingOption>(
        (static_cast<uint64_t>(lhs) | static_cast<uint64_t>(rhs)));
}

inline SettingOption operator&(const SettingOption &lhs,
                               const SettingOption &rhs)
{
    return static_cast<SettingOption>(
        (static_cast<uint64_t>(lhs) & static_cast<uint64_t>(rhs)));
}

}  // namespace Settings

// specialize a type for all of the STL containers.
namespace is_stl_container_impl {

template <typename T>
struct is_stl_container : std::false_type {
};
template <typename T, std::size_t N>
struct is_stl_container<std::array<T, N>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::vector<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::deque<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::list<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::forward_list<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::set<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::multiset<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::map<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::multimap<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::unordered_set<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::unordered_multiset<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::unordered_map<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::unordered_multimap<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::stack<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::queue<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::priority_queue<Args...>> : std::true_type {
};

}  // namespace is_stl_container_impl

// type trait to utilize the implementation type traits as well as decay the type
template <typename T>
struct is_stl_container {
    static constexpr bool const value =
        is_stl_container_impl::is_stl_container<std::decay_t<T>>::value;
};

}  // namespace pajlada
<commit_msg>reformat<commit_after>#pragma once

#include <deque>
#include <forward_list>
#include <list>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#ifdef PAJLADA_SETTINGS_BOOST_OPTIONAL
#include <boost/optional.hpp>
#else
#include <optional>
#endif

namespace pajlada {

namespace Settings {

#ifdef PAJLADA_SETTINGS_BOOST_OPTIONAL
template <typename T>
using OptionalType = boost::optional<T>;
const boost::none_t OptionalNull = boost::none;
#else
template <typename T>
using OptionalType = std::optional<T>;
const std::nullopt_t OptionalNull = std::nullopt;
#endif

template <typename Type>
struct ValueResult {
    OptionalType<Type> value;
    int updateIteration;
};

template <typename Type>
inline bool
operator==(const ValueResult<Type> &lhs, const ValueResult<Type> &rhs)
{
    return std::tie(lhs.value, lhs.updateIteration) ==
           std::tie(rhs.value, rhs.updateIteration);
}

enum class SettingOption : uint32_t {
    DoNotWriteToJSON = (1ull << 1ull),

    /// A remote setting is a setting that is never saved locally, nor registered locally with any callbacks or anything
    Remote = (1ull << 2ull),

    Default = 0,
};

inline SettingOption
operator|(const SettingOption &lhs, const SettingOption &rhs)
{
    return static_cast<SettingOption>(
        (static_cast<uint64_t>(lhs) | static_cast<uint64_t>(rhs)));
}

inline SettingOption operator&(const SettingOption &lhs,
                               const SettingOption &rhs)
{
    return static_cast<SettingOption>(
        (static_cast<uint64_t>(lhs) & static_cast<uint64_t>(rhs)));
}

}  // namespace Settings

// specialize a type for all of the STL containers.
namespace is_stl_container_impl {

template <typename T>
struct is_stl_container : std::false_type {
};
template <typename T, std::size_t N>
struct is_stl_container<std::array<T, N>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::vector<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::deque<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::list<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::forward_list<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::set<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::multiset<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::map<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::multimap<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::unordered_set<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::unordered_multiset<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::unordered_map<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::unordered_multimap<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::stack<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::queue<Args...>> : std::true_type {
};
template <typename... Args>
struct is_stl_container<std::priority_queue<Args...>> : std::true_type {
};

}  // namespace is_stl_container_impl

// type trait to utilize the implementation type traits as well as decay the type
template <typename T>
struct is_stl_container {
    static constexpr bool const value =
        is_stl_container_impl::is_stl_container<std::decay_t<T>>::value;
};

}  // namespace pajlada
<|endoftext|>


<commit_before>/**
 ** \file object/urbi-exception.hxx
 ** \brief Implementation of UrbiException
 */

#ifndef OBJECT_URBI_EXCEPTION_HXX
# define OBJECT_URBI_EXCEPTION_HXX

# include <boost/format.hpp>

namespace object
{

  inline
  LookupError::LookupError (libport::Symbol slot)
    : UrbiException ((boost::format ("lookup failed: %1%")
		      % slot.name_get()).str())
  {
  }

  inline
  RedefinitionError::RedefinitionError (libport::Symbol slot)
    : UrbiException ((boost::format ("slot redefinition: %1%")
		      % slot.name_get()).str())
  {
  }

  inline
  PrimitiveError::PrimitiveError (const libport::Symbol primitive,
				  const std::string& msg)
    : UrbiException(msg, primitive)
  {
  }

  inline
  StackExhaustedError::StackExhaustedError(const std::string& msg)
    : UrbiException(msg)
  {
  }

  inline
  WrongArgumentType::WrongArgumentType(const std::string& formal,
                                       const std::string& effective,
                                       const libport::Symbol fun)
    : UrbiException (std::string("unexpected argument type `")
		     + effective + "', expected `"
		     + formal + '\'',
		     fun)
  {
  }

  inline
  WrongArgumentType::WrongArgumentType (const libport::Symbol fun)
    : UrbiException("unexpected void", fun)
  {
  }

  inline
  WrongArgumentCount::WrongArgumentCount(unsigned formal,
                                         unsigned effective,
                                         const libport::Symbol fun)
    : UrbiException((boost::format ("expected %1% arguments, given %2%")
		      % (formal)
		      % (effective)).str (),
		     fun)
  {
  }

  inline
  WrongArgumentCount::WrongArgumentCount(unsigned minformal,
                                         unsigned maxformal,
                                         unsigned effective,
                                         const libport::Symbol fun)
    : UrbiException((boost::format("expected between %1% and %2% arguments, "
                                   "given %3%")
                     % (minformal-1)
                     % (maxformal-1)
                     % (effective-1)).str(),
                    fun)
  {
  }

  inline
  BadInteger::BadInteger(libport::ufloat effective, const libport::Symbol fun,
			 std::string fmt)
    : UrbiException((boost::format(fmt)
                     % effective).str(),
                    fun)
  {
  }

  inline
  ImplicitTagComponentError::ImplicitTagComponentError(const ast::loc& l)
    : UrbiException("illegal component for implicit tag", l)
  {
  }

  inline
  SchedulingError::SchedulingError(const std::string& msg)
    : UrbiException(msg)
  {
  }

  inline
  InternalError::InternalError(const std::string& msg)
    : UrbiException(msg)
  {
  }

  inline
  ParserError::ParserError(const ast::loc& loc, const std::string& msg)
    : UrbiException(msg, loc)
  {
  }

  inline
  void
  check_arg_count(unsigned formal, unsigned effective,
                  const libport::Symbol fun)
  {
    if (formal != effective)
      throw WrongArgumentCount(formal, effective, fun);
  }

  inline
  void
  check_arg_count(unsigned minformal, unsigned maxformal,
                  unsigned effective, const libport::Symbol fun)
  {
    if (effective < minformal || maxformal < effective)
      throw WrongArgumentCount(minformal, maxformal, effective, fun);
  }

  inline bool
  UrbiException::was_displayed() const
  {
    return displayed_;
  }

  inline void
  UrbiException::set_displayed()
  {
    displayed_ = true;
  }
} // namespace object

#endif //! OBJECT_URBI_EXCEPTION_HXX
<commit_msg>Print the right numbers in error message.<commit_after>/**
 ** \file object/urbi-exception.hxx
 ** \brief Implementation of UrbiException
 */

#ifndef OBJECT_URBI_EXCEPTION_HXX
# define OBJECT_URBI_EXCEPTION_HXX

# include <boost/format.hpp>

namespace object
{

  inline
  LookupError::LookupError (libport::Symbol slot)
    : UrbiException ((boost::format ("lookup failed: %1%")
		      % slot.name_get()).str())
  {
  }

  inline
  RedefinitionError::RedefinitionError (libport::Symbol slot)
    : UrbiException ((boost::format ("slot redefinition: %1%")
		      % slot.name_get()).str())
  {
  }

  inline
  PrimitiveError::PrimitiveError (const libport::Symbol primitive,
				  const std::string& msg)
    : UrbiException(msg, primitive)
  {
  }

  inline
  StackExhaustedError::StackExhaustedError(const std::string& msg)
    : UrbiException(msg)
  {
  }

  inline
  WrongArgumentType::WrongArgumentType(const std::string& formal,
                                       const std::string& effective,
                                       const libport::Symbol fun)
    : UrbiException (std::string("unexpected argument type `")
		     + effective + "', expected `"
		     + formal + '\'',
		     fun)
  {
  }

  inline
  WrongArgumentType::WrongArgumentType (const libport::Symbol fun)
    : UrbiException("unexpected void", fun)
  {
  }

  inline
  WrongArgumentCount::WrongArgumentCount(unsigned formal,
                                         unsigned effective,
                                         const libport::Symbol fun)
    : UrbiException((boost::format ("expected %1% arguments, given %2%")
		      % (formal)
		      % (effective)).str (),
		     fun)
  {
  }

  inline
  WrongArgumentCount::WrongArgumentCount(unsigned minformal,
                                         unsigned maxformal,
                                         unsigned effective,
                                         const libport::Symbol fun)
    : UrbiException((boost::format("expected between %1% and %2% arguments, "
                                   "given %3%")
                     % minformal
                     % maxformal
                     % effective).str(),
                    fun)
  {
  }

  inline
  BadInteger::BadInteger(libport::ufloat effective, const libport::Symbol fun,
			 std::string fmt)
    : UrbiException((boost::format(fmt)
                     % effective).str(),
                    fun)
  {
  }

  inline
  ImplicitTagComponentError::ImplicitTagComponentError(const ast::loc& l)
    : UrbiException("illegal component for implicit tag", l)
  {
  }

  inline
  SchedulingError::SchedulingError(const std::string& msg)
    : UrbiException(msg)
  {
  }

  inline
  InternalError::InternalError(const std::string& msg)
    : UrbiException(msg)
  {
  }

  inline
  ParserError::ParserError(const ast::loc& loc, const std::string& msg)
    : UrbiException(msg, loc)
  {
  }

  inline
  void
  check_arg_count(unsigned formal, unsigned effective,
                  const libport::Symbol fun)
  {
    if (formal != effective)
      throw WrongArgumentCount(formal, effective, fun);
  }

  inline
  void
  check_arg_count(unsigned minformal, unsigned maxformal,
                  unsigned effective, const libport::Symbol fun)
  {
    if (effective < minformal || maxformal < effective)
      throw WrongArgumentCount(minformal, maxformal, effective, fun);
  }

  inline bool
  UrbiException::was_displayed() const
  {
    return displayed_;
  }

  inline void
  UrbiException::set_displayed()
  {
    displayed_ = true;
  }
} // namespace object

#endif //! OBJECT_URBI_EXCEPTION_HXX
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * 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
 * OpenSceneGraph Public License for more details.
*/

#include <osgGA/GUIEventHandler>
#include <osgGA/EventVisitor>

using namespace osgGA;

void GUIEventHandler::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
    osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(nv);
    if (ev && ev->getActionAdapter() && !ev->getEvents().empty())
    {
        for(osgGA::EventQueue::Events::iterator itr = ev->getEvents().begin();
            itr != ev->getEvents().end();
            ++itr)
        {
            handleWithCheckAgainstIgnoreHandledEventsMask(*(*itr), *(ev->getActionAdapter()), node, nv);
        }
    }
    if (node->getNumChildrenRequiringEventTraversal()>0) traverse(node,nv);
}

void GUIEventHandler::event(osg::NodeVisitor* nv, osg::Drawable* drawable)
{
    osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(nv);
    if (ev && ev->getActionAdapter() && !ev->getEvents().empty())
    {
        for(osgGA::EventQueue::Events::iterator itr = ev->getEvents().begin();
            itr != ev->getEvents().end();
            ++itr)
        {
            handleWithCheckAgainstIgnoreHandledEventsMask(*(*itr), *(ev->getActionAdapter()), drawable, nv);
        }
    }
}

<commit_msg>From Serge Lages, "Currently if multiple event callbacks are nested on one node, only the first will be called. The proposed fix checks if there is a nested callback."<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * 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
 * OpenSceneGraph Public License for more details.
*/

#include <osgGA/GUIEventHandler>
#include <osgGA/EventVisitor>

using namespace osgGA;

void GUIEventHandler::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
    osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(nv);
    if (ev && ev->getActionAdapter() && !ev->getEvents().empty())
    {
        for(osgGA::EventQueue::Events::iterator itr = ev->getEvents().begin();
            itr != ev->getEvents().end();
            ++itr)
        {
            handleWithCheckAgainstIgnoreHandledEventsMask(*(*itr), *(ev->getActionAdapter()), node, nv);
        }
    }
    if (node->getNumChildrenRequiringEventTraversal()>0 || _nestedCallback.valid()) traverse(node,nv);
}

void GUIEventHandler::event(osg::NodeVisitor* nv, osg::Drawable* drawable)
{
    osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(nv);
    if (ev && ev->getActionAdapter() && !ev->getEvents().empty())
    {
        for(osgGA::EventQueue::Events::iterator itr = ev->getEvents().begin();
            itr != ev->getEvents().end();
            ++itr)
        {
            handleWithCheckAgainstIgnoreHandledEventsMask(*(*itr), *(ev->getActionAdapter()), drawable, nv);
        }
    }
}

<|endoftext|>


<commit_before>#include "gvki/Logger.h"
#include <cstdlib>
#include <cstdio>
#include <cassert>
#include <errno.h>
#include <iostream>
#include <iomanip>
#include <sstream>
#include "string.h"
#include "gvki/Debug.h"

// For mkdir(). FIXME: Make windows compatible
#include <sys/stat.h>
// For opendir(). FIXME: Make windows compatible
#include <dirent.h>

// For getcwd()
#include <unistd.h>
#define FILE_SEP "/"

using namespace std;
using namespace gvki;

// Maximum number of files or directories
// that can be created
static const int maxFiles = 10000;

Logger& Logger::Singleton()
{
    static Logger l;
    return l;
}

Logger::Logger()
{
    int count = 0;
    bool success= false;

    // FIXME: Reading from the environment probably doesn't belong in here
    // but it makes implementing the singleton a lot easier
    std::string directoryPrefix;

    const char* envTemp = getenv("GVKI_ROOT");
    if (envTemp)
    {
        DEBUG_MSG("Using GVKI_ROOT value as destination for directories");
        DIR* dh = opendir(envTemp);
        if (dh == NULL)
        {
            ERROR_MSG(strerror(errno) << ". Directory was :" << envTemp);
            exit(1);
        }
        else
            closedir(dh);

        directoryPrefix = envTemp;

    }
    else
    {
        // Use the current working directory
        DEBUG_MSG("Using current working directory as destination for directories");

        // FIXME: Hard-coding this size is gross
        char cwdArray[1024];
        char* cwdResult = getcwd(cwdArray, sizeof(cwdArray)/sizeof(char));
        if (!cwdResult)
        {
            ERROR_MSG(strerror(errno) << ". Could not read the current working directory");
            exit(1);
        }
        else
            directoryPrefix = cwdResult;

    }
    directoryPrefix += FILE_SEP "gvki";
    DEBUG_MSG("Directory prefix is \"" << directoryPrefix << "\"");

    // Keep trying a directoryPrefix name with a number as suffix
    // until we find an available one or we exhaust the maximum
    // allowed number
    while (count < maxFiles)
    {
        stringstream ss;
        ss <<  directoryPrefix << "-" << count;
        ++count;

        // Make the directoryPrefix
        if (mkdir(ss.str().c_str(), 0770) != 0)
        {
            if (errno != EEXIST)
            {
                ERROR_MSG(strerror(errno) << ". Directory was :" << directoryPrefix);
                exit(1);
            }

            // It already exists, try again
            continue;
        }

        this->directory = ss.str();
        success = true;
        break;
    }

    if (!success)
    {
        ERROR_MSG("Exhausted available directory names or couldn't create any");
        exit(1);
    }

    openLog();
}

void Logger::openLog()
{
    // FIXME: We should use mkstemp() or something
    std::stringstream ss;
    ss << directory << FILE_SEP << "log.json";
    output = new std::ofstream(ss.str().c_str(), std::ofstream::out | std::ofstream::ate);

    if (! output->good())
    {
        ERROR_MSG("Failed to create file (" << ss.str() <<  ") to write log to");
        exit(1);
    }

    // Start of JSON array
    *output << "[" << std::endl;
}

void Logger::closeLog()
{
    // End of JSON array
    *output << std::endl << "]";
    output->close();
}

Logger::~Logger()
{
    closeLog();
    delete output;
}

void Logger::dump(cl_kernel k)
{
    // Output JSON format defined by
    // http://multicore.doc.ic.ac.uk/tools/GPUVerify/docs/json_format.html
    KernelInfo& ki = kernels[k];

    static bool isFirst = true;

    if (!isFirst)
    {
        // Emit array element seperator
        // to seperate from previous dump
        *output << "," << endl;
        isFirst = false;
    }

    *output << "{" << endl << "\"language\": \"OpenCL\"," << endl;

    std::string kernelSourceFile = dumpKernelSource(ki);

    *output << "\"kernel_file\": \"" << kernelSourceFile << "\"," << endl;

    // Not officially supported but let's emit it anyway
    *output << "\"global_offset\": ";
    printJSONArray(ki.globalWorkOffset);
    *output << "," << endl;

    *output << "\"global_size\": ";
    printJSONArray(ki.globalWorkSize);
    *output << "," << endl;

    *output << "\"local_size\": ";
    printJSONArray(ki.localWorkSize);
    *output << "," << endl;

    assert(ki.globalWorkOffset.size() == ki.globalWorkSize.size() == ki.localWorkSize.size() &&
            "dimension mismatch");

    *output << "\"entry_point\": \"" << ki.entryPointName << "\"";

    // entry_point might be the last entry is there were no kernel args
    if (ki.arguments.size() == 0)
        *output << endl;
    else
    {
        *output << "," << endl << "\"kernel_arguments\": [ " << endl;
        for (int argIndex=0; argIndex < ki.arguments.size() ; ++argIndex)
        {
            printJSONKernelArgumentInfo(ki.arguments[argIndex]);
            if (argIndex != (ki.arguments.size() -1))
                *output << "," << endl;
        }
        *output << endl << "]" << endl;
    }

    *output << "}";
}

void Logger::printJSONArray(std::vector<size_t>& array)
{
    *output << "[ ";
    for (int index=0; index < array.size(); ++index)
    {
        *output << array[index];

        if (index != (array.size() -1))
            *output << ", ";
    }
    *output << "]";
}

void Logger::printJSONKernelArgumentInfo(ArgInfo& ai)
{
    *output << "{";
    if (ai.argValue == NULL)
    {
        // NULL was passed to clSetKernelArg()
        // That implies its for unallocated memory
        *output << "\"type\": \"array\",";

        // If the arg is for local memory
        if (ai.argSize != sizeof(cl_mem) && ai.argSize != sizeof(cl_sampler))
        {
            // We assume this means this arguments is for local memory
            // where size actually means the sizeof the underlying buffer
            // rather than the size of the type.
            *output << "\"size\" : " << ai.argSize;
        }
        *output << "}";
        return;
    }

    // FIXME:
    // Eurgh... the spec says
    // ```
    // If the argument is a buffer object, the arg_value pointer can be NULL or
    // point to a NULL value in which case a NULL value will be used as the
    // value for the argument declared as a pointer to __global or __constant
    // memory in the kernel.  ```
    //
    // This makes it impossible (seeing as we don't know which address space
    // the arguments are in) to work out the argument type once derefencing the
    // pointer and finding it's equal zero because it could be a scalar constant
    // (of value 0) or it could be an unintialised array!

    DEBUG_MSG("Note sizeof(cl_mem) == " << sizeof(cl_mem));
    // Hack:
    // It's hard to determine what type the argument is.
    // We can't dereference the void* to check if
    // it points to cl_mem we previously stored
    //
    // In some implementations cl_mem will be a pointer
    // which poses a risk if a scalar parameter of the same size
    // as the pointer type.
    if (ai.argSize == sizeof(cl_mem))
    {
       cl_mem mightBecl_mem = *((cl_mem*) ai.argValue);

       // We might be reading invalid data now
       if (buffers.count(mightBecl_mem) == 1)
       {
           // We're going to assume it's cl_mem that we saw before
           *output << "\"type\": \"array\",";
           BufferInfo& bi = buffers[mightBecl_mem];

           *output << "\"size\": " << bi.size << "}";
           return;
       }

    }

    // FIXME: Check for cl_sampler
    //

    // I guess it's scalar???
    *output << "\"type\": \"scalar\",";
    *output << " \"value\": \"0x";
    // Print the value as hex
    uint8_t* asByte = (uint8_t*) ai.argValue;
    for (int byteIndex=0; byteIndex < ai.argSize; ++byteIndex)
    {
       *output << setw(2) << setfill('0') << std::hex << asByte[byteIndex];
    }
    *output << "\"" << std::dec; //std::hex is sticky so switch back to decimal

    *output << "}";
    return;

}

static bool file_exists(std::string& name) {
	ifstream f(name.c_str());
	bool result = f.good();
	f.close();
	return result;
}

std::string Logger::dumpKernelSource(KernelInfo& ki)
{
    int count = 0;
    bool success = false;
    // FIXME: I really want a std::unique_ptr
    std::ofstream* kos = 0;
    std::string theKernelPath;
    while (count < maxFiles)
    {
        stringstream ss;
        ss << ki.entryPointName << "." << count << ".cl";

        ++count;

        std::string withDir = (directory + FILE_SEP) + ss.str();
        if (!file_exists(withDir))
        {
           kos = new std::ofstream(withDir.c_str());

           if (!kos->good())
           {
                kos->close();
                delete kos;
                continue;
           }

           success = true;
           theKernelPath = ss.str();
           break;
        }
    }

    if (!success)
    {
        ERROR_MSG("Failed to log kernel output");
        return std::string("FIXME");
    }

    // Write kernel source
    ProgramInfo& pi = programs[ki.program];

    for (vector<string>::const_iterator b = pi.sources.begin(), e = pi.sources.end(); b != e; ++b)
    {
        *kos << *b;
    }

    // Urgh this is bad, need RAII!
    kos->close();
    delete kos;
    return theKernelPath;
}
<commit_msg>Only emit global_offset when its non zero. This is to work around the fact that GPUVerify does not support this right now.<commit_after>#include "gvki/Logger.h"
#include <cstdlib>
#include <cstdio>
#include <cassert>
#include <errno.h>
#include <iostream>
#include <iomanip>
#include <sstream>
#include "string.h"
#include "gvki/Debug.h"

// For mkdir(). FIXME: Make windows compatible
#include <sys/stat.h>
// For opendir(). FIXME: Make windows compatible
#include <dirent.h>

// For getcwd()
#include <unistd.h>
#define FILE_SEP "/"

using namespace std;
using namespace gvki;

// Maximum number of files or directories
// that can be created
static const int maxFiles = 10000;

Logger& Logger::Singleton()
{
    static Logger l;
    return l;
}

Logger::Logger()
{
    int count = 0;
    bool success= false;

    // FIXME: Reading from the environment probably doesn't belong in here
    // but it makes implementing the singleton a lot easier
    std::string directoryPrefix;

    const char* envTemp = getenv("GVKI_ROOT");
    if (envTemp)
    {
        DEBUG_MSG("Using GVKI_ROOT value as destination for directories");
        DIR* dh = opendir(envTemp);
        if (dh == NULL)
        {
            ERROR_MSG(strerror(errno) << ". Directory was :" << envTemp);
            exit(1);
        }
        else
            closedir(dh);

        directoryPrefix = envTemp;

    }
    else
    {
        // Use the current working directory
        DEBUG_MSG("Using current working directory as destination for directories");

        // FIXME: Hard-coding this size is gross
        char cwdArray[1024];
        char* cwdResult = getcwd(cwdArray, sizeof(cwdArray)/sizeof(char));
        if (!cwdResult)
        {
            ERROR_MSG(strerror(errno) << ". Could not read the current working directory");
            exit(1);
        }
        else
            directoryPrefix = cwdResult;

    }
    directoryPrefix += FILE_SEP "gvki";
    DEBUG_MSG("Directory prefix is \"" << directoryPrefix << "\"");

    // Keep trying a directoryPrefix name with a number as suffix
    // until we find an available one or we exhaust the maximum
    // allowed number
    while (count < maxFiles)
    {
        stringstream ss;
        ss <<  directoryPrefix << "-" << count;
        ++count;

        // Make the directoryPrefix
        if (mkdir(ss.str().c_str(), 0770) != 0)
        {
            if (errno != EEXIST)
            {
                ERROR_MSG(strerror(errno) << ". Directory was :" << directoryPrefix);
                exit(1);
            }

            // It already exists, try again
            continue;
        }

        this->directory = ss.str();
        success = true;
        break;
    }

    if (!success)
    {
        ERROR_MSG("Exhausted available directory names or couldn't create any");
        exit(1);
    }

    openLog();
}

void Logger::openLog()
{
    // FIXME: We should use mkstemp() or something
    std::stringstream ss;
    ss << directory << FILE_SEP << "log.json";
    output = new std::ofstream(ss.str().c_str(), std::ofstream::out | std::ofstream::ate);

    if (! output->good())
    {
        ERROR_MSG("Failed to create file (" << ss.str() <<  ") to write log to");
        exit(1);
    }

    // Start of JSON array
    *output << "[" << std::endl;
}

void Logger::closeLog()
{
    // End of JSON array
    *output << std::endl << "]";
    output->close();
}

Logger::~Logger()
{
    closeLog();
    delete output;
}

void Logger::dump(cl_kernel k)
{
    // Output JSON format defined by
    // http://multicore.doc.ic.ac.uk/tools/GPUVerify/docs/json_format.html
    KernelInfo& ki = kernels[k];

    static bool isFirst = true;

    if (!isFirst)
    {
        // Emit array element seperator
        // to seperate from previous dump
        *output << "," << endl;
        isFirst = false;
    }

    *output << "{" << endl << "\"language\": \"OpenCL\"," << endl;

    std::string kernelSourceFile = dumpKernelSource(ki);

    *output << "\"kernel_file\": \"" << kernelSourceFile << "\"," << endl;

    // FIXME: Teach GPUVerify how to handle non zero global_offset
    // FIXME: Document this json attribute!
    // Only emit global_offset if its non zero
    bool hasNonZeroGlobalOffset = false;
    for (int index=0; index < ki.globalWorkOffset.size() ; ++index)
    {
        if (ki.globalWorkOffset[index] != 0)
            hasNonZeroGlobalOffset = true;
    }
    if (hasNonZeroGlobalOffset)
    {
        *output << "\"global_offset\": ";
        printJSONArray(ki.globalWorkOffset);
        *output << "," << endl;
    }

    *output << "\"global_size\": ";
    printJSONArray(ki.globalWorkSize);
    *output << "," << endl;

    *output << "\"local_size\": ";
    printJSONArray(ki.localWorkSize);
    *output << "," << endl;

    assert(ki.globalWorkOffset.size() == ki.globalWorkSize.size() == ki.localWorkSize.size() &&
            "dimension mismatch");

    *output << "\"entry_point\": \"" << ki.entryPointName << "\"";

    // entry_point might be the last entry is there were no kernel args
    if (ki.arguments.size() == 0)
        *output << endl;
    else
    {
        *output << "," << endl << "\"kernel_arguments\": [ " << endl;
        for (int argIndex=0; argIndex < ki.arguments.size() ; ++argIndex)
        {
            printJSONKernelArgumentInfo(ki.arguments[argIndex]);
            if (argIndex != (ki.arguments.size() -1))
                *output << "," << endl;
        }
        *output << endl << "]" << endl;
    }

    *output << "}";
}

void Logger::printJSONArray(std::vector<size_t>& array)
{
    *output << "[ ";
    for (int index=0; index < array.size(); ++index)
    {
        *output << array[index];

        if (index != (array.size() -1))
            *output << ", ";
    }
    *output << "]";
}

void Logger::printJSONKernelArgumentInfo(ArgInfo& ai)
{
    *output << "{";
    if (ai.argValue == NULL)
    {
        // NULL was passed to clSetKernelArg()
        // That implies its for unallocated memory
        *output << "\"type\": \"array\",";

        // If the arg is for local memory
        if (ai.argSize != sizeof(cl_mem) && ai.argSize != sizeof(cl_sampler))
        {
            // We assume this means this arguments is for local memory
            // where size actually means the sizeof the underlying buffer
            // rather than the size of the type.
            *output << "\"size\" : " << ai.argSize;
        }
        *output << "}";
        return;
    }

    // FIXME:
    // Eurgh... the spec says
    // ```
    // If the argument is a buffer object, the arg_value pointer can be NULL or
    // point to a NULL value in which case a NULL value will be used as the
    // value for the argument declared as a pointer to __global or __constant
    // memory in the kernel.  ```
    //
    // This makes it impossible (seeing as we don't know which address space
    // the arguments are in) to work out the argument type once derefencing the
    // pointer and finding it's equal zero because it could be a scalar constant
    // (of value 0) or it could be an unintialised array!

    DEBUG_MSG("Note sizeof(cl_mem) == " << sizeof(cl_mem));
    // Hack:
    // It's hard to determine what type the argument is.
    // We can't dereference the void* to check if
    // it points to cl_mem we previously stored
    //
    // In some implementations cl_mem will be a pointer
    // which poses a risk if a scalar parameter of the same size
    // as the pointer type.
    if (ai.argSize == sizeof(cl_mem))
    {
       cl_mem mightBecl_mem = *((cl_mem*) ai.argValue);

       // We might be reading invalid data now
       if (buffers.count(mightBecl_mem) == 1)
       {
           // We're going to assume it's cl_mem that we saw before
           *output << "\"type\": \"array\",";
           BufferInfo& bi = buffers[mightBecl_mem];

           *output << "\"size\": " << bi.size << "}";
           return;
       }

    }

    // FIXME: Check for cl_sampler
    //

    // I guess it's scalar???
    *output << "\"type\": \"scalar\",";
    *output << " \"value\": \"0x";
    // Print the value as hex
    uint8_t* asByte = (uint8_t*) ai.argValue;
    for (int byteIndex=0; byteIndex < ai.argSize; ++byteIndex)
    {
       *output << setw(2) << setfill('0') << std::hex << asByte[byteIndex];
    }
    *output << "\"" << std::dec; //std::hex is sticky so switch back to decimal

    *output << "}";
    return;

}

static bool file_exists(std::string& name) {
	ifstream f(name.c_str());
	bool result = f.good();
	f.close();
	return result;
}

std::string Logger::dumpKernelSource(KernelInfo& ki)
{
    int count = 0;
    bool success = false;
    // FIXME: I really want a std::unique_ptr
    std::ofstream* kos = 0;
    std::string theKernelPath;
    while (count < maxFiles)
    {
        stringstream ss;
        ss << ki.entryPointName << "." << count << ".cl";

        ++count;

        std::string withDir = (directory + FILE_SEP) + ss.str();
        if (!file_exists(withDir))
        {
           kos = new std::ofstream(withDir.c_str());

           if (!kos->good())
           {
                kos->close();
                delete kos;
                continue;
           }

           success = true;
           theKernelPath = ss.str();
           break;
        }
    }

    if (!success)
    {
        ERROR_MSG("Failed to log kernel output");
        return std::string("FIXME");
    }

    // Write kernel source
    ProgramInfo& pi = programs[ki.program];

    for (vector<string>::const_iterator b = pi.sources.begin(), e = pi.sources.end(); b != e; ++b)
    {
        *kos << *b;
    }

    // Urgh this is bad, need RAII!
    kos->close();
    delete kos;
    return theKernelPath;
}
<|endoftext|>


<commit_before>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  ______             __                  ___
// /\__  _\           /\ \                /\_ \
// \/_/\ \/    __     \_\ \  _____     ___\//\ \      __
//    \ \ \  /'__`\   /'_` \/\ '__`\  / __`\\ \ \   /'__`\
//     \ \ \/\ \L\.\_/\ \L\ \ \ \L\ \/\ \L\ \\_\ \_/\  __/
//      \ \_\ \__/.\_\ \___,_\ \ ,__/\ \____//\____\ \____\
//       \/_/\/__/\/_/\/__,_ /\ \ \/  \/___/ \/____/\/____/
//                             \ \_\
//                              \/_/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <GC/GC.hh>
#include <Object/UpvalueObject.hh>

namespace Tadpole::Object {

str_t UpvalueObject::stringify() const {
  ss_t ss;
  ss << "<upvalue at `" << this << "`>";
  return ss.str();
}

void UpvalueObject::iter_children(ObjectVisitor&& visitor) {
  visitor(closed_.as_object(safe_t()));
}

UpvalueObject* UpvalueObject::create(Value::Value* value, UpvalueObject* next) {
  return GC::make_object<UpvalueObject>(value, next);
}

}
<commit_msg>:construction: chore(upvalue-object): updated the implementation of upvalue object<commit_after>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  ______             __                  ___
// /\__  _\           /\ \                /\_ \
// \/_/\ \/    __     \_\ \  _____     ___\//\ \      __
//    \ \ \  /'__`\   /'_` \/\ '__`\  / __`\\ \ \   /'__`\
//     \ \ \/\ \L\.\_/\ \L\ \ \ \L\ \/\ \L\ \\_\ \_/\  __/
//      \ \_\ \__/.\_\ \___,_\ \ ,__/\ \____//\____\ \____\
//       \/_/\/__/\/_/\/__,_ /\ \ \/  \/___/ \/____/\/____/
//                             \ \_\
//                              \/_/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <GC/GC.hh>
#include <Object/UpvalueObject.hh>

namespace Tadpole::Object {

str_t UpvalueObject::stringify() const {
  ss_t ss;
  ss << "<upvalue at `" << this << "`>";
  return ss.str();
}

void UpvalueObject::iter_children(ObjectVisitor&& visitor) {
  visitor(closed_.as_object(kSafePlaceholder));
}

UpvalueObject* UpvalueObject::create(Value::Value* value, UpvalueObject* next) {
  return GC::make_object<UpvalueObject>(value, next);
}

}
<|endoftext|>