<commit_before>#include "xchainer/array_repr.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <nonstd/optional.hpp>

#include <algorithm>
#include <cmath>
#include <limits>
#include <sstream>
#include <string>
#include <vector>

#include "xchainer/backend.h"
#ifdef XCHAINER_ENABLE_CUDA
#include "xchainer/cuda/cuda_backend.h"
#endif  // XCHAINER_ENABLE_CUDA
#include "xchainer/device.h"
#include "xchainer/native_backend.h"

namespace xchainer {
namespace {

template <typename T>
std::string AsString(const T& object) {
    std::ostringstream os;
    os << object;
    return os.str();
}

std::string ArrayReprFromTemplate(const std::string& array_data_repr, const std::string& dtype_repr, const std::string& device_repr,
                                  const nonstd::optional<std::string>& graph_ids_repr = nonstd::nullopt) {
    std::ostringstream os;
    os << "array(" + array_data_repr;
    os << ", dtype=" + dtype_repr;
    os << ", device=" << device_repr;
    if (graph_ids_repr) {
        os << ", graph_ids=" << graph_ids_repr.value();
    }
    os << ")";
    return os.str();
}

std::string CreateExpectedArrayRepr(const std::string& array_data_repr, Dtype dtype, const Device& device,
                                    const std::vector<GraphId> graph_ids) {
    // Dtype repr
    std::string dtype_repr = AsString(dtype);

    // Device repr
    std::string device_repr = AsString(device);

    // Graph IDs repr
    nonstd::optional<std::string> graph_ids_repr;
    if (!graph_ids.empty()) {
        std::ostringstream os;
        os << "[";
        for (size_t i = 0; i < graph_ids.size(); ++i) {
            if (i > 0) {
                os << ", ";
            }
            os << '\'' << graph_ids[i] << '\'';
        }
        os << "]";
        graph_ids_repr = nonstd::optional<std::string>(os.str());
    }

    // Expected Array repr
    return ArrayReprFromTemplate(array_data_repr, dtype_repr, device_repr, graph_ids_repr);
}

// Check Array repr without any graph IDs
template <typename T>
void CheckArrayRepr(const std::string& array_data_repr, const std::vector<T>& data_vec, Shape shape, const Device& device,
                    const std::vector<GraphId> graph_ids = {}) {
    std::string expected = CreateExpectedArrayRepr(array_data_repr, TypeToDtype<T>, device, graph_ids);

    // Copy to a contiguous memory block because std::vector<bool> is not packed as a sequence of bool's.
    std::shared_ptr<T> data_ptr = std::make_unique<T[]>(data_vec.size());
    std::copy(data_vec.begin(), data_vec.end(), data_ptr.get());
    Array array = Array::FromBuffer(shape, TypeToDtype<T>, static_cast<std::shared_ptr<void>>(data_ptr), device);
    for (const GraphId& graph_id : graph_ids) {
        array.RequireGrad(graph_id);
    }

    // std::string version
    EXPECT_EQ(expected, ArrayRepr(array));

    // std::ostream version
    std::ostringstream os;
    os << array;
    EXPECT_EQ(expected, os.str());
}

void CheckAllForDevice(const Device& device) {
    // bool
    CheckArrayRepr<bool>("[False]", {false}, Shape({1}), device);
    CheckArrayRepr<bool>("[ True]", {true}, Shape({1}), device);
    CheckArrayRepr<bool>(
        "[[False,  True,  True],\n"
        "       [ True, False,  True]]",
        {false, true, true, true, false, true}, Shape({2, 3}), device);
    CheckArrayRepr<bool>("[False]", {false}, Shape({1}), device);
    CheckArrayRepr<bool>("[ True]", {true}, Shape({1}), device);
    CheckArrayRepr<bool>(
        "[[False,  True,  True],\n"
        "       [ True, False,  True]]",
        {false, true, true, true, false, true}, Shape({2, 3}), device);
    CheckArrayRepr<bool>("[[[[ True]]]]", {true}, Shape({1, 1, 1, 1}), device);

    // int8
    CheckArrayRepr<int8_t>("[0]", {0}, Shape({1}), device);
    CheckArrayRepr<int8_t>("[-2]", {-2}, Shape({1}), device);
    CheckArrayRepr<int8_t>(
        "[[0, 1, 2],\n"
        "       [3, 4, 5]]",
        {0, 1, 2, 3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<int8_t>(
        "[[ 0,  1,  2],\n"
        "       [-3,  4,  5]]",
        {0, 1, 2, -3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<int8_t>("[[[[3]]]]", {3}, Shape({1, 1, 1, 1}), device);

    // int16
    CheckArrayRepr<int16_t>("[0]", {0}, Shape({1}), device);
    CheckArrayRepr<int16_t>("[-2]", {-2}, Shape({1}), device);
    CheckArrayRepr<int16_t>(
        "[[0, 1, 2],\n"
        "       [3, 4, 5]]",
        {0, 1, 2, 3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<int16_t>(
        "[[ 0,  1,  2],\n"
        "       [-3,  4,  5]]",
        {0, 1, 2, -3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<int16_t>("[[[[3]]]]", {3}, Shape({1, 1, 1, 1}), device);

    // int32
    CheckArrayRepr<int32_t>("[0]", {0}, Shape({1}), device);
    CheckArrayRepr<int32_t>("[-2]", {-2}, Shape({1}), device);
    CheckArrayRepr<int32_t>(
        "[[0, 1, 2],\n"
        "       [3, 4, 5]]",
        {0, 1, 2, 3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<int32_t>(
        "[[ 0,  1,  2],\n"
        "       [-3,  4,  5]]",
        {0, 1, 2, -3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<int32_t>("[[[[3]]]]", {3}, Shape({1, 1, 1, 1}), device);

    // int64
    CheckArrayRepr<int64_t>("[0]", {0}, Shape({1}), device);
    CheckArrayRepr<int64_t>("[-2]", {-2}, Shape({1}), device);
    CheckArrayRepr<int64_t>(
        "[[0, 1, 2],\n"
        "       [3, 4, 5]]",
        {0, 1, 2, 3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<int64_t>(
        "[[ 0,  1,  2],\n"
        "       [-3,  4,  5]]",
        {0, 1, 2, -3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<int64_t>("[[[[3]]]]", {3}, Shape({1, 1, 1, 1}), device);

    // uint8
    CheckArrayRepr<uint8_t>("[0]", {0}, Shape({1}), device);
    CheckArrayRepr<uint8_t>("[2]", {2}, Shape({1}), device);
    CheckArrayRepr<uint8_t>(
        "[[0, 1, 2],\n"
        "       [3, 4, 5]]",
        {0, 1, 2, 3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<uint8_t>("[[[[3]]]]", {3}, Shape({1, 1, 1, 1}), device);

    // float32
    CheckArrayRepr<float>("[0.]", {0}, Shape({1}), device);
    CheckArrayRepr<float>("[3.25]", {3.25}, Shape({1}), device);
    CheckArrayRepr<float>("[-3.25]", {-3.25}, Shape({1}), device);
    CheckArrayRepr<float>("[ inf]", {std::numeric_limits<float>::infinity()}, Shape({1}), device);
    CheckArrayRepr<float>("[ -inf]", {-std::numeric_limits<float>::infinity()}, Shape({1}), device);
    CheckArrayRepr<float>("[ nan]", {std::nanf("")}, Shape({1}), device);
    CheckArrayRepr<float>(
        "[[0., 1., 2.],\n"
        "       [3., 4., 5.]]",
        {0, 1, 2, 3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<float>(
        "[[0.  , 1.  , 2.  ],\n"
        "       [3.25, 4.  , 5.  ]]",
        {0, 1, 2, 3.25, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<float>(
        "[[ 0.  ,  1.  ,  2.  ],\n"
        "       [-3.25,  4.  ,  5.  ]]",
        {0, 1, 2, -3.25, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<float>("[[[[3.25]]]]", {3.25}, Shape({1, 1, 1, 1}), device);

    // float64
    CheckArrayRepr<double>("[0.]", {0}, Shape({1}), device);
    CheckArrayRepr<double>("[3.25]", {3.25}, Shape({1}), device);
    CheckArrayRepr<double>("[-3.25]", {-3.25}, Shape({1}), device);
    CheckArrayRepr<double>("[ inf]", {std::numeric_limits<double>::infinity()}, Shape({1}), device);
    CheckArrayRepr<double>("[ -inf]", {-std::numeric_limits<double>::infinity()}, Shape({1}), device);
    CheckArrayRepr<double>("[ nan]", {std::nan("")}, Shape({1}), device);
    CheckArrayRepr<double>(
        "[[0., 1., 2.],\n"
        "       [3., 4., 5.]]",
        {0, 1, 2, 3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<double>(
        "[[0.  , 1.  , 2.  ],\n"
        "       [3.25, 4.  , 5.  ]]",
        {0, 1, 2, 3.25, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<double>(
        "[[ 0.  ,  1.  ,  2.  ],\n"
        "       [-3.25,  4.  ,  5.  ]]",
        {0, 1, 2, -3.25, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<double>("[[[[3.25]]]]", {3.25}, Shape({1, 1, 1, 1}), device);

    // Single graph
    CheckArrayRepr<int32_t>("[-2]", {-2}, Shape({1}), device, {"graph_1"});

    // Two graphs
    CheckArrayRepr<int32_t>("[1]", {1}, Shape({1}), device, {"graph_1", "graph_2"});

    // Multiple graphs
    CheckArrayRepr<int32_t>("[-9]", {-9}, Shape({1}), device, {"graph_1", "graph_2", "graph_3", "graph_4", "graph_5"});
}

TEST(ArrayReprNativeTest, ArrayRepr) {
    NativeBackend backend;
    Device device = Device("cpu", &backend);
    CheckAllForDevice(device);
}

#ifdef XCHAINER_ENABLE_CUDA
TEST(ArrayReprCudaTest, ArrayRepr) {
    cuda::CudaBackend backend;
    Device device = Device("cuda", &backend);
    CheckAllForDevice(device);
}
#endif  // XCHAINER_ENABLE_CUDA

}  // namespace
}  // namespace xchainer
<commit_msg>Delete unused include<commit_after>#include "xchainer/array_repr.h"

#include <gtest/gtest.h>
#include <nonstd/optional.hpp>

#include <algorithm>
#include <cmath>
#include <limits>
#include <sstream>
#include <string>
#include <vector>

#include "xchainer/backend.h"
#ifdef XCHAINER_ENABLE_CUDA
#include "xchainer/cuda/cuda_backend.h"
#endif  // XCHAINER_ENABLE_CUDA
#include "xchainer/device.h"
#include "xchainer/native_backend.h"

namespace xchainer {
namespace {

template <typename T>
std::string AsString(const T& object) {
    std::ostringstream os;
    os << object;
    return os.str();
}

std::string ArrayReprFromTemplate(const std::string& array_data_repr, const std::string& dtype_repr, const std::string& device_repr,
                                  const nonstd::optional<std::string>& graph_ids_repr = nonstd::nullopt) {
    std::ostringstream os;
    os << "array(" + array_data_repr;
    os << ", dtype=" + dtype_repr;
    os << ", device=" << device_repr;
    if (graph_ids_repr) {
        os << ", graph_ids=" << graph_ids_repr.value();
    }
    os << ")";
    return os.str();
}

std::string CreateExpectedArrayRepr(const std::string& array_data_repr, Dtype dtype, const Device& device,
                                    const std::vector<GraphId> graph_ids) {
    // Dtype repr
    std::string dtype_repr = AsString(dtype);

    // Device repr
    std::string device_repr = AsString(device);

    // Graph IDs repr
    nonstd::optional<std::string> graph_ids_repr;
    if (!graph_ids.empty()) {
        std::ostringstream os;
        os << "[";
        for (size_t i = 0; i < graph_ids.size(); ++i) {
            if (i > 0) {
                os << ", ";
            }
            os << '\'' << graph_ids[i] << '\'';
        }
        os << "]";
        graph_ids_repr = nonstd::optional<std::string>(os.str());
    }

    // Expected Array repr
    return ArrayReprFromTemplate(array_data_repr, dtype_repr, device_repr, graph_ids_repr);
}

// Check Array repr without any graph IDs
template <typename T>
void CheckArrayRepr(const std::string& array_data_repr, const std::vector<T>& data_vec, Shape shape, const Device& device,
                    const std::vector<GraphId> graph_ids = {}) {
    std::string expected = CreateExpectedArrayRepr(array_data_repr, TypeToDtype<T>, device, graph_ids);

    // Copy to a contiguous memory block because std::vector<bool> is not packed as a sequence of bool's.
    std::shared_ptr<T> data_ptr = std::make_unique<T[]>(data_vec.size());
    std::copy(data_vec.begin(), data_vec.end(), data_ptr.get());
    Array array = Array::FromBuffer(shape, TypeToDtype<T>, static_cast<std::shared_ptr<void>>(data_ptr), device);
    for (const GraphId& graph_id : graph_ids) {
        array.RequireGrad(graph_id);
    }

    // std::string version
    EXPECT_EQ(expected, ArrayRepr(array));

    // std::ostream version
    std::ostringstream os;
    os << array;
    EXPECT_EQ(expected, os.str());
}

void CheckAllForDevice(const Device& device) {
    // bool
    CheckArrayRepr<bool>("[False]", {false}, Shape({1}), device);
    CheckArrayRepr<bool>("[ True]", {true}, Shape({1}), device);
    CheckArrayRepr<bool>(
        "[[False,  True,  True],\n"
        "       [ True, False,  True]]",
        {false, true, true, true, false, true}, Shape({2, 3}), device);
    CheckArrayRepr<bool>("[False]", {false}, Shape({1}), device);
    CheckArrayRepr<bool>("[ True]", {true}, Shape({1}), device);
    CheckArrayRepr<bool>(
        "[[False,  True,  True],\n"
        "       [ True, False,  True]]",
        {false, true, true, true, false, true}, Shape({2, 3}), device);
    CheckArrayRepr<bool>("[[[[ True]]]]", {true}, Shape({1, 1, 1, 1}), device);

    // int8
    CheckArrayRepr<int8_t>("[0]", {0}, Shape({1}), device);
    CheckArrayRepr<int8_t>("[-2]", {-2}, Shape({1}), device);
    CheckArrayRepr<int8_t>(
        "[[0, 1, 2],\n"
        "       [3, 4, 5]]",
        {0, 1, 2, 3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<int8_t>(
        "[[ 0,  1,  2],\n"
        "       [-3,  4,  5]]",
        {0, 1, 2, -3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<int8_t>("[[[[3]]]]", {3}, Shape({1, 1, 1, 1}), device);

    // int16
    CheckArrayRepr<int16_t>("[0]", {0}, Shape({1}), device);
    CheckArrayRepr<int16_t>("[-2]", {-2}, Shape({1}), device);
    CheckArrayRepr<int16_t>(
        "[[0, 1, 2],\n"
        "       [3, 4, 5]]",
        {0, 1, 2, 3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<int16_t>(
        "[[ 0,  1,  2],\n"
        "       [-3,  4,  5]]",
        {0, 1, 2, -3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<int16_t>("[[[[3]]]]", {3}, Shape({1, 1, 1, 1}), device);

    // int32
    CheckArrayRepr<int32_t>("[0]", {0}, Shape({1}), device);
    CheckArrayRepr<int32_t>("[-2]", {-2}, Shape({1}), device);
    CheckArrayRepr<int32_t>(
        "[[0, 1, 2],\n"
        "       [3, 4, 5]]",
        {0, 1, 2, 3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<int32_t>(
        "[[ 0,  1,  2],\n"
        "       [-3,  4,  5]]",
        {0, 1, 2, -3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<int32_t>("[[[[3]]]]", {3}, Shape({1, 1, 1, 1}), device);

    // int64
    CheckArrayRepr<int64_t>("[0]", {0}, Shape({1}), device);
    CheckArrayRepr<int64_t>("[-2]", {-2}, Shape({1}), device);
    CheckArrayRepr<int64_t>(
        "[[0, 1, 2],\n"
        "       [3, 4, 5]]",
        {0, 1, 2, 3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<int64_t>(
        "[[ 0,  1,  2],\n"
        "       [-3,  4,  5]]",
        {0, 1, 2, -3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<int64_t>("[[[[3]]]]", {3}, Shape({1, 1, 1, 1}), device);

    // uint8
    CheckArrayRepr<uint8_t>("[0]", {0}, Shape({1}), device);
    CheckArrayRepr<uint8_t>("[2]", {2}, Shape({1}), device);
    CheckArrayRepr<uint8_t>(
        "[[0, 1, 2],\n"
        "       [3, 4, 5]]",
        {0, 1, 2, 3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<uint8_t>("[[[[3]]]]", {3}, Shape({1, 1, 1, 1}), device);

    // float32
    CheckArrayRepr<float>("[0.]", {0}, Shape({1}), device);
    CheckArrayRepr<float>("[3.25]", {3.25}, Shape({1}), device);
    CheckArrayRepr<float>("[-3.25]", {-3.25}, Shape({1}), device);
    CheckArrayRepr<float>("[ inf]", {std::numeric_limits<float>::infinity()}, Shape({1}), device);
    CheckArrayRepr<float>("[ -inf]", {-std::numeric_limits<float>::infinity()}, Shape({1}), device);
    CheckArrayRepr<float>("[ nan]", {std::nanf("")}, Shape({1}), device);
    CheckArrayRepr<float>(
        "[[0., 1., 2.],\n"
        "       [3., 4., 5.]]",
        {0, 1, 2, 3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<float>(
        "[[0.  , 1.  , 2.  ],\n"
        "       [3.25, 4.  , 5.  ]]",
        {0, 1, 2, 3.25, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<float>(
        "[[ 0.  ,  1.  ,  2.  ],\n"
        "       [-3.25,  4.  ,  5.  ]]",
        {0, 1, 2, -3.25, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<float>("[[[[3.25]]]]", {3.25}, Shape({1, 1, 1, 1}), device);

    // float64
    CheckArrayRepr<double>("[0.]", {0}, Shape({1}), device);
    CheckArrayRepr<double>("[3.25]", {3.25}, Shape({1}), device);
    CheckArrayRepr<double>("[-3.25]", {-3.25}, Shape({1}), device);
    CheckArrayRepr<double>("[ inf]", {std::numeric_limits<double>::infinity()}, Shape({1}), device);
    CheckArrayRepr<double>("[ -inf]", {-std::numeric_limits<double>::infinity()}, Shape({1}), device);
    CheckArrayRepr<double>("[ nan]", {std::nan("")}, Shape({1}), device);
    CheckArrayRepr<double>(
        "[[0., 1., 2.],\n"
        "       [3., 4., 5.]]",
        {0, 1, 2, 3, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<double>(
        "[[0.  , 1.  , 2.  ],\n"
        "       [3.25, 4.  , 5.  ]]",
        {0, 1, 2, 3.25, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<double>(
        "[[ 0.  ,  1.  ,  2.  ],\n"
        "       [-3.25,  4.  ,  5.  ]]",
        {0, 1, 2, -3.25, 4, 5}, Shape({2, 3}), device);
    CheckArrayRepr<double>("[[[[3.25]]]]", {3.25}, Shape({1, 1, 1, 1}), device);

    // Single graph
    CheckArrayRepr<int32_t>("[-2]", {-2}, Shape({1}), device, {"graph_1"});

    // Two graphs
    CheckArrayRepr<int32_t>("[1]", {1}, Shape({1}), device, {"graph_1", "graph_2"});

    // Multiple graphs
    CheckArrayRepr<int32_t>("[-9]", {-9}, Shape({1}), device, {"graph_1", "graph_2", "graph_3", "graph_4", "graph_5"});
}

TEST(ArrayReprNativeTest, ArrayRepr) {
    NativeBackend backend;
    Device device = Device("cpu", &backend);
    CheckAllForDevice(device);
}

#ifdef XCHAINER_ENABLE_CUDA
TEST(ArrayReprCudaTest, ArrayRepr) {
    cuda::CudaBackend backend;
    Device device = Device("cuda", &backend);
    CheckAllForDevice(device);
}
#endif  // XCHAINER_ENABLE_CUDA

}  // namespace
}  // namespace xchainer
<|endoftext|>


<commit_before>#include "calc.h"
#include "sevensegment.h"
#include "pocketcalculator.h"

#include "cute.h"
#include "ide_listener.h"
#include "xml_listener.h"
#include "cute_runner.h"

#include <string>
#include <sstream>
#include <limits>
#include <algorithm>

namespace calc_tests {
	constexpr int max { std::numeric_limits<int>::max() },
				  min { std::numeric_limits<int>::min() };
	void multiplies_positive_numbers() {
		ASSERT_EQUAL(20, calc(4, 5, '*'));
	}
	void multiplies_negative_with_positive_number() {
		ASSERT_EQUAL(-30, calc(-6, 5, '*'));
	}
	void multiplies_negative_numbers() {
		ASSERT_EQUAL(20, calc(-4, -5, '*'));
	}
	void recognizes_overflows_when_multiplying() {
		calc(1, max, '*');
		calc(1, min, '*');
		calc(-1, max, '*');
		calc(-1, min+1, '*');
		calc(2, max/2, '*');
		calc(2, min/2, '*');
		calc(-2, max/2, '*');
		calc(-2, min/2+1, '*');

		ASSERT_THROWS(calc(4, max/3, '*'), std::overflow_error);
		ASSERT_THROWS(calc(4, min/3, '*'), std::overflow_error);
		ASSERT_THROWS(calc(-4, max/3, '*'), std::overflow_error);
		ASSERT_THROWS(calc(-4, min/3, '*'), std::overflow_error);
	}
	void divides() {
		ASSERT_EQUAL(5, calc(60, 12, '/'));
		ASSERT_EQUAL(-3, calc(9, -3, '/'));
	}
	void throws_when_dividing_by_zero() {
		ASSERT_THROWS(calc(1, 0, '/'), std::domain_error);
	}
	void adds() {
		ASSERT_EQUAL(5, calc(2, 3, '+'));
		ASSERT_EQUAL(-10, calc(-6, -4, '+'));
	}
	void recognizes_overflows_when_adding() {
		calc(max, 0, '+'); // must not throw
		ASSERT_THROWS(calc(max, 1, '+'), std::overflow_error);
		calc(min, 0, '+'); // must not throw
		ASSERT_THROWS(calc(min, -1, '+'), std::overflow_error);
	}
	void subtracts() {
		ASSERT_EQUAL(17, calc(20, 3, '-'));
		ASSERT_EQUAL(-5, calc(-2, 3, '-'));
	}
	void recognizes_overflows_when_subtracting() {
		calc(max, 0, '-'); // must not throw
		ASSERT_THROWS(calc(max, -1, '-'), std::overflow_error);
		calc(min, 0, '-'); // must not throw
		ASSERT_THROWS(calc(min, 1, '-'), std::overflow_error);
	}
	void knows_modulo() {
		ASSERT_EQUAL(5, calc(15, 10, '%'));
		ASSERT_EQUAL(-5, calc(-15, 10, '%'));
	}
	void throws_when_modulo_zero() {
		ASSERT_THROWS(calc(10, 0, '%'), std::domain_error);
	}
	void throws_when_given_invalid_operator() {
		ASSERT_THROWS(calc(1, 1, '^'), std::runtime_error);
	}

	void takes_term_from_istream() {
		std::istringstream term_stream { "1+1" };
		int result = calc(term_stream);
		ASSERT_EQUAL(2, result);
	}

	const std::vector<std::string> invalid_terms {
        "foobar",
        "3+2-",
        "1",
        "8--",
        "*",
        "4%%6",
        "3//7",
	};

    void throws_when_given_invalid_term() {
		for(auto const term : invalid_terms) {
			std::istringstream term_stream { term };
			ASSERT_THROWS(calc(term_stream), std::exception); // TODO: more specific?
		}
	}

	void add_tests_to_suite(cute::suite& s) {
		s.push_back(CUTE(multiplies_positive_numbers));
		s.push_back(CUTE(multiplies_negative_with_positive_number));
		s.push_back(CUTE(multiplies_negative_numbers));
		s.push_back(CUTE(recognizes_overflows_when_multiplying));
		s.push_back(CUTE(divides));
		s.push_back(CUTE(throws_when_dividing_by_zero));
		s.push_back(CUTE(adds));
		s.push_back(CUTE(recognizes_overflows_when_adding));
		s.push_back(CUTE(subtracts));
		s.push_back(CUTE(recognizes_overflows_when_subtracting));
		s.push_back(CUTE(throws_when_given_invalid_operator));
		s.push_back(CUTE(knows_modulo));
		s.push_back(CUTE(throws_when_modulo_zero));
		s.push_back(CUTE(takes_term_from_istream));
		s.push_back(CUTE(throws_when_given_invalid_term));
	}
}

namespace sevensegment_tests {
	const std::string large_8 {
		" - \n"
		"| |\n"
		" - \n"
		"| |\n"
		" - \n"
	};
	const std::string large_1 {
		"   \n"
		"  |\n"
		"   \n"
		"  |\n"
		"   \n"
	};
	const std::string large_3_scale2 {
		" -- \n"
		"   |\n"
		"   |\n"
		" -- \n"
		"   |\n"
		"   |\n"
		" -- \n"
	};

	void prints_digit() {
		std::ostringstream output {};
		sevensegment::printLargeDigit(8, output);
		ASSERT_EQUAL(large_8, output.str());
		output.str("");
		sevensegment::printLargeDigit(1, output);
		ASSERT_EQUAL(large_1, output.str());
	}
	void prints_scaled_digit() {
		std::ostringstream output {};
		sevensegment::printLargeDigit(3, output, 2);
		ASSERT_EQUAL(large_3_scale2, output.str());
	}
	void throws_when_digit_out_of_range() {
		std::ostringstream output {};
		ASSERT_THROWS(sevensegment::printLargeDigit(10,output),
				std::out_of_range);
	}
	void throws_when_scale_out_of_range() {
		std::ostringstream output {};
		ASSERT_THROWS(sevensegment::printLargeDigit(5,output, 0),
				std::range_error);
	}

	const std::string large_number {
		" -     -  -    \n"
		"|  | |  |  |  |\n"
		" -  -  -  -    \n"
		"  |  |  ||    |\n"
		" -     -  -    \n"
	};

	const std::string large_negative_number {
	"    -  - \n"
	"     |  |\n"
	" -  -  - \n"
	"     |  |\n"
	"    -  - \n"
	};

	void prints_number() {
		std::ostringstream output {};
		sevensegment::printLargeNumber(54321, output);
		ASSERT_EQUAL(large_number, output.str());
	}

	void prints_negative_number() {
		std::ostringstream output {};
		sevensegment::printLargeNumber(-33, output);
		ASSERT_EQUAL(large_negative_number, output.str());
	}

	const std::string large_error {
		" -             \n"
		"|              \n"
		" -  -  -  -  - \n"
		"|  |  |  | ||  \n"
		" -        -    \n"
	};

	void prints_error() {
		std::ostringstream output {};
		sevensegment::printLargeError(output);
		ASSERT_EQUAL(large_error, output.str());
	}

	void throws_when_too_many_digits_for_display() {
		std::ostringstream output {};
		ASSERT_THROWS(sevensegment::printLargeNumber(100000000, output, 1),
				std::overflow_error);
	}

	void add_tests_to_suite(cute::suite& s) {
		s.push_back(CUTE(prints_digit));
		s.push_back(CUTE(prints_scaled_digit));
		s.push_back(CUTE(throws_when_digit_out_of_range));
		s.push_back(CUTE(throws_when_scale_out_of_range));
		s.push_back(CUTE(prints_number));
		s.push_back(CUTE(prints_negative_number));
		s.push_back(CUTE(prints_error));
		s.push_back(CUTE(throws_when_too_many_digits_for_display));
	}
}

namespace pocketcalculator_tests {
	const std::string large_output {
		" --   -- \n"
		"   |    |\n"
		"   |    |\n"
		" --   -- \n"
		"|    |   \n"
		"|    |   \n"
		" --   -- \n"
	};

	// TODO: we don't have a prompt anymore. so maybe this functionality is obsolete anyway
	bool includes(const std::string str, const std::string substr) {
		return (str.find(substr) != std::string::npos);
	}

	void gets_term_and_prints_result() {
		std::ostringstream output {};
		std::istringstream input { "2+20" };
		pocketcalculator::start(input, output);
		ASSERT(includes(output.str(), large_output));
	}

	const std::string error_scale2 {
		" --                     \n"
		"|                       \n"
		"|                       \n"
		" --   --   --   --   -- \n"
		"|    |    |    |  | |   \n"
		"|    |    |    |  | |   \n"
		" --             --      \n"
	};

	void prints_error_on_invalid_input() {
		for(auto const term : calc_tests::invalid_terms) {

			std::ostringstream output {};
			std::istringstream input { term };
			pocketcalculator::start(input, output);
			ASSERT(includes(output.str(), error_scale2));
		}
	}

	const std::string large_2_scale4 {
		" ---- \n"
		"     |\n"
		"     |\n"
		"     |\n"
		"     |\n"
		" ---- \n"
		"|     \n"
		"|     \n"
		"|     \n"
		"|     \n"
		" ---- \n"
	};

	void scales() {
		std::ostringstream output {};
		std::istringstream input {"1+1"};
		pocketcalculator::start(input, output, 4);
		ASSERT(includes(output.str(), large_2_scale4));
	}

	const std::string large_2_scale2 {
		" -- \n"
		"   |\n"
		"   |\n"
		" -- \n"
		"|   \n"
		"|   \n"
		" -- \n"
	};

	void uses_default_scale_when_scale_omitted() {
		std::ostringstream output {};
		std::istringstream input {"1+1"};
		pocketcalculator::start(input, output);
		ASSERT(includes(output.str(), large_2_scale2));
	}

	void add_tests_to_suite(cute::suite& s) {
		s.push_back(CUTE(gets_term_and_prints_result));
		s.push_back(CUTE(prints_error_on_invalid_input));
		s.push_back(CUTE(scales));
		s.push_back(CUTE(uses_default_scale_when_scale_omitted));
	}

	// TODO: add env scale test
}

void runAllTests(int argc, char const *argv[]){
	cute::suite s {};
	calc_tests::add_tests_to_suite(s);
	sevensegment_tests::add_tests_to_suite(s);
	pocketcalculator_tests::add_tests_to_suite(s);

	cute::xml_file_opener xmlfile(argc,argv);
	cute::xml_listener<cute::ide_listener<> >  lis(xmlfile.out);
	cute::makeRunner(lis,argc,argv)(s, "AllTests");
}

int main(int argc, char const *argv[]){
    runAllTests(argc,argv);
    return 0;
}

<commit_msg>simplify tests because we don't have a prompt anymore<commit_after>#include "calc.h"
#include "sevensegment.h"
#include "pocketcalculator.h"

#include "cute.h"
#include "ide_listener.h"
#include "xml_listener.h"
#include "cute_runner.h"

#include <string>
#include <sstream>
#include <limits>
#include <algorithm>

namespace calc_tests {
	constexpr int max { std::numeric_limits<int>::max() },
				  min { std::numeric_limits<int>::min() };
	void multiplies_positive_numbers() {
		ASSERT_EQUAL(20, calc(4, 5, '*'));
	}
	void multiplies_negative_with_positive_number() {
		ASSERT_EQUAL(-30, calc(-6, 5, '*'));
	}
	void multiplies_negative_numbers() {
		ASSERT_EQUAL(20, calc(-4, -5, '*'));
	}
	void recognizes_overflows_when_multiplying() {
		calc(1, max, '*');
		calc(1, min, '*');
		calc(-1, max, '*');
		calc(-1, min+1, '*');
		calc(2, max/2, '*');
		calc(2, min/2, '*');
		calc(-2, max/2, '*');
		calc(-2, min/2+1, '*');

		ASSERT_THROWS(calc(4, max/3, '*'), std::overflow_error);
		ASSERT_THROWS(calc(4, min/3, '*'), std::overflow_error);
		ASSERT_THROWS(calc(-4, max/3, '*'), std::overflow_error);
		ASSERT_THROWS(calc(-4, min/3, '*'), std::overflow_error);
	}
	void divides() {
		ASSERT_EQUAL(5, calc(60, 12, '/'));
		ASSERT_EQUAL(-3, calc(9, -3, '/'));
	}
	void throws_when_dividing_by_zero() {
		ASSERT_THROWS(calc(1, 0, '/'), std::domain_error);
	}
	void adds() {
		ASSERT_EQUAL(5, calc(2, 3, '+'));
		ASSERT_EQUAL(-10, calc(-6, -4, '+'));
	}
	void recognizes_overflows_when_adding() {
		calc(max, 0, '+'); // must not throw
		ASSERT_THROWS(calc(max, 1, '+'), std::overflow_error);
		calc(min, 0, '+'); // must not throw
		ASSERT_THROWS(calc(min, -1, '+'), std::overflow_error);
	}
	void subtracts() {
		ASSERT_EQUAL(17, calc(20, 3, '-'));
		ASSERT_EQUAL(-5, calc(-2, 3, '-'));
	}
	void recognizes_overflows_when_subtracting() {
		calc(max, 0, '-'); // must not throw
		ASSERT_THROWS(calc(max, -1, '-'), std::overflow_error);
		calc(min, 0, '-'); // must not throw
		ASSERT_THROWS(calc(min, 1, '-'), std::overflow_error);
	}
	void knows_modulo() {
		ASSERT_EQUAL(5, calc(15, 10, '%'));
		ASSERT_EQUAL(-5, calc(-15, 10, '%'));
	}
	void throws_when_modulo_zero() {
		ASSERT_THROWS(calc(10, 0, '%'), std::domain_error);
	}
	void throws_when_given_invalid_operator() {
		ASSERT_THROWS(calc(1, 1, '^'), std::runtime_error);
	}

	void takes_term_from_istream() {
		std::istringstream term_stream { "1+1" };
		int result = calc(term_stream);
		ASSERT_EQUAL(2, result);
	}

	const std::vector<std::string> invalid_terms {
        "foobar",
        "3+2-",
        "1",
        "8--",
        "*",
        "4%%6",
        "3//7",
	};

    void throws_when_given_invalid_term() {
		for(auto const term : invalid_terms) {
			std::istringstream term_stream { term };
			ASSERT_THROWS(calc(term_stream), std::exception); // TODO: more specific?
		}
	}

	void add_tests_to_suite(cute::suite& s) {
		s.push_back(CUTE(multiplies_positive_numbers));
		s.push_back(CUTE(multiplies_negative_with_positive_number));
		s.push_back(CUTE(multiplies_negative_numbers));
		s.push_back(CUTE(recognizes_overflows_when_multiplying));
		s.push_back(CUTE(divides));
		s.push_back(CUTE(throws_when_dividing_by_zero));
		s.push_back(CUTE(adds));
		s.push_back(CUTE(recognizes_overflows_when_adding));
		s.push_back(CUTE(subtracts));
		s.push_back(CUTE(recognizes_overflows_when_subtracting));
		s.push_back(CUTE(throws_when_given_invalid_operator));
		s.push_back(CUTE(knows_modulo));
		s.push_back(CUTE(throws_when_modulo_zero));
		s.push_back(CUTE(takes_term_from_istream));
		s.push_back(CUTE(throws_when_given_invalid_term));
	}
}

namespace sevensegment_tests {
	const std::string large_8 {
		" - \n"
		"| |\n"
		" - \n"
		"| |\n"
		" - \n"
	};
	const std::string large_1 {
		"   \n"
		"  |\n"
		"   \n"
		"  |\n"
		"   \n"
	};
	const std::string large_3_scale2 {
		" -- \n"
		"   |\n"
		"   |\n"
		" -- \n"
		"   |\n"
		"   |\n"
		" -- \n"
	};

	void prints_digit() {
		std::ostringstream output {};
		sevensegment::printLargeDigit(8, output);
		ASSERT_EQUAL(large_8, output.str());
		output.str("");
		sevensegment::printLargeDigit(1, output);
		ASSERT_EQUAL(large_1, output.str());
	}
	void prints_scaled_digit() {
		std::ostringstream output {};
		sevensegment::printLargeDigit(3, output, 2);
		ASSERT_EQUAL(large_3_scale2, output.str());
	}
	void throws_when_digit_out_of_range() {
		std::ostringstream output {};
		ASSERT_THROWS(sevensegment::printLargeDigit(10,output),
				std::out_of_range);
	}
	void throws_when_scale_out_of_range() {
		std::ostringstream output {};
		ASSERT_THROWS(sevensegment::printLargeDigit(5,output, 0),
				std::range_error);
	}

	const std::string large_number {
		" -     -  -    \n"
		"|  | |  |  |  |\n"
		" -  -  -  -    \n"
		"  |  |  ||    |\n"
		" -     -  -    \n"
	};

	const std::string large_negative_number {
	"    -  - \n"
	"     |  |\n"
	" -  -  - \n"
	"     |  |\n"
	"    -  - \n"
	};

	void prints_number() {
		std::ostringstream output {};
		sevensegment::printLargeNumber(54321, output);
		ASSERT_EQUAL(large_number, output.str());
	}

	void prints_negative_number() {
		std::ostringstream output {};
		sevensegment::printLargeNumber(-33, output);
		ASSERT_EQUAL(large_negative_number, output.str());
	}

	const std::string large_error {
		" -             \n"
		"|              \n"
		" -  -  -  -  - \n"
		"|  |  |  | ||  \n"
		" -        -    \n"
	};

	void prints_error() {
		std::ostringstream output {};
		sevensegment::printLargeError(output);
		ASSERT_EQUAL(large_error, output.str());
	}

	void throws_when_too_many_digits_for_display() {
		std::ostringstream output {};
		ASSERT_THROWS(sevensegment::printLargeNumber(100000000, output, 1),
				std::overflow_error);
	}

	void add_tests_to_suite(cute::suite& s) {
		s.push_back(CUTE(prints_digit));
		s.push_back(CUTE(prints_scaled_digit));
		s.push_back(CUTE(throws_when_digit_out_of_range));
		s.push_back(CUTE(throws_when_scale_out_of_range));
		s.push_back(CUTE(prints_number));
		s.push_back(CUTE(prints_negative_number));
		s.push_back(CUTE(prints_error));
		s.push_back(CUTE(throws_when_too_many_digits_for_display));
	}
}

namespace pocketcalculator_tests {
	const std::string large_output {
		" --   -- \n"
		"   |    |\n"
		"   |    |\n"
		" --   -- \n"
		"|    |   \n"
		"|    |   \n"
		" --   -- \n"
	};

	void gets_term_and_prints_result() {
		std::ostringstream output {};
		std::istringstream input { "2+20" };
		pocketcalculator::start(input, output);
		ASSERT_EQUAL(large_output, output.str());
	}

	const std::string error_scale2 {
		" --                     \n"
		"|                       \n"
		"|                       \n"
		" --   --   --   --   -- \n"
		"|    |    |    |  | |   \n"
		"|    |    |    |  | |   \n"
		" --             --      \n"
	};

	void prints_error_on_invalid_input() {
		for(auto const term : calc_tests::invalid_terms) {

			std::ostringstream output {};
			std::istringstream input { term };
			pocketcalculator::start(input, output);
			ASSERT_EQUAL(error_scale2, output.str());
		}
	}

	const std::string large_2_scale4 {
		" ---- \n"
		"     |\n"
		"     |\n"
		"     |\n"
		"     |\n"
		" ---- \n"
		"|     \n"
		"|     \n"
		"|     \n"
		"|     \n"
		" ---- \n"
	};

	void scales() {
		std::ostringstream output {};
		std::istringstream input {"1+1"};
		pocketcalculator::start(input, output, 4);
		ASSERT_EQUAL(large_2_scale4, output.str());
	}

	const std::string large_2_scale2 {
		" -- \n"
		"   |\n"
		"   |\n"
		" -- \n"
		"|   \n"
		"|   \n"
		" -- \n"
	};

	void uses_default_scale_when_scale_omitted() {
		std::ostringstream output {};
		std::istringstream input {"1+1"};
		pocketcalculator::start(input, output);
		ASSERT_EQUAL(large_2_scale2, output.str());
	}

	void add_tests_to_suite(cute::suite& s) {
		s.push_back(CUTE(gets_term_and_prints_result));
		s.push_back(CUTE(prints_error_on_invalid_input));
		s.push_back(CUTE(scales));
		s.push_back(CUTE(uses_default_scale_when_scale_omitted));
	}

	// TODO: add env scale test
}

void runAllTests(int argc, char const *argv[]){
	cute::suite s {};
	calc_tests::add_tests_to_suite(s);
	sevensegment_tests::add_tests_to_suite(s);
	pocketcalculator_tests::add_tests_to_suite(s);

	cute::xml_file_opener xmlfile(argc,argv);
	cute::xml_listener<cute::ide_listener<> >  lis(xmlfile.out);
	cute::makeRunner(lis,argc,argv)(s, "AllTests");
}

int main(int argc, char const *argv[]){
    runAllTests(argc,argv);
    return 0;
}

<|endoftext|>


<commit_before>#include <rapid/rapid.h>
#include <algorithm>
#include <cctype>
#include <map>
#include <regex>
#include <sstream>
#include <tuple>
#include <vector>

namespace rapid {

class Request::Impl {
 public:
  using Matcher = struct {
    std::regex re;
    std::function<void(std::smatch &)> fn;
  };
  using Matchers = std::vector<Matcher>;

  Impl(Request *owner) : _owner(owner) {}
  ~Impl() { _owner = nullptr; }

  void init_matchers() {
    _matchers = {
        {std::regex("^([a-zA-Z0-9\\-]+): (.+)$"),
         [&](std::smatch &m) {
           std::string key = m[1];
           std::transform(key.begin(), key.end(), key.begin(),
                          [&](std::string::value_type c1) {
                            auto c2 = ::toupper(c1);
                            if (c2 == '-') {
                              c2 = '_';
                            }
                            return c2;
                          });
           _environments[key] = m[2];
         }},
        {std::regex("^GET (.+) HTTP/\\d\\.\\d$"),
         [&](std::smatch &m) {
           _owner->_method = rapid::Method::Get;
           _owner->_request_uri = m[1];
           _environments["REQUEST_METHOD"] = "GET";
           _environments["REQUEST_URI"] = m[1];
         }},
        {std::regex("^POST (.+) HTTP/\\d\\.\\d$"),
         [&](std::smatch &m) {
           _owner->_method = rapid::Method::Post;
           _owner->_request_uri = m[1];
           _environments["REQUEST_METHOD"] = "POST";
           _environments["REQUEST_URI"] = m[1];
         }},
    };
  }

  std::vector<std::string> split(const std::string &input) {
    std::istringstream stream(input);
    std::string result;
    std::vector<std::string> results;
    while (std::getline(stream, result, '\n')) {
      result.erase(result.size() - 1);
      results.emplace_back(result);
    }
    return std::move(results);
  }

  void parse(const std::string &raw_input) {
    init_matchers();
    auto rows = split(raw_input);

    if (!rows.empty()) {
      for (auto &row : rows) {
        for (auto &matcher : _matchers) {
          std::smatch match;
          if (std::regex_match(row, match, matcher.re)) {
            matcher.fn(match);
          }
        }
      }
    }
  }

  const Request::Environments &environments() const { return _environments; }

  void add_additional_environments(const Peer &peer) {
    _environments["SERVER_SOFTWARE"] =
        std::string(RAPID_SOFTWARE_NAME "/" RAPID_VERSION);
    _environments["SERVER_ADDR"] = peer.server_addr;
    _environments["SERVER_PORT"] = peer.server_port;
    _environments["SERVER_NAME"] = peer.server_name;
    _environments["REMOTE_ADDR"] = peer.client_addr;
    _environments["REMOTE_PORT"] = peer.client_port;
  }

 private:
  Request *_owner = nullptr;
  Matchers _matchers;
  Request::Environments _environments;
};

Request::Request(const std::string &raw_input) : Request(raw_input, Peer()) {}

Request::Request(const std::string &raw_input, const Peer &peer)
    : _impl(new Impl(this)), _peer(peer) {
  _impl->parse(raw_input);
  _impl->add_additional_environments(_peer);
}

Request::~Request() {}

const Request::Environments &Request::environments() const {
  return _impl->environments();
}

std::string Request::user_agent() const {
  try {
    return environments().at("USER_AGENT");
  } catch (std::out_of_range &e) {
    return "";
  }
}
}<commit_msg>add gateway_interface, request_time<commit_after>#include <rapid/rapid.h>
#include <algorithm>
#include <cctype>
#include <map>
#include <regex>
#include <sstream>
#include <tuple>
#include <vector>

namespace rapid {

class Request::Impl {
 public:
  using Matcher = struct {
    std::regex re;
    std::function<void(std::smatch &)> fn;
  };
  using Matchers = std::vector<Matcher>;

  Impl(Request *owner) : _owner(owner) {}
  ~Impl() { _owner = nullptr; }

  void init_matchers() {
    auto set = [&](std::smatch &m, const std::string &method) {
      _environments["REQUEST_METHOD"] = method;
      _environments["REQUEST_URI"] = m[1];
      _environments["SERVER_PROTOCOL"] = m[2];
    };

    _matchers = {
        {std::regex("^([a-zA-Z0-9\\-]+): (.+)$"),
         [&](std::smatch &m) {
           std::string key = m[1];
           std::transform(key.begin(), key.end(), key.begin(),
                          [&](std::string::value_type c1) {
                            auto c2 = ::toupper(c1);
                            if (c2 == '-') {
                              c2 = '_';
                            }
                            return c2;
                          });
           _environments[key] = m[2];
         }},
        {std::regex("^GET (.+) (HTTP/\\d\\.\\d)$"),
         [&](std::smatch &m) {
           _owner->_method = rapid::Method::Get;
           _owner->_request_uri = m[1];
           set(m, "GET");
         }},
        {std::regex("^POST (.+) (HTTP/\\d\\.\\d)$"),
         [&](std::smatch &m) {
           _owner->_method = rapid::Method::Post;
           _owner->_request_uri = m[1];
           set(m, "POST");
         }},
    };
  }

  std::vector<std::string> split(const std::string &input) {
    std::istringstream stream(input);
    std::string result;
    std::vector<std::string> results;
    while (std::getline(stream, result, '\n')) {
      result.erase(result.size() - 1);
      results.emplace_back(result);
    }
    return std::move(results);
  }

  void parse(const std::string &raw_input) {
    init_matchers();
    auto rows = split(raw_input);

    if (!rows.empty()) {
      for (auto &row : rows) {
        for (auto &matcher : _matchers) {
          std::smatch match;
          if (std::regex_match(row, match, matcher.re)) {
            matcher.fn(match);
          }
        }
      }
    }
  }

  const Request::Environments &environments() const { return _environments; }

  void add_additional_environments(const Peer &peer) {
    _environments["GATEWAY_INTERFACE"] = "CGI/1.1";
    _environments["SERVER_ADDR"] = peer.server_addr;
    _environments["SERVER_NAME"] = peer.server_name;
    _environments["SERVER_SOFTWARE"] =
        std::string(RAPID_SOFTWARE_NAME "/" RAPID_VERSION);
    _environments["SERVER_PORT"] = peer.server_port;

    char buf[16];
    sprintf(buf, "%d", ::time(nullptr));
    _environments["REQUEST_TIME"] = buf;

    _environments["REMOTE_ADDR"] = peer.client_addr;
    _environments["REMOTE_PORT"] = peer.client_port;
  }

 private:
  Request *_owner = nullptr;
  Matchers _matchers;
  Request::Environments _environments;
};

Request::Request(const std::string &raw_input) : Request(raw_input, Peer()) {}

Request::Request(const std::string &raw_input, const Peer &peer)
    : _impl(new Impl(this)), _peer(peer) {
  _impl->parse(raw_input);
  _impl->add_additional_environments(_peer);
}

Request::~Request() {}

const Request::Environments &Request::environments() const {
  return _impl->environments();
}

std::string Request::user_agent() const {
  try {
    return environments().at("USER_AGENT");
  } catch (std::out_of_range &e) {
    return "";
  }
}
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: parametricpolypolygon.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: kz $ $Date: 2005-11-02 12:54:50 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <canvas/debug.hxx>
#include <canvas/canvastools.hxx>

#include <rtl/math.hxx>

#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/range/b2drectangle.hxx>
#include <basegfx/tools/canvastools.hxx>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/tools/tools.hxx>

#include <limits>

#include <canvas/parametricpolypolygon.hxx>

using namespace ::com::sun::star;

namespace canvas
{
    ParametricPolyPolygon* ParametricPolyPolygon::createLinearHorizontalGradient(
        const uno::Reference< rendering::XGraphicDevice >&  rDevice,
        const uno::Sequence< double >&                      leftColor,
        const uno::Sequence< double >&                      rightColor )
    {
        // TODO(P2): hold gradient brush statically, and only setup
        // the colors
        return new ParametricPolyPolygon( rDevice, GRADIENT_LINEAR, leftColor, rightColor );
    }

    ParametricPolyPolygon* ParametricPolyPolygon::createAxialHorizontalGradient(
        const uno::Reference< rendering::XGraphicDevice >&  rDevice,
        const uno::Sequence< double >&                      middleColor,
        const uno::Sequence< double >&                      endColor )
    {
        // TODO(P2): hold gradient brush statically, and only setup
        // the colors
        return new ParametricPolyPolygon( rDevice, GRADIENT_AXIAL, endColor, middleColor );
    }

    namespace
    {
        double calcAspectRatio( const geometry::RealRectangle2D& rBoundRect )
        {
            const double nWidth( rBoundRect.X2 - rBoundRect.X1 );
            const double nHeight( rBoundRect.Y2 - rBoundRect.Y1 );

            return ::basegfx::fTools::equalZero( nHeight ) ? 1.0 : fabs( nWidth / nHeight );
        }
    }

    ParametricPolyPolygon* ParametricPolyPolygon::createEllipticalGradient(
        const uno::Reference< rendering::XGraphicDevice >&  rDevice,
        const uno::Sequence< double >&                      centerColor,
        const uno::Sequence< double >&                      endColor,
        const geometry::RealRectangle2D&                    boundRect )
    {
        // TODO(P2): hold gradient polygon statically, and only setup
        // the colors
        return new ParametricPolyPolygon(
            rDevice,
            ::basegfx::tools::createPolygonFromCircle(
                ::basegfx::B2DPoint( 0.5, 0.5), 0.5 ),
            GRADIENT_ELLIPTICAL,
            endColor, centerColor,
            calcAspectRatio( boundRect ) );
    }

    ParametricPolyPolygon* ParametricPolyPolygon::createRectangularGradient( const uno::Reference< rendering::XGraphicDevice >& rDevice,
                                                                             const uno::Sequence< double >&                     centerColor,
                                                                             const uno::Sequence< double >&                     endColor,
                                                                             const geometry::RealRectangle2D&                   boundRect )
    {
        // TODO(P2): hold gradient polygon statically, and only setup
        // the colors
        return new ParametricPolyPolygon(
            rDevice,
            ::basegfx::tools::createPolygonFromRect(
                ::basegfx::B2DRectangle( 0.0, 0.0, 1.0, 1.0 ) ),
            GRADIENT_RECTANGULAR,
            endColor, centerColor,
            calcAspectRatio( boundRect ) );
    }

    void SAL_CALL ParametricPolyPolygon::disposing()
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        mxDevice.clear();
    }

    uno::Reference< rendering::XPolyPolygon2D > SAL_CALL ParametricPolyPolygon::getOutline( double t ) throw (lang::IllegalArgumentException, uno::RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        // TODO(F1): outline NYI
        return uno::Reference< rendering::XPolyPolygon2D >();
    }

    uno::Sequence< double > SAL_CALL ParametricPolyPolygon::getColor( double t ) throw (lang::IllegalArgumentException, uno::RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        // TODO(F1): color NYI
        return uno::Sequence< double >();
    }

    uno::Sequence< double > SAL_CALL ParametricPolyPolygon::getPointColor( const geometry::RealPoint2D& point ) throw (lang::IllegalArgumentException, uno::RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        // TODO(F1): point color NYI
        return uno::Sequence< double >();
    }

    uno::Reference< rendering::XColorSpace > SAL_CALL ParametricPolyPolygon::getColorSpace() throw (uno::RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        return mxDevice.is() ? mxDevice->getDeviceColorSpace() : uno::Reference< rendering::XColorSpace >();
    }

#define IMPLEMENTATION_NAME "Canvas::ParametricPolyPolygon"
#define SERVICE_NAME "com.sun.star.rendering.ParametricPolyPolygon"

    ::rtl::OUString SAL_CALL ParametricPolyPolygon::getImplementationName(  ) throw (uno::RuntimeException)
    {
        return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) );
    }

    sal_Bool SAL_CALL ParametricPolyPolygon::supportsService( const ::rtl::OUString& ServiceName ) throw (uno::RuntimeException)
    {
        return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ) );
    }

    uno::Sequence< ::rtl::OUString > SAL_CALL ParametricPolyPolygon::getSupportedServiceNames(  ) throw (uno::RuntimeException)
    {
        uno::Sequence< ::rtl::OUString > aRet(1);
        aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );

        return aRet;
    }

    ParametricPolyPolygon::~ParametricPolyPolygon()
    {
    }

    ParametricPolyPolygon::ParametricPolyPolygon( const uno::Reference< rendering::XGraphicDevice >&    rDevice,
                                                  const ::basegfx::B2DPolygon&                          rGradientPoly,
                                                  GradientType                                          eType,
                                                  const ::com::sun::star::uno::Sequence< double >&      rColor1,
                                                  const ::com::sun::star::uno::Sequence< double >&      rColor2 ) :
        ParametricPolyPolygon_Base( m_aMutex ),
        mxDevice( rDevice ),
        maValues( rGradientPoly,
                  rColor1,
                  rColor2,
                  1.0,
                  eType )
    {
    }

    ParametricPolyPolygon::ParametricPolyPolygon( const uno::Reference< rendering::XGraphicDevice >&    rDevice,
                                                  const ::basegfx::B2DPolygon&                          rGradientPoly,
                                                  GradientType                                          eType,
                                                  const ::com::sun::star::uno::Sequence< double >&      rColor1,
                                                  const ::com::sun::star::uno::Sequence< double >&      rColor2,
                                                  double                                                nAspectRatio ) :
        ParametricPolyPolygon_Base( m_aMutex ),
        mxDevice( rDevice ),
        maValues( rGradientPoly,
                  rColor1,
                  rColor2,
                  nAspectRatio,
                  eType )
    {
    }

    ParametricPolyPolygon::ParametricPolyPolygon( const uno::Reference< rendering::XGraphicDevice >&    rDevice,
                                                  GradientType                                          eType,
                                                  const ::com::sun::star::uno::Sequence< double >&      rColor1,
                                                  const ::com::sun::star::uno::Sequence< double >&      rColor2 ) :
        ParametricPolyPolygon_Base( m_aMutex ),
        mxDevice( rDevice ),
        maValues( ::basegfx::B2DPolygon(),
                  rColor1,
                  rColor2,
                  1.0,
                  eType )
    {
    }

    ParametricPolyPolygon::Values ParametricPolyPolygon::getValues() const
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        return maValues;
    }

}
<commit_msg>INTEGRATION: CWS warnings01 (1.2.8); FILE MERGED 2005/11/15 16:51:48 thb 1.2.8.1: #i55991# made code compile without warnings for gcc<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: parametricpolypolygon.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 02:18:37 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <canvas/debug.hxx>
#include <canvas/canvastools.hxx>

#include <rtl/math.hxx>

#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/range/b2drectangle.hxx>
#include <basegfx/tools/canvastools.hxx>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/tools/tools.hxx>

#include <limits>

#include <canvas/parametricpolypolygon.hxx>

using namespace ::com::sun::star;

namespace canvas
{
    ParametricPolyPolygon* ParametricPolyPolygon::createLinearHorizontalGradient(
        const uno::Reference< rendering::XGraphicDevice >&  rDevice,
        const uno::Sequence< double >&                      leftColor,
        const uno::Sequence< double >&                      rightColor )
    {
        // TODO(P2): hold gradient brush statically, and only setup
        // the colors
        return new ParametricPolyPolygon( rDevice, GRADIENT_LINEAR, leftColor, rightColor );
    }

    ParametricPolyPolygon* ParametricPolyPolygon::createAxialHorizontalGradient(
        const uno::Reference< rendering::XGraphicDevice >&  rDevice,
        const uno::Sequence< double >&                      middleColor,
        const uno::Sequence< double >&                      endColor )
    {
        // TODO(P2): hold gradient brush statically, and only setup
        // the colors
        return new ParametricPolyPolygon( rDevice, GRADIENT_AXIAL, endColor, middleColor );
    }

    namespace
    {
        double calcAspectRatio( const geometry::RealRectangle2D& rBoundRect )
        {
            const double nWidth( rBoundRect.X2 - rBoundRect.X1 );
            const double nHeight( rBoundRect.Y2 - rBoundRect.Y1 );

            return ::basegfx::fTools::equalZero( nHeight ) ? 1.0 : fabs( nWidth / nHeight );
        }
    }

    ParametricPolyPolygon* ParametricPolyPolygon::createEllipticalGradient(
        const uno::Reference< rendering::XGraphicDevice >&  rDevice,
        const uno::Sequence< double >&                      centerColor,
        const uno::Sequence< double >&                      endColor,
        const geometry::RealRectangle2D&                    boundRect )
    {
        // TODO(P2): hold gradient polygon statically, and only setup
        // the colors
        return new ParametricPolyPolygon(
            rDevice,
            ::basegfx::tools::createPolygonFromCircle(
                ::basegfx::B2DPoint( 0.5, 0.5), 0.5 ),
            GRADIENT_ELLIPTICAL,
            endColor, centerColor,
            calcAspectRatio( boundRect ) );
    }

    ParametricPolyPolygon* ParametricPolyPolygon::createRectangularGradient( const uno::Reference< rendering::XGraphicDevice >& rDevice,
                                                                             const uno::Sequence< double >&                     centerColor,
                                                                             const uno::Sequence< double >&                     endColor,
                                                                             const geometry::RealRectangle2D&                   boundRect )
    {
        // TODO(P2): hold gradient polygon statically, and only setup
        // the colors
        return new ParametricPolyPolygon(
            rDevice,
            ::basegfx::tools::createPolygonFromRect(
                ::basegfx::B2DRectangle( 0.0, 0.0, 1.0, 1.0 ) ),
            GRADIENT_RECTANGULAR,
            endColor, centerColor,
            calcAspectRatio( boundRect ) );
    }

    void SAL_CALL ParametricPolyPolygon::disposing()
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        mxDevice.clear();
    }

    uno::Reference< rendering::XPolyPolygon2D > SAL_CALL ParametricPolyPolygon::getOutline( double /*t*/ ) throw (lang::IllegalArgumentException, uno::RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        // TODO(F1): outline NYI
        return uno::Reference< rendering::XPolyPolygon2D >();
    }

    uno::Sequence< double > SAL_CALL ParametricPolyPolygon::getColor( double /*t*/ ) throw (lang::IllegalArgumentException, uno::RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        // TODO(F1): color NYI
        return uno::Sequence< double >();
    }

    uno::Sequence< double > SAL_CALL ParametricPolyPolygon::getPointColor( const geometry::RealPoint2D& /*point*/ ) throw (lang::IllegalArgumentException, uno::RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        // TODO(F1): point color NYI
        return uno::Sequence< double >();
    }

    uno::Reference< rendering::XColorSpace > SAL_CALL ParametricPolyPolygon::getColorSpace() throw (uno::RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        return mxDevice.is() ? mxDevice->getDeviceColorSpace() : uno::Reference< rendering::XColorSpace >();
    }

#define IMPLEMENTATION_NAME "Canvas::ParametricPolyPolygon"
#define SERVICE_NAME "com.sun.star.rendering.ParametricPolyPolygon"

    ::rtl::OUString SAL_CALL ParametricPolyPolygon::getImplementationName(  ) throw (uno::RuntimeException)
    {
        return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) );
    }

    sal_Bool SAL_CALL ParametricPolyPolygon::supportsService( const ::rtl::OUString& ServiceName ) throw (uno::RuntimeException)
    {
        return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ) );
    }

    uno::Sequence< ::rtl::OUString > SAL_CALL ParametricPolyPolygon::getSupportedServiceNames(  ) throw (uno::RuntimeException)
    {
        uno::Sequence< ::rtl::OUString > aRet(1);
        aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );

        return aRet;
    }

    ParametricPolyPolygon::~ParametricPolyPolygon()
    {
    }

    ParametricPolyPolygon::ParametricPolyPolygon( const uno::Reference< rendering::XGraphicDevice >&    rDevice,
                                                  const ::basegfx::B2DPolygon&                          rGradientPoly,
                                                  GradientType                                          eType,
                                                  const ::com::sun::star::uno::Sequence< double >&      rColor1,
                                                  const ::com::sun::star::uno::Sequence< double >&      rColor2 ) :
        ParametricPolyPolygon_Base( m_aMutex ),
        mxDevice( rDevice ),
        maValues( rGradientPoly,
                  rColor1,
                  rColor2,
                  1.0,
                  eType )
    {
    }

    ParametricPolyPolygon::ParametricPolyPolygon( const uno::Reference< rendering::XGraphicDevice >&    rDevice,
                                                  const ::basegfx::B2DPolygon&                          rGradientPoly,
                                                  GradientType                                          eType,
                                                  const ::com::sun::star::uno::Sequence< double >&      rColor1,
                                                  const ::com::sun::star::uno::Sequence< double >&      rColor2,
                                                  double                                                nAspectRatio ) :
        ParametricPolyPolygon_Base( m_aMutex ),
        mxDevice( rDevice ),
        maValues( rGradientPoly,
                  rColor1,
                  rColor2,
                  nAspectRatio,
                  eType )
    {
    }

    ParametricPolyPolygon::ParametricPolyPolygon( const uno::Reference< rendering::XGraphicDevice >&    rDevice,
                                                  GradientType                                          eType,
                                                  const ::com::sun::star::uno::Sequence< double >&      rColor1,
                                                  const ::com::sun::star::uno::Sequence< double >&      rColor2 ) :
        ParametricPolyPolygon_Base( m_aMutex ),
        mxDevice( rDevice ),
        maValues( ::basegfx::B2DPolygon(),
                  rColor1,
                  rColor2,
                  1.0,
                  eType )
    {
    }

    ParametricPolyPolygon::Values ParametricPolyPolygon::getValues() const
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        return maValues;
    }

}
<|endoftext|>


<commit_before>/****************************************************************************

    worker.hpp - Support file for writing LV2 plugins in C++

    Copyright (C) 2012 Michael Fisher <mfisher31@gmail.com>

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

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

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

****************************************************************************/

#ifndef LV2_WORKER_HPP
#define LV2_WORKER_HPP

#include <lv2/lv2plug.in/ns/ext/worker/worker.h>

namespace LV2 {

   /** Convenience enum to get LV2_Worker_Status into a C++ namespace */
   typedef enum {
      WORKER_SUCCESS      = LV2_WORKER_SUCCESS,      /**< Work Completed. */
      WORKER_ERR_UNKNOWN  = LV2_WORKER_ERR_UNKNOWN,  /**< Unknown error. */
      WORKER_ERR_NO_SPACE = LV2_WORKER_ERR_NO_SPACE  /**< Fail due to Lack of Space. */
   } WorkerStatus;

   typedef LV2_Worker_Respond_Handle    WorkerRespondHandle;
   typedef LV2_Worker_Respond_Function  WorkerRespondFunction;
   typedef LV2_Worker_Schedule          WorkerSchedule;

   /**
       Wrapper struct for state retrieval. This wraps an
       LV2_State_Retrieve_Function and exeucutes via operator ()
    */
   struct WorkerRespond {
      WorkerRespond(LV2_Handle instance,
                    WorkerRespondFunction wrfunc,
                    WorkerRespondHandle handle)
      : p_instance(instance), p_wrfunc(wrfunc), p_handle(handle) { }

      /**
          Execute the retrieve functor.
          @param key
          @param size
          @param type
          @param flags
          @return Associate 'value' data for the given key
       */
      WorkerStatus operator () (uint32_t size, const void* data)
      {
         return (WorkerStatus) p_wrfunc (p_handle, size, data);
      }

   private:
      LV2_Handle                p_instance;
      WorkerRespondHandle       p_handle;
      WorkerRespondFunction     p_wrfunc;
   };

   /** The LV2 Worker Feature.
       The actual type that your plugin class will inherit when you use
       this mixin is the internal struct template I.
       @ingroup pluginmixins
    */
   LV2MM_MIXIN_CLASS Worker {

      /** This is the type that your plugin class will inherit when you use the
          Worker mixin. The public and protected members defined here
          will be available in your plugin class.
      */
      LV2MM_MIXIN_DERIVED {

         /** @internal */
         static void map_feature_handlers(FeatureHandlerMap& hmap)
         {
            hmap[LV2_WORKER__schedule] = &I<Derived>::handle_feature;
         }

         /** @internal */
         static void handle_feature(void* instance, void* data)
         {
            Derived* d = reinterpret_cast<Derived*>(instance);
            I<Derived>* fe = static_cast<I<Derived>*>(d);

            if (LV2MM_DEBUG) {
               std::clog<<"  [LV2::Worker] handle_feature\n";
            }

            WorkerSchedule *ws = reinterpret_cast<WorkerSchedule*>(data);
            fe->m_worker_schedule_handle = ws->handle;
            fe->m_schedule_work_func = ws->schedule_work;
            fe->m_ok = true;
         }

         /** @internal */
         bool check_ok()
         {
            if (LV2MM_DEBUG) {
              std::clog<<"    [LV2::Worker] Validation "
                       <<(this->m_ok ? "succeeded" : "failed")<<"."<<std::endl;
            }
            return this->m_ok;
         }

         /** @internal */
         static const void* extension_data (const char* uri)
         {
            if (!std::strcmp (uri, LV2_WORKER__interface)) {
               static LV2_Worker_Interface worker = { &I<Derived>::_work,
                                                      &I<Derived>::_work_response,
                                                      &I<Derived>::_end_run };
               return &worker;
            }

            return 0;
         }

         /**
            Request from run() that the host call the worker.

            This function is in the audio threading class.  It should be called from
            run() to request that the host call the work() method in a non-realtime
            context with the given arguments.

            This function is always safe to call from run(), but it is not
            guaranteed that the worker is actually called from a different thread.
            In particular, when free-wheeling (e.g. for offline rendering), the
            worker may be executed immediately.  This allows single-threaded
            processing with sample accuracy and avoids timing problems when run() is
            executing much faster or slower than real-time.

            Plugins SHOULD be written in such a way that if the worker runs
            immediately, and responses from the worker are delivered immediately,
            the effect of the work takes place immediately with sample accuracy.

            The @p data MUST be safe for the host to copy and later pass to work(),
            and the host MUST guarantee that it will be eventually passed to work()
            if this function returns LV2::WORKER_SUCCESS.

            @param size   The size of @p data.
            @param data   Message to pass to work(), or NULL.
         */
          WorkerStatus schedule_work (uint32_t size, void *data)
          {
            return (WorkerStatus)m_schedule_work_func(
                                    m_worker_schedule_handle, size, data);
          }

         /**
            This is called by the host in a non-realtime context as requested,
            possibly with an arbitrary message to handle. A response can be sent
            to run() using @p respond.  The plugin MUST NOT make any assumptions
            about which thread calls this method, other than the fact that there
            are no real-time requirements.

            @param respond  A functor for sending a response to run().
            @param size     The size of @p data.
            @param data     Data from run(), or NULL.
         */
          WorkerStatus work(WorkerRespond        &respond,
                            uint32_t             size,
                            const void*          data)
          {
             return WORKER_SUCCESS;
          }

          /**
              Handle a response from the worker.  This is called by the host in the
              run() context when a response from the worker is ready.

              @param size     The size of @p body.
              @param body     Message body, or NULL.
           */
          WorkerStatus work_response (uint32_t size, const void* body)
          {
             return WORKER_SUCCESS;
          }

         /**
            Called when all responses for this cycle have been delivered.

            Since work_response() may be called after run() finished, this provides
            a hook for code that must run after the cycle is completed.

            This field may be NULL if the plugin has no use for it.  Otherwise, the
            host MUST call it after every run(), regardless of whether or not any
            responses were sent that cycle.
         */
          WorkerStatus end_run()
          {
             return WORKER_SUCCESS;
          }

        protected:

         /* LV2 Worker C API Implementation */

         /** @internal */
         LV2_Worker_Schedule_Handle m_worker_schedule_handle;

         /** @internal */
         LV2_Worker_Status (*m_schedule_work_func)(LV2_Worker_Schedule_Handle handle,
                                                   uint32_t                   size,
                                                   const void*                data);

         /** @internal */
         static LV2_Worker_Status _work(LV2_Handle                  instance,
                                        LV2_Worker_Respond_Function respond,
                                        LV2_Worker_Respond_Handle   handle,
                                        uint32_t                    size,
                                        const void*                 data)
         {
            Derived* plugin = reinterpret_cast<Derived*>(instance);
            WorkerRespond wrsp (instance, respond, handle);
            return (LV2_Worker_Status)plugin->work(wrsp, size, data);
         }

         /** @internal */
         static LV2_Worker_Status _work_response (LV2_Handle  instance,
                                                  uint32_t    size,
                                                  const void* body)
         {
            Derived* plugin = reinterpret_cast<Derived*>(instance);
            return (LV2_Worker_Status)plugin->work_response (size, body);
         }

         /** @internal */
         static LV2_Worker_Status _end_run (LV2_Handle instance)
         {
          Derived* plugin = reinterpret_cast<Derived*>(instance);
          return (LV2_Worker_Status)plugin->end_run();
         }
      };
   };

} /* namespace LV2 */

#endif /* LV2_WORKER_HPP */
<commit_msg>Code Style Fixin's<commit_after>/****************************************************************************

    worker.hpp - Support file for writing LV2 plugins in C++

    Copyright (C) 2012 Michael Fisher <mfisher31@gmail.com>

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

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

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

****************************************************************************/

#ifndef LV2_WORKER_HPP
#define LV2_WORKER_HPP

#include <lv2/lv2plug.in/ns/ext/worker/worker.h>

namespace LV2 {

   /** Convenience enum to get LV2_Worker_Status into a C++ namespace */
   typedef enum {
      WORKER_SUCCESS      = LV2_WORKER_SUCCESS,      /**< Work Completed. */
      WORKER_ERR_UNKNOWN  = LV2_WORKER_ERR_UNKNOWN,  /**< Unknown error. */
      WORKER_ERR_NO_SPACE = LV2_WORKER_ERR_NO_SPACE  /**< Fail due to Lack of Space. */
   } WorkerStatus;

   typedef LV2_Worker_Respond_Handle    WorkerRespondHandle;
   typedef LV2_Worker_Respond_Function  WorkerRespondFunction;
   typedef LV2_Worker_Schedule          WorkerSchedule;

   /**
       Wrapper struct for state retrieval. This wraps an
       LV2_State_Retrieve_Function and exeucutes via operator ()
    */
   struct WorkerRespond {
      WorkerRespond(LV2_Handle instance,
                    WorkerRespondFunction wrfunc,
                    WorkerRespondHandle handle)
      : p_instance(instance), p_wrfunc(wrfunc), p_handle(handle) { }

      /**
          Execute the retrieve functor.
          @param key
          @param size
          @param type
          @param flags
          @return Associate 'value' data for the given key
       */
      WorkerStatus operator () (uint32_t size, const void* data)
      {
         return (WorkerStatus) p_wrfunc (p_handle, size, data);
      }

   private:
      LV2_Handle                p_instance;
      WorkerRespondHandle       p_handle;
      WorkerRespondFunction     p_wrfunc;
   };

   /** The LV2 Worker Feature.
       The actual type that your plugin class will inherit when you use
       this mixin is the internal struct template I.
       @ingroup pluginmixins
    */
   LV2MM_MIXIN_CLASS Worker {

      /** This is the type that your plugin class will inherit when you use the
          Worker mixin. The public and protected members defined here
          will be available in your plugin class.
      */
      LV2MM_MIXIN_DERIVED {

         /** @internal */
         static void
         map_feature_handlers(FeatureHandlerMap& hmap)
         {
            hmap[LV2_WORKER__schedule] = &I<Derived>::handle_feature;
         }

         /** @internal */
         static void
         handle_feature(void* instance, void* data)
         {
            Derived* d = reinterpret_cast<Derived*>(instance);
            I<Derived>* fe = static_cast<I<Derived>*>(d);

            if (LV2MM_DEBUG) {
               std::clog<<"  [LV2::Worker] handle_feature\n";
            }

            WorkerSchedule *ws = reinterpret_cast<WorkerSchedule*>(data);
            fe->m_worker_schedule_handle = ws->handle;
            fe->m_schedule_work_func = ws->schedule_work;
            fe->m_ok = true;
         }

         /** @internal */
         bool
         check_ok()
         {
            if (LV2MM_DEBUG) {
              std::clog<<"    [LV2::Worker] Validation "
                       <<(this->m_ok ? "succeeded" : "failed")<<"."<<std::endl;
            }
            return this->m_ok;
         }

         /** @internal */
         static const void*
         extension_data (const char* uri)
         {
            if (!std::strcmp (uri, LV2_WORKER__interface)) {
               static LV2_Worker_Interface worker = { &I<Derived>::_work,
                                                      &I<Derived>::_work_response,
                                                      &I<Derived>::_end_run };
               return &worker;
            }

            return 0;
         }

         /**
            Request from run() that the host call the worker.

            This function is in the audio threading class.  It should be called from
            run() to request that the host call the work() method in a non-realtime
            context with the given arguments.

            This function is always safe to call from run(), but it is not
            guaranteed that the worker is actually called from a different thread.
            In particular, when free-wheeling (e.g. for offline rendering), the
            worker may be executed immediately.  This allows single-threaded
            processing with sample accuracy and avoids timing problems when run() is
            executing much faster or slower than real-time.

            Plugins SHOULD be written in such a way that if the worker runs
            immediately, and responses from the worker are delivered immediately,
            the effect of the work takes place immediately with sample accuracy.

            The @p data MUST be safe for the host to copy and later pass to work(),
            and the host MUST guarantee that it will be eventually passed to work()
            if this function returns LV2::WORKER_SUCCESS.

            @param size   The size of @p data.
            @param data   Message to pass to work(), or NULL.
         */
          WorkerStatus
          schedule_work (uint32_t size, void *data)
          {
            return (WorkerStatus)m_schedule_work_func(
                                    m_worker_schedule_handle, size, data);
          }

         /**
            This is called by the host in a non-realtime context as requested,
            possibly with an arbitrary message to handle. A response can be sent
            to run() using @p respond.  The plugin MUST NOT make any assumptions
            about which thread calls this method, other than the fact that there
            are no real-time requirements.

            @param respond  A functor for sending a response to run().
            @param size     The size of @p data.
            @param data     Data from run(), or NULL.
         */
          WorkerStatus
          work(WorkerRespond        &respond,
                            uint32_t             size,
                            const void*          data)
          {
             return WORKER_SUCCESS;
          }

          /**
              Handle a response from the worker.  This is called by the host in the
              run() context when a response from the worker is ready.

              @param size     The size of @p body.
              @param body     Message body, or NULL.
           */
          WorkerStatus
          work_response
          (uint32_t size, const void* body)
          {
             return WORKER_SUCCESS;
          }

         /**
            Called when all responses for this cycle have been delivered.

            Since work_response() may be called after run() finished, this provides
            a hook for code that must run after the cycle is completed.

            This field may be NULL if the plugin has no use for it.  Otherwise, the
            host MUST call it after every run(), regardless of whether or not any
            responses were sent that cycle.
         */
          WorkerStatus
          end_run()
          {
             return WORKER_SUCCESS;
          }

        protected:

         /* LV2 Worker C API Implementation */

         /** @internal */
         LV2_Worker_Schedule_Handle m_worker_schedule_handle;

         /** @internal */
         LV2_Worker_Status (*m_schedule_work_func)(LV2_Worker_Schedule_Handle handle,
                                                   uint32_t                   size,
                                                   const void*                data);

         /** @internal */
         static LV2_Worker_Status _work(LV2_Handle               instance,
                                        LV2_Worker_Respond_Function respond,
                                        LV2_Worker_Respond_Handle   handle,
                                        uint32_t                    size,
                                        const void*                 data)
         {
            Derived* plugin = reinterpret_cast<Derived*>(instance);
            WorkerRespond wrsp (instance, respond, handle);
            return (LV2_Worker_Status)plugin->work(wrsp, size, data);
         }

         /** @internal */
         static LV2_Worker_Status _work_response (LV2_Handle  instance,
                                                  uint32_t    size,
                                                  const void* body)
         {
            Derived* plugin = reinterpret_cast<Derived*>(instance);
            return (LV2_Worker_Status)plugin->work_response (size, body);
         }

         /** @internal */
         static LV2_Worker_Status _end_run (LV2_Handle instance)
         {
            Derived* plugin = reinterpret_cast<Derived*>(instance);
            return (LV2_Worker_Status)plugin->end_run();
         }
      };
   };
} /* namespace LV2 */

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


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: configsettings.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2007-04-11 17:49:50 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef VCL_INC_CONFIGSETTINGS_HXX
#define VCL_INC_CONFIGSETTINGS_HXX

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif
#ifndef _UTL_CONFIGITEM_HXX_
#include <unotools/configitem.hxx>
#endif
#ifndef _VCL_DLLAPI_H
#include <vcl/dllapi.h>
#endif

#include <hash_map>

//........................................................................
namespace vcl
{
//........................................................................

    typedef std::hash_map< rtl::OUString, rtl::OUString, rtl::OUStringHash > OUStrMap;
    class SmallOUStrMap : public OUStrMap { public: SmallOUStrMap() : OUStrMap(1) {} };

    //====================================================================
    //= SettingsConfigItem
    //====================================================================
    class VCL_DLLPUBLIC SettingsConfigItem : public ::utl::ConfigItem
    {

        std::hash_map< rtl::OUString, SmallOUStrMap, rtl::OUStringHash > m_aSettings;

        virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString >& rPropertyNames );
        virtual void Commit();

        void getValues();
        SettingsConfigItem();
    public:
        virtual ~SettingsConfigItem();

        static SettingsConfigItem* get();

        const rtl::OUString& getValue( const rtl::OUString& rGroup, const rtl::OUString& rKey ) const;
        void setValue( const rtl::OUString& rGroup, const rtl::OUString& rKey, const rtl::OUString& rValue );
    };

//........................................................................
} // namespace vcl
//........................................................................

#endif // VCL_INC_CONFIGSETTINGS_HXX

<commit_msg>INTEGRATION: CWS changefileheader (1.2.320); FILE MERGED 2008/04/01 16:05:14 thb 1.2.320.3: #i85898# Stripping all external header guards 2008/04/01 13:01:07 thb 1.2.320.2: #i85898# Stripping all external header guards 2008/03/28 15:44:10 rt 1.2.320.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: configsettings.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef VCL_INC_CONFIGSETTINGS_HXX
#define VCL_INC_CONFIGSETTINGS_HXX

#include <rtl/ustring.hxx>
#include <com/sun/star/uno/Sequence.hxx>
#include <unotools/configitem.hxx>
#include <vcl/dllapi.h>

#include <hash_map>

//........................................................................
namespace vcl
{
//........................................................................

    typedef std::hash_map< rtl::OUString, rtl::OUString, rtl::OUStringHash > OUStrMap;
    class SmallOUStrMap : public OUStrMap { public: SmallOUStrMap() : OUStrMap(1) {} };

    //====================================================================
    //= SettingsConfigItem
    //====================================================================
    class VCL_DLLPUBLIC SettingsConfigItem : public ::utl::ConfigItem
    {

        std::hash_map< rtl::OUString, SmallOUStrMap, rtl::OUStringHash > m_aSettings;

        virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString >& rPropertyNames );
        virtual void Commit();

        void getValues();
        SettingsConfigItem();
    public:
        virtual ~SettingsConfigItem();

        static SettingsConfigItem* get();

        const rtl::OUString& getValue( const rtl::OUString& rGroup, const rtl::OUString& rKey ) const;
        void setValue( const rtl::OUString& rGroup, const rtl::OUString& rKey, const rtl::OUString& rValue );
    };

//........................................................................
} // namespace vcl
//........................................................................

#endif // VCL_INC_CONFIGSETTINGS_HXX

<|endoftext|>