<commit_before>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef DELETER_HH_
#define DELETER_HH_

#include <memory>

class deleter {
public:
    struct impl;
private:
    impl* _impl = nullptr;
public:
    deleter() = default;
    deleter(const deleter&) = delete;
    deleter(deleter&& x) : _impl(x._impl) { x._impl = nullptr; }
    explicit deleter(impl* i) : _impl(i) {}
    ~deleter();
    deleter& operator=(deleter&& x);
    deleter& operator=(deleter&) = delete;
    impl& operator*() const { return *_impl; }
    impl* operator->() const { return _impl; }
    impl* get() const { return _impl; }
    void unshare();
    deleter share();
    explicit operator bool() const { return bool(_impl); }
    void reset(impl* i) {
        this->~deleter();
        new (this) deleter(i);
    }
};

struct deleter::impl {
    unsigned refs = 1;
    deleter next;
    impl(deleter next) : next(std::move(next)) {}
    virtual ~impl() {}
};

inline
deleter::~deleter() {
    if (_impl && --_impl->refs == 0) {
        delete _impl;
    }
}

inline
deleter& deleter::operator=(deleter&& x) {
    if (this != &x) {
        this->~deleter();
        new (this) deleter(std::move(x));
    }
    return *this;
}

template <typename Deleter>
struct lambda_deleter_impl final : deleter::impl {
    Deleter del;
    lambda_deleter_impl(deleter next, Deleter&& del)
        : impl(std::move(next)), del(std::move(del)) {}
    virtual ~lambda_deleter_impl() override { del(); }
};

template <typename Deleter>
deleter
make_deleter(deleter next, Deleter d) {
    return deleter(new lambda_deleter_impl<Deleter>(std::move(next), std::move(d)));
}

inline
deleter
deleter::share() {
    if (!_impl) {
        return deleter();
    }
    ++_impl->refs;
    return deleter(_impl);
}

#endif /* DELETER_HH_ */
<commit_msg>Add make_free_deleter<commit_after>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef DELETER_HH_
#define DELETER_HH_

#include <memory>

class deleter {
public:
    struct impl;
private:
    impl* _impl = nullptr;
public:
    deleter() = default;
    deleter(const deleter&) = delete;
    deleter(deleter&& x) : _impl(x._impl) { x._impl = nullptr; }
    explicit deleter(impl* i) : _impl(i) {}
    ~deleter();
    deleter& operator=(deleter&& x);
    deleter& operator=(deleter&) = delete;
    impl& operator*() const { return *_impl; }
    impl* operator->() const { return _impl; }
    impl* get() const { return _impl; }
    void unshare();
    deleter share();
    explicit operator bool() const { return bool(_impl); }
    void reset(impl* i) {
        this->~deleter();
        new (this) deleter(i);
    }
};

struct deleter::impl {
    unsigned refs = 1;
    deleter next;
    impl(deleter next) : next(std::move(next)) {}
    virtual ~impl() {}
};

inline
deleter::~deleter() {
    if (_impl && --_impl->refs == 0) {
        delete _impl;
    }
}

inline
deleter& deleter::operator=(deleter&& x) {
    if (this != &x) {
        this->~deleter();
        new (this) deleter(std::move(x));
    }
    return *this;
}

template <typename Deleter>
struct lambda_deleter_impl final : deleter::impl {
    Deleter del;
    lambda_deleter_impl(deleter next, Deleter&& del)
        : impl(std::move(next)), del(std::move(del)) {}
    virtual ~lambda_deleter_impl() override { del(); }
};

template <typename Deleter>
deleter
make_deleter(deleter next, Deleter d) {
    return deleter(new lambda_deleter_impl<Deleter>(std::move(next), std::move(d)));
}

inline
deleter
deleter::share() {
    if (!_impl) {
        return deleter();
    }
    ++_impl->refs;
    return deleter(_impl);
}

inline
deleter
make_free_deleter(void* obj) {
    return make_deleter(deleter(), [obj] { free(obj); });
}

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


<commit_before>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  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.
 */
/*
 * Copyright (C) 2016 ScyllaDB.
 */

#pragma once

#include <functional>
#include "sstring.hh"
#include "core/shared_ptr.hh"
#include "core/metrics_registration.hh"

/*! \file metrics.hh
 *  \brief header for metrics creation.
 *
 *  This header file contains the metrics creation method with their helper function.
 *  Include this file when need to create metrics.
 *  Typically this will be in your source file.
 *
 *  Code that is under the impl namespace should not be used directly.
 *
 */

namespace seastar {

/*!
 * \namespace metrics
 * \brief metrics creation and registration
 *
 * the metrics namespace holds the relevant method and classes to generate metrics.
 *
 * The metrics layer support registering metrics, that later will be
 * exported via different API protocols.
 *
 * To be able to support multiple protocols the following simplifications where made:
 * 1. The id of the metrics is based on the collectd id
 * 2. A metric could be a single value either a reference or a function
 *
 * To add metrics definition to class A do the following:
 * * Add a metrics_group memeber to A
 * * Add a a set_metrics() method that would be called in the constructor.
 *
 *
 * In A header file
 * \code
 * #include "core/metrics_registration.hh"
 * class A {
 *   metric_groups _metrics
 *
 *   void setup_metrics();
 *
 * };
 * \endcode
 *
 * In A source file:
 *
 * \code
 * include "core/metrics.hh"
 *
 * void A::setup_metrics() {
 *   namespace sm = seastar::metrics;
 *   _metrics = sm::create_metric_group();
 *   _metrics->add_group("cache", {sm::make_gauge("bytes", "used", [this] { return _region.occupancy().used_space(); })});
 * }
 * \endcode
 */

namespace metrics {

/*!
 * \defgroup metrics_types metrics type definitions
 * The following are for the metric layer use, do not use them directly
 * Instead use the make_counter, make_gauge, make_absolute and make_derived
 *
 */
using metric_type_def = sstring; /*!< Used to hold an inherit type (like bytes)*/
using metric_name_type = sstring; /*!<  The metric name'*/
using instance_id_type = sstring; /*!<  typically used for the shard id*/

/*!
 * \brief Human-readable description of a metric/group.
 *
 *
 * Uses a separate class to deal with type resolution
 *
 * Add this to metric creation:
 *
 * \code
 * _metrics->add_group("groupname", {
 *   sm::make_gauge("metric_name", value, description("A documentation about the return value"))
 * });
 * \endcode
 *
 */
class description {
public:
    description(sstring s = sstring()) : _s(std::move(s))
    {}
    const sstring& str() const {
        return _s;
    }
private:
    sstring _s;
};

/*!
 * \namesapce impl
 * \brief holds the implementation parts of the metrics layer, do not use directly.
 *
 * The metrics layer define a thin API for adding metrics.
 * Some of the implementation details need to be in the header file, they should not be use directly.
 */
namespace impl {

// The value binding data types
enum class data_type : uint8_t {
    COUNTER, // unsigned int 64
    GAUGE, // double
    DERIVE, // signed int 64
    ABSOLUTE, // unsigned int 64
};

/*!
 * \breif A helper class that used to return metrics value.
 *
 * Do not use directly @see metrics_creation
 */
struct metric_value {
    union {
        double _d;
        uint64_t _ui;
        int64_t _i;
    } u;
    data_type _type;

    data_type type() const {
        return _type;
    }

    double d() const {
        return u._d;
    }

    uint64_t ui() const {
        return u._ui;
    }

    int64_t i() const {
        return u._i;
    }

    metric_value()
            : _type(data_type::GAUGE) {
    }

    template<typename T>
    metric_value(T i, data_type t)
            : _type(t) {
        switch (_type) {
        case data_type::DERIVE:
            u._i = i;
            break;
        case data_type::GAUGE:
            u._d = i;
            break;
        default:
            u._ui = i;
            break;
        }
    }

    metric_value& operator=(const metric_value& c) = default;

    metric_value& operator+=(const metric_value& c) {
        *this = *this + c;
        return *this;
    }

    metric_value operator+(const metric_value& c);
};

using metric_function = std::function<metric_value()>;

struct metric_type {
    data_type base_type;
    metric_type_def type_name;
};

struct metric_definition_impl {
    metric_name_type name;
    instance_id_type id;
    metric_type type;
    metric_function f;
    description d;
    bool enabled = true;
};

class metric_groups_def {
public:
    metric_groups_def() = default;
    virtual ~metric_groups_def() = default;
    metric_groups_def(const metric_groups_def&) = delete;
    metric_groups_def(metric_groups_def&&) = default;
    virtual metric_groups_def& add_metric(group_name_type name, const metric_definition& md) = 0;
    virtual metric_groups_def& add_group(group_name_type name, const std::initializer_list<metric_definition>& l) = 0;
    virtual metric_groups_def& add_group(group_name_type name, const std::vector<metric_definition>& l) = 0;
};

instance_id_type shard();

extern const bool metric_disabled;

template<typename T, typename En = std::true_type>
struct is_callable;

template<typename T>
struct is_callable<T, typename std::integral_constant<bool, !std::is_void<typename std::result_of<T()>::type>::value>::type> : public std::true_type {
};

template<typename T>
struct is_callable<T, typename std::enable_if<std::is_fundamental<T>::value, std::true_type>::type> : public std::false_type {
};

template<typename T, typename = std::enable_if_t<is_callable<T>::value>>
metric_function make_function(T val, data_type dt) {
    return [dt, val] {
        return metric_value(val(), dt);
    };
}

template<typename T, typename = std::enable_if_t<!is_callable<T>::value>>
metric_function make_function(T& val, data_type dt) {
    return [dt, &val] {
        return metric_value(val, dt);
    };
}
}
/*
 * The metrics definition are defined to be compatible with collectd metrics defintion.
 * Typically you should used gauge or derived.
 */

/*!
 * \brief Gauge are a general purpose metric.
 *
 * They can support floating point and can increase or decrease
 */
template<typename T>
impl::metric_definition_impl make_gauge(metric_name_type name,
        T val, description d=description(), bool enabled=true,
        instance_id_type instance = impl::shard(), metric_type_def iht = "gauge") {
    return {name, instance, {impl::data_type::GAUGE, iht}, make_function(val, impl::data_type::GAUGE), d, enabled};
}

/*!
 * \brief Derive are used when a rate is more interesting than the value.
 *
 * Derive is an integer value that can increase or decrease, typically it is used when looking at the
 * derivation of the value.
 *
 * It is OK to use it when counting things and if no wrap-around is expected (it shouldn't) it's prefer over counter metric.
 */
template<typename T>
impl::metric_definition_impl make_derive(metric_name_type name,
        T val, description d=description(), bool enabled=true,
        instance_id_type instance = impl::shard(), metric_type_def iht = "derive") {
    return {name, instance, {impl::data_type::DERIVE, iht}, make_function(val, impl::data_type::DERIVE), d, enabled};
}

/*!
 * \brief create a counter metric
 *
 * Counters are similar to derived, but they assume monotony, so if a counter value decrease in a series it is count as a wrap-around.
 * It is better to use large enough data value than to use counter.
 *
 */
template<typename T>
impl::metric_definition_impl make_counter(metric_name_type name,
        T val, description d=description(), bool enabled=true,
        instance_id_type instance = impl::shard(), metric_type_def iht = "counter") {
    return {name, instance, {impl::data_type::COUNTER, iht}, make_function(val, impl::data_type::COUNTER), d, enabled};
}

/*!
 * \brief create an absolute metric.
 *
 * Absolute are used for metric that are being erased after each time they are read.
 * They are here for compatibility reasons and should general be avoided in most applications.
 */
template<typename T>
impl::metric_definition_impl make_absolute(metric_name_type name,
        T val, description d=description(), bool enabled=true,
        instance_id_type instance = impl::shard(), metric_type_def iht = "absolute") {
    return {name, instance, {impl::data_type::ABSOLUTE, iht}, make_function(val, impl::data_type::ABSOLUTE), d, enabled};
}

/*!
 * \brief create a total_bytes metric.
 *
 * total_bytes are used for an ever growing counters, like the total bytes
 * passed on a network.
 */

template<typename T>
impl::metric_definition_impl make_total_bytes(metric_name_type name,
        T val, description d=description(), bool enabled=true,
        instance_id_type instance = impl::shard()) {
    return make_derive(name, val, d, enabled, instance, "total_bytes");
}

/*!
 * \brief create a current_bytes metric.
 *
 * current_bytes are used to report on current status in bytes.
 * For example the current free memory.
 */

template<typename T>
impl::metric_definition_impl make_current_bytes(metric_name_type name,
        T val, description d=description(), bool enabled=true,
        instance_id_type instance = impl::shard()) {
    return make_derive(name, val, d, enabled, instance, "bytes");
}

/*!
 * \brief create a queue_length metric.
 *
 * queue_length are used to report on queue length
 */

template<typename T>
impl::metric_definition_impl make_queue_length(metric_name_type name,
        T val, description d=description(), bool enabled=true,
        instance_id_type instance = impl::shard()) {
    return make_gauge(name, val, d, enabled, instance, "queue_length");
}

/*!
 * \brief create a total operation metric.
 *
 * total_operations are used for ever growing operation counter.
 */

template<typename T>
impl::metric_definition_impl make_total_operations(metric_name_type name,
        T val, description d=description(), bool enabled=true,
        instance_id_type instance = impl::shard()) {
    return make_derive(name, val, d, enabled, instance, "total_operations");
}

/*! @} */
}
}
<commit_msg>metrics: Metrics function should take variable as a refernce<commit_after>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  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.
 */
/*
 * Copyright (C) 2016 ScyllaDB.
 */

#pragma once

#include <functional>
#include "sstring.hh"
#include "core/shared_ptr.hh"
#include "core/metrics_registration.hh"

/*! \file metrics.hh
 *  \brief header for metrics creation.
 *
 *  This header file contains the metrics creation method with their helper function.
 *  Include this file when need to create metrics.
 *  Typically this will be in your source file.
 *
 *  Code that is under the impl namespace should not be used directly.
 *
 */

namespace seastar {

/*!
 * \namespace metrics
 * \brief metrics creation and registration
 *
 * the metrics namespace holds the relevant method and classes to generate metrics.
 *
 * The metrics layer support registering metrics, that later will be
 * exported via different API protocols.
 *
 * To be able to support multiple protocols the following simplifications where made:
 * 1. The id of the metrics is based on the collectd id
 * 2. A metric could be a single value either a reference or a function
 *
 * To add metrics definition to class A do the following:
 * * Add a metrics_group memeber to A
 * * Add a a set_metrics() method that would be called in the constructor.
 *
 *
 * In A header file
 * \code
 * #include "core/metrics_registration.hh"
 * class A {
 *   metric_groups _metrics
 *
 *   void setup_metrics();
 *
 * };
 * \endcode
 *
 * In A source file:
 *
 * \code
 * include "core/metrics.hh"
 *
 * void A::setup_metrics() {
 *   namespace sm = seastar::metrics;
 *   _metrics = sm::create_metric_group();
 *   _metrics->add_group("cache", {sm::make_gauge("bytes", "used", [this] { return _region.occupancy().used_space(); })});
 * }
 * \endcode
 */

namespace metrics {

/*!
 * \defgroup metrics_types metrics type definitions
 * The following are for the metric layer use, do not use them directly
 * Instead use the make_counter, make_gauge, make_absolute and make_derived
 *
 */
using metric_type_def = sstring; /*!< Used to hold an inherit type (like bytes)*/
using metric_name_type = sstring; /*!<  The metric name'*/
using instance_id_type = sstring; /*!<  typically used for the shard id*/

/*!
 * \brief Human-readable description of a metric/group.
 *
 *
 * Uses a separate class to deal with type resolution
 *
 * Add this to metric creation:
 *
 * \code
 * _metrics->add_group("groupname", {
 *   sm::make_gauge("metric_name", value, description("A documentation about the return value"))
 * });
 * \endcode
 *
 */
class description {
public:
    description(sstring s = sstring()) : _s(std::move(s))
    {}
    const sstring& str() const {
        return _s;
    }
private:
    sstring _s;
};

/*!
 * \namesapce impl
 * \brief holds the implementation parts of the metrics layer, do not use directly.
 *
 * The metrics layer define a thin API for adding metrics.
 * Some of the implementation details need to be in the header file, they should not be use directly.
 */
namespace impl {

// The value binding data types
enum class data_type : uint8_t {
    COUNTER, // unsigned int 64
    GAUGE, // double
    DERIVE, // signed int 64
    ABSOLUTE, // unsigned int 64
};

/*!
 * \breif A helper class that used to return metrics value.
 *
 * Do not use directly @see metrics_creation
 */
struct metric_value {
    union {
        double _d;
        uint64_t _ui;
        int64_t _i;
    } u;
    data_type _type;

    data_type type() const {
        return _type;
    }

    double d() const {
        return u._d;
    }

    uint64_t ui() const {
        return u._ui;
    }

    int64_t i() const {
        return u._i;
    }

    metric_value()
            : _type(data_type::GAUGE) {
    }

    template<typename T>
    metric_value(T i, data_type t)
            : _type(t) {
        switch (_type) {
        case data_type::DERIVE:
            u._i = i;
            break;
        case data_type::GAUGE:
            u._d = i;
            break;
        default:
            u._ui = i;
            break;
        }
    }

    metric_value& operator=(const metric_value& c) = default;

    metric_value& operator+=(const metric_value& c) {
        *this = *this + c;
        return *this;
    }

    metric_value operator+(const metric_value& c);
};

using metric_function = std::function<metric_value()>;

struct metric_type {
    data_type base_type;
    metric_type_def type_name;
};

struct metric_definition_impl {
    metric_name_type name;
    instance_id_type id;
    metric_type type;
    metric_function f;
    description d;
    bool enabled = true;
};

class metric_groups_def {
public:
    metric_groups_def() = default;
    virtual ~metric_groups_def() = default;
    metric_groups_def(const metric_groups_def&) = delete;
    metric_groups_def(metric_groups_def&&) = default;
    virtual metric_groups_def& add_metric(group_name_type name, const metric_definition& md) = 0;
    virtual metric_groups_def& add_group(group_name_type name, const std::initializer_list<metric_definition>& l) = 0;
    virtual metric_groups_def& add_group(group_name_type name, const std::vector<metric_definition>& l) = 0;
};

instance_id_type shard();

extern const bool metric_disabled;

template<typename T, typename En = std::true_type>
struct is_callable;

template<typename T>
struct is_callable<T, typename std::integral_constant<bool, !std::is_void<typename std::result_of<T()>::type>::value>::type> : public std::true_type {
};

template<typename T>
struct is_callable<T, typename std::enable_if<std::is_fundamental<T>::value, std::true_type>::type> : public std::false_type {
};

template<typename T, typename = std::enable_if_t<is_callable<T>::value>>
metric_function make_function(T val, data_type dt) {
    return [dt, val] {
        return metric_value(val(), dt);
    };
}

template<typename T, typename = std::enable_if_t<!is_callable<T>::value>>
metric_function make_function(T& val, data_type dt) {
    return [dt, &val] {
        return metric_value(val, dt);
    };
}
}
/*
 * The metrics definition are defined to be compatible with collectd metrics defintion.
 * Typically you should used gauge or derived.
 */

/*!
 * \brief Gauge are a general purpose metric.
 *
 * They can support floating point and can increase or decrease
 */
template<typename T>
impl::metric_definition_impl make_gauge(metric_name_type name,
        T&& val, description d=description(), bool enabled=true,
        instance_id_type instance = impl::shard(), metric_type_def iht = "gauge") {
    return {name, instance, {impl::data_type::GAUGE, iht}, make_function(std::forward<T>(val), impl::data_type::GAUGE), d, enabled};
}

/*!
 * \brief Derive are used when a rate is more interesting than the value.
 *
 * Derive is an integer value that can increase or decrease, typically it is used when looking at the
 * derivation of the value.
 *
 * It is OK to use it when counting things and if no wrap-around is expected (it shouldn't) it's prefer over counter metric.
 */
template<typename T>
impl::metric_definition_impl make_derive(metric_name_type name,
        T&& val, description d=description(), bool enabled=true,
        instance_id_type instance = impl::shard(), metric_type_def iht = "derive") {
    return {name, instance, {impl::data_type::DERIVE, iht}, make_function(std::forward<T>(val), impl::data_type::DERIVE), d, enabled};
}

/*!
 * \brief create a counter metric
 *
 * Counters are similar to derived, but they assume monotony, so if a counter value decrease in a series it is count as a wrap-around.
 * It is better to use large enough data value than to use counter.
 *
 */
template<typename T>
impl::metric_definition_impl make_counter(metric_name_type name,
        T&& val, description d=description(), bool enabled=true,
        instance_id_type instance = impl::shard(), metric_type_def iht = "counter") {
    return {name, instance, {impl::data_type::COUNTER, iht}, make_function(std::forward<T>(val), impl::data_type::COUNTER), d, enabled};
}

/*!
 * \brief create an absolute metric.
 *
 * Absolute are used for metric that are being erased after each time they are read.
 * They are here for compatibility reasons and should general be avoided in most applications.
 */
template<typename T>
impl::metric_definition_impl make_absolute(metric_name_type name,
        T&& val, description d=description(), bool enabled=true,
        instance_id_type instance = impl::shard(), metric_type_def iht = "absolute") {
    return {name, instance, {impl::data_type::ABSOLUTE, iht}, make_function(std::forward<T>(val), impl::data_type::ABSOLUTE), d, enabled};
}

/*!
 * \brief create a total_bytes metric.
 *
 * total_bytes are used for an ever growing counters, like the total bytes
 * passed on a network.
 */

template<typename T>
impl::metric_definition_impl make_total_bytes(metric_name_type name,
        T&& val, description d=description(), bool enabled=true,
        instance_id_type instance = impl::shard()) {
    return make_derive(name, std::forward<T>(val), d, enabled, instance, "total_bytes");
}

/*!
 * \brief create a current_bytes metric.
 *
 * current_bytes are used to report on current status in bytes.
 * For example the current free memory.
 */

template<typename T>
impl::metric_definition_impl make_current_bytes(metric_name_type name,
        T&& val, description d=description(), bool enabled=true,
        instance_id_type instance = impl::shard()) {
    return make_derive(name, std::forward<T>(val), d, enabled, instance, "bytes");
}

/*!
 * \brief create a queue_length metric.
 *
 * queue_length are used to report on queue length
 */

template<typename T>
impl::metric_definition_impl make_queue_length(metric_name_type name,
        T&& val, description d=description(), bool enabled=true,
        instance_id_type instance = impl::shard()) {
    return make_gauge(name, std::forward<T>(val), d, enabled, instance, "queue_length");
}

/*!
 * \brief create a total operation metric.
 *
 * total_operations are used for ever growing operation counter.
 */

template<typename T>
impl::metric_definition_impl make_total_operations(metric_name_type name,
        T&& val, description d=description(), bool enabled=true,
        instance_id_type instance = impl::shard()) {
    return make_derive(name, std::forward<T>(val), d, enabled, instance, "total_operations");
}

/*! @} */
}
}
<|endoftext|>


<commit_before>/*
 * Copyright 2014 Cloudius Systems
 */

#ifndef SSTRING_HH_
#define SSTRING_HH_

#include <stdint.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <stdexcept>
#include <initializer_list>
#include <iostream>
#include <functional>
#include <cstdio>

template <typename char_type, typename size_type, size_type max_size>
class basic_sstring {
    union contents {
        struct external_type {
            char* str;
            size_type size;
            int8_t pad;
        } external;
        struct internal_type {
            char str[max_size];
            int8_t size;
        } internal;
        static_assert(sizeof(external_type) <= sizeof(internal_type), "max_size too small");
        static_assert(max_size <= 127, "max_size too large");
    } u;
    bool is_internal() const noexcept {
        return u.internal.size >= 0;
    }
    bool is_external() const noexcept {
        return !is_internal();
    }
    const char* str() const {
        return is_internal() ? u.internal.str : u.external.str;
    }
    char* str() {
        return is_internal() ? u.internal.str : u.external.str;
    }
    struct initialized_later {};
public:
    basic_sstring() noexcept {
        u.internal.size = 0;
        u.internal.str[0] = '\0';
    }
    basic_sstring(const basic_sstring& x) {
        if (x.is_internal()) {
            u.internal = x.u.internal;
        } else {
            u.internal.size = -1;
            u.external.str = new char[x.u.external.size + 1];
            std::copy(x.u.external.str, x.u.external.str + x.u.external.size + 1, u.external.str);
            u.external.size = x.u.external.size;
        }
    }
    basic_sstring(basic_sstring&& x) noexcept {
        u = x.u;
        x.u.internal.size = 0;
        x.u.internal.str[0] = '\0';
    }
    basic_sstring(initialized_later, size_t size) {
        if (size_type(size) != size) {
            throw std::overflow_error("sstring overflow");
        }
        if (size + 1 <= sizeof(u.internal.str)) {
            u.internal.str[size] = '\0';
            u.internal.size = size;
        } else {
            u.internal.size = -1;
            u.external.str = new char[size + 1];
            u.external.size = size;
            u.external.str[size] = '\0';
        }
    }
    basic_sstring(const char_type* x, size_t size) {
        if (size_type(size) != size) {
            throw std::overflow_error("sstring overflow");
        }
        if (size + 1 <= sizeof(u.internal.str)) {
            std::copy(x, x + size, u.internal.str);
            u.internal.str[size] = '\0';
            u.internal.size = size;
        } else {
            u.internal.size = -1;
            u.external.str = new char[size + 1];
            u.external.size = size;
            std::copy(x, x + size, u.external.str);
            u.external.str[size] = '\0';
        }
    }
    basic_sstring(const char_type* x) : basic_sstring(x, std::strlen(x)) {}
    basic_sstring(std::basic_string<char_type>& x) : basic_sstring(x.c_str(), x.size()) {}
    basic_sstring(std::initializer_list<char_type> x) : basic_sstring(x.begin(), x.end() - x.begin()) {}
    basic_sstring(const char_type* b, const char_type* e) : basic_sstring(b, e - b) {}
    ~basic_sstring() noexcept {
        if (is_external()) {
            delete[] u.external.str;
        }
    }
    basic_sstring& operator=(const basic_sstring& x) {
        basic_sstring tmp(x);
        swap(tmp);
    }
    basic_sstring& operator=(basic_sstring&& x) noexcept {
        if (this != &x) {
            swap(x);
            x.reset();
        }
        return *this;
    }
    operator std::string() const {
        return str();
    }
    size_t size() const noexcept {
        return is_internal() ? u.internal.size : u.external.size;
    }
    bool empty() const noexcept {
        return u.internal.size == 0;
    }
    void reset() noexcept {
        if (is_external()) {
            delete[] u.external.str;
        }
        u.internal.size = 0;
        u.internal.str[0] = '\0';
    }
    void swap(basic_sstring& x) noexcept {
        contents tmp;
        tmp = x.u;
        x.u = u;
        u = tmp;
    }
    const char* c_str() const {
        return str();
    }
    const char_type* begin() const { return str(); }
    const char_type* end() const { return str() + size(); }
    char_type* begin() { return str(); }
    char_type* end() { return str() + size(); }
    bool operator==(const basic_sstring& x) const {
        return size() == x.size() && std::equal(begin(), end(), x.begin());
    }
    bool operator!=(const basic_sstring& x) const {
        return !operator==(x);
    }
    basic_sstring operator+(const basic_sstring& x) const {
        basic_sstring ret(initialized_later(), size() + x.size());
        std::copy(begin(), end(), ret.begin());
        std::copy(x.begin(), x.end(), ret.begin() + size());
        return ret;
    }
    basic_sstring& operator+=(const basic_sstring& x) {
        return *this = *this + x;
    }
};

template <typename char_type, typename size_type, size_type max_size>
inline
void swap(basic_sstring<char_type, size_type, max_size>& x,
          basic_sstring<char_type, size_type, max_size>& y) noexcept
{
    return x.swap(y);
}

template <typename char_type, typename size_type, size_type max_size, typename char_traits>
inline
std::basic_ostream<char_type, char_traits>&
operator<<(std::basic_ostream<char_type, char_traits>& os,
        const basic_sstring<char_type, size_type, max_size>& s) {
    return os.write(s.begin(), s.size());
}

namespace std {

template <typename char_type, typename size_type, size_type max_size>
struct hash<basic_sstring<char_type, size_type, max_size>> {
    size_t operator()(const basic_sstring<char_type, size_type, max_size>& s) const {
        size_t ret = 0;
        for (auto c : s) {
            ret = (ret << 6) | (ret >> (sizeof(ret) * 8 - 6));
            ret ^= c;
        }
        return ret;
    }
};

}

using sstring = basic_sstring<char, uint32_t, 15>;

template <typename T, typename String = sstring, typename for_enable_if = void*>
String to_sstring(T value, for_enable_if);

template <typename T>
inline
sstring to_sstring_sprintf(T value, const char* fmt) {
    char tmp[sizeof(value) / 3 + 3];
    auto len = std::sprintf(tmp, fmt, value);
    return sstring(tmp, len);
}

template <typename string_type = sstring>
inline
string_type to_sstring(int value, void* = nullptr) {
    return to_sstring_sprintf(value, "%d");
}

template <typename string_type = sstring>
inline
string_type to_sstring(unsigned value, void* = nullptr) {
    return to_sstring_sprintf(value, "%u");
}

template <typename string_type = sstring>
inline
string_type to_sstring(long value, void* = nullptr) {
    return to_sstring_sprintf(value, "%ld");
}

template <typename string_type = sstring>
inline
string_type to_sstring(unsigned long value, void* = nullptr) {
    return to_sstring_sprintf(value, "%lu");
}

template <typename string_type = sstring>
inline
string_type to_sstring(long long value, void* = nullptr) {
    return to_sstring_sprintf(value, "%lld");
}

template <typename string_type = sstring>
inline
string_type to_sstring(unsigned long long value, void* = nullptr) {
    return to_sstring_sprintf(value, "%llu");
}

#endif /* SSTRING_HH_ */
<commit_msg>sstring: fix assignment operator missing return<commit_after>/*
 * Copyright 2014 Cloudius Systems
 */

#ifndef SSTRING_HH_
#define SSTRING_HH_

#include <stdint.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <stdexcept>
#include <initializer_list>
#include <iostream>
#include <functional>
#include <cstdio>

template <typename char_type, typename size_type, size_type max_size>
class basic_sstring {
    union contents {
        struct external_type {
            char* str;
            size_type size;
            int8_t pad;
        } external;
        struct internal_type {
            char str[max_size];
            int8_t size;
        } internal;
        static_assert(sizeof(external_type) <= sizeof(internal_type), "max_size too small");
        static_assert(max_size <= 127, "max_size too large");
    } u;
    bool is_internal() const noexcept {
        return u.internal.size >= 0;
    }
    bool is_external() const noexcept {
        return !is_internal();
    }
    const char* str() const {
        return is_internal() ? u.internal.str : u.external.str;
    }
    char* str() {
        return is_internal() ? u.internal.str : u.external.str;
    }
    struct initialized_later {};
public:
    basic_sstring() noexcept {
        u.internal.size = 0;
        u.internal.str[0] = '\0';
    }
    basic_sstring(const basic_sstring& x) {
        if (x.is_internal()) {
            u.internal = x.u.internal;
        } else {
            u.internal.size = -1;
            u.external.str = new char[x.u.external.size + 1];
            std::copy(x.u.external.str, x.u.external.str + x.u.external.size + 1, u.external.str);
            u.external.size = x.u.external.size;
        }
    }
    basic_sstring(basic_sstring&& x) noexcept {
        u = x.u;
        x.u.internal.size = 0;
        x.u.internal.str[0] = '\0';
    }
    basic_sstring(initialized_later, size_t size) {
        if (size_type(size) != size) {
            throw std::overflow_error("sstring overflow");
        }
        if (size + 1 <= sizeof(u.internal.str)) {
            u.internal.str[size] = '\0';
            u.internal.size = size;
        } else {
            u.internal.size = -1;
            u.external.str = new char[size + 1];
            u.external.size = size;
            u.external.str[size] = '\0';
        }
    }
    basic_sstring(const char_type* x, size_t size) {
        if (size_type(size) != size) {
            throw std::overflow_error("sstring overflow");
        }
        if (size + 1 <= sizeof(u.internal.str)) {
            std::copy(x, x + size, u.internal.str);
            u.internal.str[size] = '\0';
            u.internal.size = size;
        } else {
            u.internal.size = -1;
            u.external.str = new char[size + 1];
            u.external.size = size;
            std::copy(x, x + size, u.external.str);
            u.external.str[size] = '\0';
        }
    }
    basic_sstring(const char_type* x) : basic_sstring(x, std::strlen(x)) {}
    basic_sstring(std::basic_string<char_type>& x) : basic_sstring(x.c_str(), x.size()) {}
    basic_sstring(std::initializer_list<char_type> x) : basic_sstring(x.begin(), x.end() - x.begin()) {}
    basic_sstring(const char_type* b, const char_type* e) : basic_sstring(b, e - b) {}
    ~basic_sstring() noexcept {
        if (is_external()) {
            delete[] u.external.str;
        }
    }
    basic_sstring& operator=(const basic_sstring& x) {
        basic_sstring tmp(x);
        swap(tmp);
        return *this;
    }
    basic_sstring& operator=(basic_sstring&& x) noexcept {
        if (this != &x) {
            swap(x);
            x.reset();
        }
        return *this;
    }
    operator std::string() const {
        return str();
    }
    size_t size() const noexcept {
        return is_internal() ? u.internal.size : u.external.size;
    }
    bool empty() const noexcept {
        return u.internal.size == 0;
    }
    void reset() noexcept {
        if (is_external()) {
            delete[] u.external.str;
        }
        u.internal.size = 0;
        u.internal.str[0] = '\0';
    }
    void swap(basic_sstring& x) noexcept {
        contents tmp;
        tmp = x.u;
        x.u = u;
        u = tmp;
    }
    const char* c_str() const {
        return str();
    }
    const char_type* begin() const { return str(); }
    const char_type* end() const { return str() + size(); }
    char_type* begin() { return str(); }
    char_type* end() { return str() + size(); }
    bool operator==(const basic_sstring& x) const {
        return size() == x.size() && std::equal(begin(), end(), x.begin());
    }
    bool operator!=(const basic_sstring& x) const {
        return !operator==(x);
    }
    basic_sstring operator+(const basic_sstring& x) const {
        basic_sstring ret(initialized_later(), size() + x.size());
        std::copy(begin(), end(), ret.begin());
        std::copy(x.begin(), x.end(), ret.begin() + size());
        return ret;
    }
    basic_sstring& operator+=(const basic_sstring& x) {
        return *this = *this + x;
    }
};

template <typename char_type, typename size_type, size_type max_size>
inline
void swap(basic_sstring<char_type, size_type, max_size>& x,
          basic_sstring<char_type, size_type, max_size>& y) noexcept
{
    return x.swap(y);
}

template <typename char_type, typename size_type, size_type max_size, typename char_traits>
inline
std::basic_ostream<char_type, char_traits>&
operator<<(std::basic_ostream<char_type, char_traits>& os,
        const basic_sstring<char_type, size_type, max_size>& s) {
    return os.write(s.begin(), s.size());
}

namespace std {

template <typename char_type, typename size_type, size_type max_size>
struct hash<basic_sstring<char_type, size_type, max_size>> {
    size_t operator()(const basic_sstring<char_type, size_type, max_size>& s) const {
        size_t ret = 0;
        for (auto c : s) {
            ret = (ret << 6) | (ret >> (sizeof(ret) * 8 - 6));
            ret ^= c;
        }
        return ret;
    }
};

}

using sstring = basic_sstring<char, uint32_t, 15>;

template <typename T, typename String = sstring, typename for_enable_if = void*>
String to_sstring(T value, for_enable_if);

template <typename T>
inline
sstring to_sstring_sprintf(T value, const char* fmt) {
    char tmp[sizeof(value) / 3 + 3];
    auto len = std::sprintf(tmp, fmt, value);
    return sstring(tmp, len);
}

template <typename string_type = sstring>
inline
string_type to_sstring(int value, void* = nullptr) {
    return to_sstring_sprintf(value, "%d");
}

template <typename string_type = sstring>
inline
string_type to_sstring(unsigned value, void* = nullptr) {
    return to_sstring_sprintf(value, "%u");
}

template <typename string_type = sstring>
inline
string_type to_sstring(long value, void* = nullptr) {
    return to_sstring_sprintf(value, "%ld");
}

template <typename string_type = sstring>
inline
string_type to_sstring(unsigned long value, void* = nullptr) {
    return to_sstring_sprintf(value, "%lu");
}

template <typename string_type = sstring>
inline
string_type to_sstring(long long value, void* = nullptr) {
    return to_sstring_sprintf(value, "%lld");
}

template <typename string_type = sstring>
inline
string_type to_sstring(unsigned long long value, void* = nullptr) {
    return to_sstring_sprintf(value, "%llu");
}

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


<commit_before>/**
 * Copyright (c) 2011 Daniel Wiberg
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "Interpreter.hpp"
#include "InterpreterPrivate.hpp"

#include <cassert>
#include <iostream>
#include <sstream>

namespace script
{
  pointer scriptCallback(scheme * sc, pointer arguments)
  {
    int functionId = ivalue(pair_car(arguments));
    fprintf(stderr, "Callback '%d' called\n", functionId);

    std::vector<BasicFunction *> * functions = static_cast<std::vector<BasicFunction *> *>(sc->ext_data);
    return (*functions)[functionId]->call(sc, pair_cdr(arguments));
  }

  Interpreter::Interpreter()
    : m_private(new InterpreterPrivate())
  {
    m_private->eval = scheme_init_new();
    m_private->bindOutputPort();

    scheme_set_external_data(m_private->eval, static_cast<void *>(&m_private->functions));
  }

  Interpreter::Interpreter(Interpreter const& copy)
    : m_private(new InterpreterPrivate())
  {
    assert(0 && "Not allowed to create copies of an Interpreter");
  }

  Interpreter::~Interpreter()
  {
    scheme_deinit(m_private->eval);
    m_private->eval = 0;

    // Delete all the wrappers
    for (std::vector<BasicFunction *>::iterator it = m_private->functions.begin(), end = m_private->functions.end(); it != end; ++it)
      delete *it;

    m_private->functions.clear();
  }

  bool Interpreter::isValid() const
  {
    return (m_private->eval != 0) && !m_private->hasError();
  }

  bool Interpreter::hasError() const
  {
    return m_private->hasError();
  }

  std::string Interpreter::getLastErrorMessage() const
  {
    return m_private->getLastErrorMessage();
  }

  std::string Interpreter::getStandardOut()
  {
    return m_private->getStdOut();
  }

  void Interpreter::registerFunction(std::string const& name, BasicFunction * function)
  {
    assert(m_private->eval);

    // Store the wrapper so we can delete it later on.
    m_private->functions.push_back(function);

    std::stringstream ss;
    ss << "(define (" << name << " . args) (apply *" << name << "-internal* (cons " << m_private->functions.size() - 1 << " args)))";
    loadString(ss.str());
//    m_private->eval->vptr->load_string(m_private->eval, ss.str().c_str());

    // Bind the function to scheme
    scheme_define(m_private->eval, m_private->eval->global_env, mk_symbol(m_private->eval, ("*" + name + "-internal*").c_str()), mk_foreign_func(m_private->eval, scriptCallback));
  }

  void Interpreter::loadString(std::string const& code)
  {
    assert(m_private->eval);

    fprintf(stderr, "Running code: %s\n", code.c_str());

    m_private->bindOutputPort();
    m_private->eval->vptr->load_string(m_private->eval, code.c_str());

    if (m_private->checkForErrors())
      fprintf(stderr, "%s\n", m_private->getLastErrorMessage().c_str());
  }

}

<commit_msg>Some code refactoring.<commit_after>/**
 * Copyright (c) 2011 Daniel Wiberg
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "Interpreter.hpp"
#include "InterpreterPrivate.hpp"

#include <cassert>
#include <iostream>
#include <sstream>

namespace script
{
  pointer scriptCallback(scheme * sc, pointer arguments)
  {
    int functionId = ivalue(pair_car(arguments));

    std::vector<BasicFunction *> * functions = static_cast<std::vector<BasicFunction *> *>(sc->ext_data);
    return (*functions)[functionId]->call(sc, pair_cdr(arguments));
  }

  Interpreter::Interpreter()
    : m_private(new InterpreterPrivate())
  {
    m_private->eval = scheme_init_new();
    m_private->bindOutputPort();

    scheme_set_external_data(m_private->eval, static_cast<void *>(&m_private->functions));
  }

  Interpreter::Interpreter(Interpreter const& copy)
    : m_private(new InterpreterPrivate())
  {
    assert(0 && "Not allowed to create copies of an Interpreter");
  }

  Interpreter::~Interpreter()
  {
    scheme_deinit(m_private->eval);
    m_private->eval = 0;

    // Delete all the wrappers
    for (std::vector<BasicFunction *>::iterator it = m_private->functions.begin(), end = m_private->functions.end(); it != end; ++it)
      delete *it;

    m_private->functions.clear();
  }

  bool Interpreter::isValid() const
  {
    return (m_private->eval != 0) && !m_private->hasError();
  }

  bool Interpreter::hasError() const
  {
    return m_private->hasError();
  }

  std::string Interpreter::getLastErrorMessage() const
  {
    return m_private->getLastErrorMessage();
  }

  std::string Interpreter::getStandardOut()
  {
    return m_private->getStdOut();
  }

  void Interpreter::registerFunction(std::string const& name, BasicFunction * function)
  {
    assert(m_private->eval);

    // Store the wrapper so we can delete it later on.
    m_private->functions.push_back(function);

    std::stringstream ss;
    ss << "(define (" << name << " . args) (apply *" << name << "-internal* (cons " << m_private->functions.size() - 1 << " args)))";
    m_private->eval->vptr->load_string(m_private->eval, ss.str().c_str());

    // Bind the function to scheme
    scheme_define(m_private->eval,
                  m_private->eval->global_env,
                  mk_symbol(m_private->eval, ("*" + name + "-internal*").c_str()),
                  mk_foreign_func(m_private->eval, scriptCallback));
  }

  void Interpreter::loadString(std::string const& code)
  {
    assert(m_private->eval);

    m_private->bindOutputPort();
    m_private->eval->vptr->load_string(m_private->eval, code.c_str());
    m_private->checkForErrors();
  }

}

<|endoftext|>


<commit_before>class fenwick{
public:
    int n;  // array size
    vector<int> t;

    int sum(int r) {
        int ans = 0;
        for (; r >= 0; r = (r & (r + 1)) - 1) ans += t[r];
        return ans;
    }

    int sum(int l, int r) {
        return sum(r) - sum(l - 1);
    }

    void inc(int x, int y) {
        for (; x < n; x |= x + 1) t[x] += y;
    }

    fenwick(int n):n(n),t(){
        t.assign(n, 0);
    }
};
<commit_msg>fenwick update<commit_after>template<typename T>
struct fenwick{
    int n;
    vector<T> t;

    T sum(int r) {
        if (r < 0) return 0;
        r = min(r, n - 1);
        T ans = 0;
        for (; r >= 0; r = (r & (r + 1)) - 1) ans += t[r];
        return ans;
    }

    T sum(int l, int r) {
        return sum(r) - sum(l - 1);
    }

    void inc(int x, T y) {
        for (; x < n; x |= x + 1) t[x] += y;
    }

    fenwick(int n): n(n), t(n, 0) {}
};
<|endoftext|>


<commit_before>/****************************************************************************
** libmatroska : parse Matroska files, see http://www.matroska.org/
**
** <file/class description>
**
** Copyright (C) 2002-2010 Steve Lhomme.  All rights reserved.
**
** This file is part of libmatroska.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
**
** See http://www.matroska.org/license/lgpl/ for LGPL licensing information.**
** Contact license@matroska.org if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/

/*!
	\file
	\version \$Id: KaxContexts.cpp 640 2004-07-09 21:05:36Z mosu $
	\author Steve Lhomme     <robux4 @ users.sf.net>
*/
#include "ebml/EbmlContexts.h"
#include "ebml/EbmlHead.h"
#include "matroska/KaxContexts.h"
#include "matroska/KaxBlock.h"
#include "matroska/KaxCluster.h"
#include "matroska/KaxSegment.h"
#include "matroska/KaxTracks.h"

using namespace LIBEBML_NAMESPACE;

START_LIBMATROSKA_NAMESPACE

DEFINE_START_SEMANTIC(KaxMatroska_Context)
DEFINE_SEMANTIC_ITEM(true, true, EbmlHead)
DEFINE_SEMANTIC_ITEM(false, false, KaxSegment)
DEFINE_END_SEMANTIC(KaxMatroska_Context)

DEFINE_SEMANTIC_CONTEXT(KaxSegment)
DEFINE_SEMANTIC_CONTEXT(KaxAttached)
DEFINE_SEMANTIC_CONTEXT(KaxAttachments)
DEFINE_SEMANTIC_CONTEXT(KaxBlockGroup)
DEFINE_SEMANTIC_CONTEXT(KaxCluster)
DEFINE_SEMANTIC_CONTEXT(KaxTrackEntry)

// for the moment
const EbmlSemanticContext & GetKaxGlobal_Context()
{
	return GetEbmlGlobal_Context();
}

END_LIBMATROSKA_NAMESPACE
<commit_msg>libmatroska: properly use the macros for Context_KaxMatroska<commit_after>/****************************************************************************
** libmatroska : parse Matroska files, see http://www.matroska.org/
**
** <file/class description>
**
** Copyright (C) 2002-2010 Steve Lhomme.  All rights reserved.
**
** This file is part of libmatroska.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
**
** See http://www.matroska.org/license/lgpl/ for LGPL licensing information.**
** Contact license@matroska.org if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/

/*!
	\file
	\version \$Id: KaxContexts.cpp 640 2004-07-09 21:05:36Z mosu $
	\author Steve Lhomme     <robux4 @ users.sf.net>
*/
#include "ebml/EbmlContexts.h"
#include "ebml/EbmlHead.h"
#include "matroska/KaxContexts.h"
#include "matroska/KaxBlock.h"
#include "matroska/KaxCluster.h"
#include "matroska/KaxSegment.h"
#include "matroska/KaxTracks.h"

using namespace LIBEBML_NAMESPACE;

START_LIBMATROSKA_NAMESPACE

DEFINE_START_SEMANTIC(KaxMatroska)
DEFINE_SEMANTIC_ITEM(true, true, EbmlHead)
DEFINE_SEMANTIC_ITEM(false, false, KaxSegment)
DEFINE_END_SEMANTIC(KaxMatroska)

DEFINE_MKX_CONTEXT(KaxMatroska)

DEFINE_SEMANTIC_CONTEXT(KaxSegment)
DEFINE_SEMANTIC_CONTEXT(KaxAttached)
DEFINE_SEMANTIC_CONTEXT(KaxAttachments)
DEFINE_SEMANTIC_CONTEXT(KaxBlockGroup)
DEFINE_SEMANTIC_CONTEXT(KaxCluster)
DEFINE_SEMANTIC_CONTEXT(KaxTrackEntry)

// for the moment
const EbmlSemanticContext & GetKaxGlobal_Context()
{
	return GetEbmlGlobal_Context();
}

END_LIBMATROSKA_NAMESPACE
<|endoftext|>


<commit_before>/******************************************************************************\
 *           ___        __                                                    *
 *          /\_ \    __/\ \                                                   *
 *          \//\ \  /\_\ \ \____    ___   _____   _____      __               *
 *            \ \ \ \/\ \ \ '__`\  /'___\/\ '__`\/\ '__`\  /'__`\             *
 *             \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_           *
 *             /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\          *
 *             \/____/ \/_/\/___/  \/____/ \ \ \/  \ \ \/  \/__/\/_/          *
 *                                          \ \_\   \ \_\                     *
 *                                           \/_/    \/_/                     *
 *                                                                            *
 * Copyright (C) 2011, 2012                                                   *
 * Dominik Charousset <dominik.charousset@haw-hamburg.de>                     *
 *                                                                            *
 * This file is part of libcppa.                                              *
 * libcppa 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.                                     *
 *                                                                            *
 * libcppa 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 libcppa. If not, see <http://www.gnu.org/licenses/>.            *
\******************************************************************************/

#ifndef CPPA_OPTION_HPP
#define CPPA_OPTION_HPP

#include <new>
#include <utility>
#include "cppa/config.hpp"

namespace cppa {

/**
 * @brief Represents an optional value of @p T.
 */
template<typename T>
class option {

 public:

    /**
     * @brief Typdef for @p T.
     */
    typedef T type;

    /**
     * @brief Default constructor.
     * @post <tt>valid() == false</tt>
     */
    option() : m_valid(false) { }

    /**
     * @brief Creates an @p option from @p value.
     * @post <tt>valid() == true</tt>
     */
    option(T value) : m_valid(false) { cr(std::move(value)); }

    option(const option& other) : m_valid(false) {
        if (other.m_valid) cr(other.m_value);
    }

    option(option&& other) : m_valid(false) {
        if (other.m_valid) cr(std::move(other.m_value));
    }

    ~option() { destroy(); }

    option& operator=(const option& other) {
        if (m_valid) {
            if (other.m_valid) m_value = other.m_value;
            else destroy();
        }
        else if (other.m_valid) {
            cr(other.m_value);
        }
        return *this;
    }

    option& operator=(option&& other) {
        if (m_valid) {
            if (other.m_valid) m_value = std::move(other.m_value);
            else destroy();
        }
        else if (other.m_valid) {
            cr(std::move(other.m_value));
        }
        return *this;
    }

    option& operator=(const T& value) {
        if (m_valid) m_value = value;
        else cr(value);
        return *this;
    }

    option& operator=(T& value) {
        if (m_valid) m_value = std::move(value);
        else cr(std::move(value));
        return *this;
    }

    /**
     * @brief Returns @p true if this @p option has a valid value;
     *        otherwise @p false.
     */
    inline bool valid() const { return m_valid; }

    inline bool empty() const { return !m_valid; }

    /**
     * @copydoc valid()
     */
    inline explicit operator bool() const { return valid(); }

    /**
     * @brief Returns <tt>!valid()</tt>
     */
    inline bool operator!() const { return empty(); }

    /**
     * @brief Returns the value.
     */
    inline T& operator*() {
        CPPA_REQUIRE(valid());
        return m_value;
    }

    /**
     * @brief Returns the value.
     */
    inline const T& operator*() const {
        CPPA_REQUIRE(valid());
        return m_value;
    }

    /**
     * @brief Returns the value.
     */
    inline T& get() {
        CPPA_REQUIRE(valid());
        return m_value;
    }

    /**
     * @brief Returns the value.
     */
    inline const T& get() const {
        CPPA_REQUIRE(valid());
        return m_value;
    }

    /**
     * @brief Returns the value. The value is set to @p default_value
     *        if <tt>valid() == false</tt>.
     * @post <tt>valid() == true</tt>
     */
    inline const T& get_or_else(const T& default_value) const {
        if (valid()) return get();
        return default_value;
    }

 private:

    bool m_valid;
    union { T m_value; };

    void destroy() {
        if (m_valid) {
            m_value.~T();
            m_valid = false;
        }
    }

    template<typename V>
    void cr(V&& value) {
        CPPA_REQUIRE(!valid());
        m_valid = true;
        new (&m_value) T (std::forward<V>(value));
    }

};

/** @relates option */
template<typename T, typename U>
bool operator==(const option<T>& lhs, const option<U>& rhs) {
    if ((lhs) && (rhs)) return *lhs == *rhs;
    return false;
}

/** @relates option */
template<typename T, typename U>
bool operator==(const option<T>& lhs, const U& rhs) {
    if (lhs) return *lhs == rhs;
    return false;
}

/** @relates option */
template<typename T, typename U>
bool operator==(const T& lhs, const option<U>& rhs) {
    return rhs == lhs;
}

/** @relates option */
template<typename T, typename U>
bool operator!=(const option<T>& lhs, const option<U>& rhs) {
    return !(lhs == rhs);
}

/** @relates option */
template<typename T, typename U>
bool operator!=(const option<T>& lhs, const U& rhs) {
    return !(lhs == rhs);
}

/** @relates option */
template<typename T, typename U>
bool operator!=(const T& lhs, const option<U>& rhs) {
    return !(lhs == rhs);
}

} // namespace cppa

#endif // CPPA_OPTION_HPP
<commit_msg>added specialization for `option<T&>`<commit_after>/******************************************************************************\
 *           ___        __                                                    *
 *          /\_ \    __/\ \                                                   *
 *          \//\ \  /\_\ \ \____    ___   _____   _____      __               *
 *            \ \ \ \/\ \ \ '__`\  /'___\/\ '__`\/\ '__`\  /'__`\             *
 *             \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_           *
 *             /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\          *
 *             \/____/ \/_/\/___/  \/____/ \ \ \/  \ \ \/  \/__/\/_/          *
 *                                          \ \_\   \ \_\                     *
 *                                           \/_/    \/_/                     *
 *                                                                            *
 * Copyright (C) 2011, 2012                                                   *
 * Dominik Charousset <dominik.charousset@haw-hamburg.de>                     *
 *                                                                            *
 * This file is part of libcppa.                                              *
 * libcppa 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.                                     *
 *                                                                            *
 * libcppa 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 libcppa. If not, see <http://www.gnu.org/licenses/>.            *
\******************************************************************************/

#ifndef CPPA_OPTION_HPP
#define CPPA_OPTION_HPP

#include <new>
#include <utility>
#include "cppa/config.hpp"

namespace cppa {

/**
 * @brief Represents an optional value of @p T.
 */
template<typename T>
class option {

 public:

    /**
     * @brief Typdef for @p T.
     */
    typedef T type;

    /**
     * @brief Default constructor.
     * @post <tt>valid() == false</tt>
     */
    option() : m_valid(false) { }

    /**
     * @brief Creates an @p option from @p value.
     * @post <tt>valid() == true</tt>
     */
    option(T value) : m_valid(false) { cr(std::move(value)); }

    option(const option& other) : m_valid(false) {
        if (other.m_valid) cr(other.m_value);
    }

    option(option&& other) : m_valid(false) {
        if (other.m_valid) cr(std::move(other.m_value));
    }

    ~option() { destroy(); }

    option& operator=(const option& other) {
        if (m_valid) {
            if (other.m_valid) m_value = other.m_value;
            else destroy();
        }
        else if (other.m_valid) {
            cr(other.m_value);
        }
        return *this;
    }

    option& operator=(option&& other) {
        if (m_valid) {
            if (other.m_valid) m_value = std::move(other.m_value);
            else destroy();
        }
        else if (other.m_valid) {
            cr(std::move(other.m_value));
        }
        return *this;
    }

    /**
     * @brief Returns @p true if this @p option has a valid value;
     *        otherwise @p false.
     */
    inline bool valid() const { return m_valid; }

    /**
     * @brief Returns <tt>!valid()</tt>.
     */
    inline bool empty() const { return !m_valid; }

    /**
     * @copydoc valid()
     */
    inline explicit operator bool() const { return valid(); }

    /**
     * @brief Returns <tt>!valid()</tt>.
     */
    inline bool operator!() const { return empty(); }

    /**
     * @brief Returns the value.
     */
    inline T& operator*() {
        CPPA_REQUIRE(valid());
        return m_value;
    }

    /**
     * @brief Returns the value.
     */
    inline const T& operator*() const {
        CPPA_REQUIRE(valid());
        return m_value;
    }

    /**
     * @brief Returns the value.
     */
    inline T& get() {
        CPPA_REQUIRE(valid());
        return m_value;
    }

    /**
     * @brief Returns the value.
     */
    inline const T& get() const {
        CPPA_REQUIRE(valid());
        return m_value;
    }

    /**
     * @brief Returns the value. The value is set to @p default_value
     *        if <tt>valid() == false</tt>.
     * @post <tt>valid() == true</tt>
     */
    inline const T& get_or_else(const T& default_value) const {
        if (valid()) return get();
        return default_value;
    }

 private:

    bool m_valid;
    union { T m_value; };

    void destroy() {
        if (m_valid) {
            m_value.~T();
            m_valid = false;
        }
    }

    template<typename V>
    void cr(V&& value) {
        CPPA_REQUIRE(!valid());
        m_valid = true;
        new (&m_value) T (std::forward<V>(value));
    }

};

template<typename T>
class option<T&> {

 public:

    typedef T type;

    option() : m_value(nullptr) { }

    option(T& value) : m_value(&value) { }

    option(const option& other) = default;

    option& operator=(const option& other) = default;

    inline bool valid() const { return m_value != nullptr; }

    inline bool empty() const { return !valid(); }

    inline explicit operator bool() const { return valid(); }

    inline bool operator!() const { return empty(); }

    inline T& operator*() {
        CPPA_REQUIRE(valid());
        return *m_value;
    }

    inline const T& operator*() const {
        CPPA_REQUIRE(valid());
        return *m_value;
    }

    inline T& get() {
        CPPA_REQUIRE(valid());
        return *m_value;
    }

    inline const T& get() const {
        CPPA_REQUIRE(valid());
        return *m_value;
    }

    inline const T& get_or_else(const T& default_value) const {
        if (valid()) return get();
        return default_value;
    }

 private:

    T* m_value;

};

/** @relates option */
template<typename T>
struct is_option { static constexpr bool value = false; };

template<typename T>
struct is_option<option<T>> { static constexpr bool value = true; };

/** @relates option */
template<typename T, typename U>
bool operator==(const option<T>& lhs, const option<U>& rhs) {
    if ((lhs) && (rhs)) return *lhs == *rhs;
    return false;
}

/** @relates option */
template<typename T, typename U>
bool operator==(const option<T>& lhs, const U& rhs) {
    if (lhs) return *lhs == rhs;
    return false;
}

/** @relates option */
template<typename T, typename U>
bool operator==(const T& lhs, const option<U>& rhs) {
    return rhs == lhs;
}

/** @relates option */
template<typename T, typename U>
bool operator!=(const option<T>& lhs, const option<U>& rhs) {
    return !(lhs == rhs);
}

/** @relates option */
template<typename T, typename U>
bool operator!=(const option<T>& lhs, const U& rhs) {
    return !(lhs == rhs);
}

/** @relates option */
template<typename T, typename U>
bool operator!=(const T& lhs, const option<U>& rhs) {
    return !(lhs == rhs);
}

} // namespace cppa

#endif // CPPA_OPTION_HPP
<|endoftext|>


<commit_before>#include <gobject-introspection-1.0/girepository.h>
#include <node.h>
#include <nan.h>

#include "boxed.h"
#include "debug.h"
#include "function.h"
#include "gi.h"
#include "gobject.h"
#include "loop.h"
#include "util.h"
#include "value.h"

using namespace v8;
using Nan::New;
using Nan::Set;

using GNodeJS::BaseInfo;

static void DefineFunction(Isolate *isolate, Local<Object> module_obj, GIBaseInfo *info) {
    const char *function_name = g_base_info_get_name ((GIBaseInfo *) info);
    Local<Function> fn = GNodeJS::MakeFunction (info);

    module_obj->Set(String::NewFromUtf8(isolate, function_name), fn);
}

static void DefineFunction(Isolate *isolate, Local<Object> module_obj, GIBaseInfo *info, const char *base_name) {
    Local<Function> fn = GNodeJS::MakeFunction (info);

    char *function_name = g_strdup_printf ("%s_%s", base_name, g_base_info_get_name(info));
    Nan::Set(module_obj, UTF8(function_name), fn);
    g_free (function_name);
}

static void DefineObjectFunctions(Isolate *isolate, Local<Object> module_obj, GIBaseInfo *info) {
    const char *object_name = g_base_info_get_name ((GIBaseInfo *) info);

    int n_methods = g_object_info_get_n_methods (info);
    for (int i = 0; i < n_methods; i++) {
        GIFunctionInfo *meth_info = g_object_info_get_method (info, i);
        DefineFunction (isolate, module_obj, meth_info, object_name);
        g_base_info_unref ((GIBaseInfo *) meth_info);
    }
}

static void DefineBoxedFunctions(Isolate *isolate, Local<Object> module_obj, GIBaseInfo *info) {
    const char *object_name = g_base_info_get_name ((GIBaseInfo *) info);

    int n_methods = g_struct_info_get_n_methods (info);
    for (int i = 0; i < n_methods; i++) {
        GIFunctionInfo *meth_info = g_struct_info_get_method (info, i);
        DefineFunction (isolate, module_obj, meth_info, object_name);
        g_base_info_unref ((GIBaseInfo *) meth_info);
    }
}

static void DefineBootstrapInfo(Isolate *isolate, Local<Object> module_obj, GIBaseInfo *info) {
    GIInfoType type = g_base_info_get_type (info);

    switch (type) {
    case GI_INFO_TYPE_FUNCTION:
        DefineFunction (isolate, module_obj, info);
        break;
    case GI_INFO_TYPE_OBJECT:
        DefineObjectFunctions (isolate, module_obj, info);
        break;
    case GI_INFO_TYPE_BOXED:
    case GI_INFO_TYPE_STRUCT:
        DefineBoxedFunctions (isolate, module_obj, info);
        break;
    default:
        break;
    }
}

NAN_METHOD(Bootstrap) {
    Isolate *isolate = info.GetIsolate();

    GIRepository *repo = g_irepository_get_default ();
    GError *error = NULL;

    const char *ns = "GIRepository";
    g_irepository_require (repo, ns, NULL, (GIRepositoryLoadFlags) 0, &error);

    if (error) {
        Nan::ThrowError( error->message );
        return;
    }

    Local<Object> module_obj = Object::New (isolate);

    int n = g_irepository_get_n_infos (repo, ns);
    for (int i = 0; i < n; i++) {
        BaseInfo baseInfo(g_irepository_get_info(repo, ns, i));
        DefineBootstrapInfo(isolate, module_obj, baseInfo.info());
    }

    info.GetReturnValue().Set(module_obj);
}

NAN_METHOD(GetConstantValue) {
    GIBaseInfo *gi_info = (GIBaseInfo *) GNodeJS::BoxedFromWrapper (info[0]);
    GITypeInfo *type = g_constant_info_get_type ((GIConstantInfo *) gi_info);

    if (type == NULL) {
        info.GetReturnValue().SetNull();
        return;
    }

    GIArgument gi_arg;
    g_constant_info_get_value((GIConstantInfo *) gi_info, &gi_arg);
    info.GetReturnValue().Set(GNodeJS::GIArgumentToV8 (type, &gi_arg));
}

NAN_METHOD(MakeFunction) {
    //Isolate *isolate = info.GetIsolate ();
    GIBaseInfo *gi_info = (GIBaseInfo *) GNodeJS::BoxedFromWrapper(info[0]);
    Local<Function> fn = GNodeJS::MakeFunction(gi_info);
    info.GetReturnValue().Set(fn);
}

NAN_METHOD(MakeObjectClass) {
    //Isolate *isolate = info.GetIsolate ();
    Local<Object> obj = info[0].As<Object>();

    if (obj->InternalFieldCount() == 0) {
        Nan::ThrowTypeError("Object is not a GIBaseInfo wrapper");
        return;
    }

    GIBaseInfo *gi_info = static_cast<GIBaseInfo*>(GNodeJS::BoxedFromWrapper (obj));

    info.GetReturnValue().Set(GNodeJS::MakeClass(gi_info));
}

NAN_METHOD(MakeBoxedClass) {
    //Isolate *isolate = info.GetIsolate ();
    GIBaseInfo *gi_info = (GIBaseInfo *) GNodeJS::BoxedFromWrapper (info[0]);

    info.GetReturnValue().Set(GNodeJS::MakeBoxed(gi_info));
}

NAN_METHOD(ObjectPropertyGetter) {
    Isolate *isolate = info.GetIsolate ();

    GObject *gobject = GNodeJS::GObjectFromWrapper (info[0]);

    g_assert(gobject != NULL);

    String::Utf8Value prop_name_v (info[1]->ToString ());
    const char *prop_name = *prop_name_v;

    GParamSpec *pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (gobject), prop_name);

    if (pspec == NULL) {
        WARN("ObjectPropertyGetter: no property %s", prop_name);
        info.GetReturnValue().SetUndefined();
        return;
    }

    GValue value = {};
    g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
    g_object_get_property (gobject, prop_name, &value);

    info.GetReturnValue().Set(
        GNodeJS::GValueToV8(isolate, &value));
}

NAN_METHOD(ObjectPropertySetter) {
    GObject *gobject = GNodeJS::GObjectFromWrapper(info[0]);

    g_assert(gobject != NULL);

    String::Utf8Value prop_name_v (info[1]->ToString ());
    const char *prop_name = *prop_name_v;

    GParamSpec *pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (gobject), prop_name);

    if (pspec == NULL) {
        WARN("ObjectPropertySetter: no property %s", prop_name);
        return;
    }

    GValue value = {};
    g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
    GNodeJS::V8ToGValue (&value, info[2]);

    g_object_set_property (gobject, prop_name, &value);
}

NAN_METHOD(StructFieldSetter) {
    // const Nan::FunctionCallbackInfo<v8::Value>& info

    Local<Object> boxedWrapper = info[0].As<Object>();
    Local<Object> fieldInfo    = info[1].As<Object>();
    Local<Value>  value        = info[2];

    void        *boxed = GNodeJS::BoxedFromWrapper(boxedWrapper);
    GIFieldInfo *field = (GIFieldInfo *) GNodeJS::BoxedFromWrapper(fieldInfo);
    GITypeInfo  *field_type = g_field_info_get_type(field);

    g_assert(boxed);
    g_assert(field);
    g_assert(field_type);

    GIArgument arg;

    if (GNodeJS::V8ToGIArgument(field_type, &arg, value, true)) {

        if (g_field_info_set_field(field, boxed, &arg) == FALSE)
            DEBUG("FieldSetter: couldnt set field %s", g_base_info_get_name(field));

        GNodeJS::FreeGIArgument(field_type, &arg);

    } else {
        DEBUG("FieldSetter: couldnt convert value for field %s", g_base_info_get_name(field));
    }

    g_base_info_unref (field_type);
}

NAN_METHOD(StructFieldGetter) {
    // const Nan::FunctionCallbackInfo<v8::Value>& info
    Local<Object> boxedWrapper = info[0].As<Object>();
    Local<Object> fieldInfo    = info[1].As<Object>();

    if (boxedWrapper->InternalFieldCount() == 0) {
        Nan::ThrowReferenceError("StructFieldGetter: argument 1 is not a boxed.");
        return;
    }

    if (fieldInfo->InternalFieldCount() == 0) {
        g_warning("StructFieldGetter: No internal fields.");
        return;
    }

    void        *boxed = GNodeJS::BoxedFromWrapper(boxedWrapper);
    GIFieldInfo *field = (GIFieldInfo *) GNodeJS::BoxedFromWrapper(fieldInfo);

    if (boxed == NULL) {
        Nan::ThrowError("StructFieldGetter: accessing NULL boxed pointer");
        return;
    }

    if (field == NULL) {
        Nan::ThrowError("FieldGetter: NULL field_info pointer");
        return;
    }

    GIArgument value;
    if (g_field_info_get_field(field, boxed, &value)) {
        GITypeInfo  *field_type = g_field_info_get_type(field);

        RETURN(GNodeJS::GIArgumentToV8(field_type, &value));

        GNodeJS::FreeGIArgument(field_type, &value);
        g_base_info_unref (field_type);
    } else {
        DEBUG("StructFieldGetter: couldnt get field %s", g_base_info_get_name(field));
        //DEBUG("StructFieldGetter: property name: %s", *Nan::Utf8String(property) );
    }
}

NAN_METHOD(StartLoop) {
    GNodeJS::StartLoop ();
}

NAN_METHOD(WrapperFromBoxed) {
    //Isolate *isolate = info.GetIsolate ();
    GIBaseInfo *gi_info = (GIBaseInfo *) GNodeJS::BoxedFromWrapper (info[0]);
    void *boxed = External::Cast(*info[1])->Value();
    info.GetReturnValue().Set(GNodeJS::WrapperFromBoxed(gi_info, boxed));
}

NAN_METHOD(PointerToString) {
    if (info[0]->ToObject()->InternalFieldCount() == 0) {
        Nan::ThrowReferenceError("Object doesnt have any internal field.");
        return;
    }
    void *boxed = GNodeJS::BoxedFromWrapper(info[0]);
    char *address = g_strdup_printf("%#zx", (unsigned long)boxed);
    info.GetReturnValue().Set(UTF8(address));
    g_free(address);
}

NAN_METHOD(InternalFieldCount) {
    Local<Object> obj = info[0].As<Object>();
    RETURN(obj->InternalFieldCount());
}

void InitModule(Local<Object> exports, Local<Value> module, void *priv) {
    NAN_EXPORT(exports, Bootstrap);
    NAN_EXPORT(exports, GetConstantValue);
    NAN_EXPORT(exports, MakeBoxedClass);
    NAN_EXPORT(exports, MakeObjectClass);
    NAN_EXPORT(exports, WrapperFromBoxed);
    NAN_EXPORT(exports, MakeFunction);
    NAN_EXPORT(exports, StructFieldGetter);
    NAN_EXPORT(exports, StructFieldSetter);
    NAN_EXPORT(exports, ObjectPropertyGetter);
    NAN_EXPORT(exports, ObjectPropertySetter);
    NAN_EXPORT(exports, StartLoop);
    NAN_EXPORT(exports, PointerToString);
    NAN_EXPORT(exports, InternalFieldCount);
}

NODE_MODULE(gi, InitModule)
<commit_msg>remove Isolate references<commit_after>#include <gobject-introspection-1.0/girepository.h>
#include <node.h>
#include <nan.h>

#include "boxed.h"
#include "debug.h"
#include "function.h"
#include "gi.h"
#include "gobject.h"
#include "loop.h"
#include "util.h"
#include "value.h"

using namespace v8;
using Nan::New;
using Nan::Set;

using GNodeJS::BaseInfo;

static void DefineFunction(Isolate *isolate, Local<Object> module_obj, GIBaseInfo *info) {
    const char *function_name = g_base_info_get_name ((GIBaseInfo *) info);
    Local<Function> fn = GNodeJS::MakeFunction (info);

    module_obj->Set(String::NewFromUtf8(isolate, function_name), fn);
}

static void DefineFunction(Isolate *isolate, Local<Object> module_obj, GIBaseInfo *info, const char *base_name) {
    Local<Function> fn = GNodeJS::MakeFunction (info);

    char *function_name = g_strdup_printf ("%s_%s", base_name, g_base_info_get_name(info));
    Nan::Set(module_obj, UTF8(function_name), fn);
    g_free (function_name);
}

static void DefineObjectFunctions(Isolate *isolate, Local<Object> module_obj, GIBaseInfo *info) {
    const char *object_name = g_base_info_get_name ((GIBaseInfo *) info);

    int n_methods = g_object_info_get_n_methods (info);
    for (int i = 0; i < n_methods; i++) {
        GIFunctionInfo *meth_info = g_object_info_get_method (info, i);
        DefineFunction (isolate, module_obj, meth_info, object_name);
        g_base_info_unref ((GIBaseInfo *) meth_info);
    }
}

static void DefineBoxedFunctions(Isolate *isolate, Local<Object> module_obj, GIBaseInfo *info) {
    const char *object_name = g_base_info_get_name ((GIBaseInfo *) info);

    int n_methods = g_struct_info_get_n_methods (info);
    for (int i = 0; i < n_methods; i++) {
        GIFunctionInfo *meth_info = g_struct_info_get_method (info, i);
        DefineFunction (isolate, module_obj, meth_info, object_name);
        g_base_info_unref ((GIBaseInfo *) meth_info);
    }
}

static void DefineBootstrapInfo(Isolate *isolate, Local<Object> module_obj, GIBaseInfo *info) {
    GIInfoType type = g_base_info_get_type (info);

    switch (type) {
    case GI_INFO_TYPE_FUNCTION:
        DefineFunction (isolate, module_obj, info);
        break;
    case GI_INFO_TYPE_OBJECT:
        DefineObjectFunctions (isolate, module_obj, info);
        break;
    case GI_INFO_TYPE_BOXED:
    case GI_INFO_TYPE_STRUCT:
        DefineBoxedFunctions (isolate, module_obj, info);
        break;
    default:
        break;
    }
}

NAN_METHOD(Bootstrap) {
    Isolate *isolate = info.GetIsolate();

    GIRepository *repo = g_irepository_get_default ();
    GError *error = NULL;

    const char *ns = "GIRepository";
    g_irepository_require (repo, ns, NULL, (GIRepositoryLoadFlags) 0, &error);

    if (error) {
        Nan::ThrowError( error->message );
        return;
    }

    Local<Object> module_obj = Object::New (isolate);

    int n = g_irepository_get_n_infos (repo, ns);
    for (int i = 0; i < n; i++) {
        BaseInfo baseInfo(g_irepository_get_info(repo, ns, i));
        DefineBootstrapInfo(isolate, module_obj, baseInfo.info());
    }

    info.GetReturnValue().Set(module_obj);
}

NAN_METHOD(GetConstantValue) {
    GIBaseInfo *gi_info = (GIBaseInfo *) GNodeJS::BoxedFromWrapper (info[0]);
    GITypeInfo *type = g_constant_info_get_type ((GIConstantInfo *) gi_info);

    if (type == NULL) {
        info.GetReturnValue().SetNull();
        return;
    }

    GIArgument gi_arg;
    g_constant_info_get_value((GIConstantInfo *) gi_info, &gi_arg);
    info.GetReturnValue().Set(GNodeJS::GIArgumentToV8 (type, &gi_arg));
}

NAN_METHOD(MakeFunction) {
    //Isolate *isolate = info.GetIsolate ();
    GIBaseInfo *gi_info = (GIBaseInfo *) GNodeJS::BoxedFromWrapper(info[0]);
    Local<Function> fn = GNodeJS::MakeFunction(gi_info);
    info.GetReturnValue().Set(fn);
}

NAN_METHOD(MakeObjectClass) {
    //Isolate *isolate = info.GetIsolate ();
    Local<Object> obj = info[0].As<Object>();

    if (obj->InternalFieldCount() == 0) {
        Nan::ThrowTypeError("Object is not a GIBaseInfo wrapper");
        return;
    }

    GIBaseInfo *gi_info = static_cast<GIBaseInfo*>(GNodeJS::BoxedFromWrapper (obj));

    info.GetReturnValue().Set(GNodeJS::MakeClass(gi_info));
}

NAN_METHOD(MakeBoxedClass) {
    //Isolate *isolate = info.GetIsolate ();
    GIBaseInfo *gi_info = (GIBaseInfo *) GNodeJS::BoxedFromWrapper (info[0]);

    info.GetReturnValue().Set(GNodeJS::MakeBoxed(gi_info));
}

NAN_METHOD(ObjectPropertyGetter) {
    GObject *gobject = GNodeJS::GObjectFromWrapper (info[0]);

    g_assert(gobject != NULL);

    String::Utf8Value prop_name_v (info[1]->ToString ());
    const char *prop_name = *prop_name_v;

    GParamSpec *pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (gobject), prop_name);

    if (pspec == NULL) {
        WARN("ObjectPropertyGetter: no property %s", prop_name);
        info.GetReturnValue().SetUndefined();
        return;
    }

    GValue value = G_VALUE_INIT;
    g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
    g_object_get_property (gobject, prop_name, &value);

    RETURN(GNodeJS::GValueToV8(&value));
}

NAN_METHOD(ObjectPropertySetter) {
    GObject *gobject = GNodeJS::GObjectFromWrapper(info[0]);

    g_assert(gobject != NULL);

    String::Utf8Value prop_name_v (info[1]->ToString ());
    const char *prop_name = *prop_name_v;

    GParamSpec *pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (gobject), prop_name);

    if (pspec == NULL) {
        WARN("ObjectPropertySetter: no property %s", prop_name);
        return;
    }

    GValue value = {};
    g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
    GNodeJS::V8ToGValue (&value, info[2]);

    g_object_set_property (gobject, prop_name, &value);
}

NAN_METHOD(StructFieldSetter) {
    // const Nan::FunctionCallbackInfo<v8::Value>& info

    Local<Object> boxedWrapper = info[0].As<Object>();
    Local<Object> fieldInfo    = info[1].As<Object>();
    Local<Value>  value        = info[2];

    void        *boxed = GNodeJS::BoxedFromWrapper(boxedWrapper);
    GIFieldInfo *field = (GIFieldInfo *) GNodeJS::BoxedFromWrapper(fieldInfo);
    GITypeInfo  *field_type = g_field_info_get_type(field);

    g_assert(boxed);
    g_assert(field);
    g_assert(field_type);

    GIArgument arg;

    if (GNodeJS::V8ToGIArgument(field_type, &arg, value, true)) {

        if (g_field_info_set_field(field, boxed, &arg) == FALSE)
            DEBUG("FieldSetter: couldnt set field %s", g_base_info_get_name(field));

        GNodeJS::FreeGIArgument(field_type, &arg);

    } else {
        DEBUG("FieldSetter: couldnt convert value for field %s", g_base_info_get_name(field));
    }

    g_base_info_unref (field_type);
}

NAN_METHOD(StructFieldGetter) {
    // const Nan::FunctionCallbackInfo<v8::Value>& info
    Local<Object> boxedWrapper = info[0].As<Object>();
    Local<Object> fieldInfo    = info[1].As<Object>();

    if (boxedWrapper->InternalFieldCount() == 0) {
        Nan::ThrowReferenceError("StructFieldGetter: argument 1 is not a boxed.");
        return;
    }

    if (fieldInfo->InternalFieldCount() == 0) {
        g_warning("StructFieldGetter: No internal fields.");
        return;
    }

    void        *boxed = GNodeJS::BoxedFromWrapper(boxedWrapper);
    GIFieldInfo *field = (GIFieldInfo *) GNodeJS::BoxedFromWrapper(fieldInfo);

    if (boxed == NULL) {
        Nan::ThrowError("StructFieldGetter: accessing NULL boxed pointer");
        return;
    }

    if (field == NULL) {
        Nan::ThrowError("FieldGetter: NULL field_info pointer");
        return;
    }

    GIArgument value;
    if (g_field_info_get_field(field, boxed, &value)) {
        GITypeInfo  *field_type = g_field_info_get_type(field);

        RETURN(GNodeJS::GIArgumentToV8(field_type, &value));

        GNodeJS::FreeGIArgument(field_type, &value);
        g_base_info_unref (field_type);
    } else {
        DEBUG("StructFieldGetter: couldnt get field %s", g_base_info_get_name(field));
        //DEBUG("StructFieldGetter: property name: %s", *Nan::Utf8String(property) );
    }
}

NAN_METHOD(StartLoop) {
    GNodeJS::StartLoop ();
}

NAN_METHOD(WrapperFromBoxed) {
    //Isolate *isolate = info.GetIsolate ();
    GIBaseInfo *gi_info = (GIBaseInfo *) GNodeJS::BoxedFromWrapper (info[0]);
    void *boxed = External::Cast(*info[1])->Value();
    info.GetReturnValue().Set(GNodeJS::WrapperFromBoxed(gi_info, boxed));
}

NAN_METHOD(PointerToString) {
    if (info[0]->ToObject()->InternalFieldCount() == 0) {
        Nan::ThrowReferenceError("Object doesnt have any internal field.");
        return;
    }
    void *boxed = GNodeJS::BoxedFromWrapper(info[0]);
    char *address = g_strdup_printf("%#zx", (unsigned long)boxed);
    info.GetReturnValue().Set(UTF8(address));
    g_free(address);
}

NAN_METHOD(InternalFieldCount) {
    Local<Object> obj = info[0].As<Object>();
    RETURN(obj->InternalFieldCount());
}

void InitModule(Local<Object> exports, Local<Value> module, void *priv) {
    NAN_EXPORT(exports, Bootstrap);
    NAN_EXPORT(exports, GetConstantValue);
    NAN_EXPORT(exports, MakeBoxedClass);
    NAN_EXPORT(exports, MakeObjectClass);
    NAN_EXPORT(exports, WrapperFromBoxed);
    NAN_EXPORT(exports, MakeFunction);
    NAN_EXPORT(exports, StructFieldGetter);
    NAN_EXPORT(exports, StructFieldSetter);
    NAN_EXPORT(exports, ObjectPropertyGetter);
    NAN_EXPORT(exports, ObjectPropertySetter);
    NAN_EXPORT(exports, StartLoop);
    NAN_EXPORT(exports, PointerToString);
    NAN_EXPORT(exports, InternalFieldCount);
}

NODE_MODULE(gi, InitModule)
<|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////////////////
// $Id: soft_int.cc,v 1.18 2003/10/04 20:48:13 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2001  MandrakeSoft S.A.
//
//    MandrakeSoft S.A.
//    43, rue d'Aboukir
//    75002 Paris - France
//    http://www.linux-mandrake.com/
//    http://www.mandrakesoft.com/
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA

#define NEED_CPU_REG_SHORTCUTS 1
#include "bochs.h"
#define LOG_THIS BX_CPU_THIS_PTR

  void
BX_CPU_C::BOUND_GvMa(bxInstruction_c *i)
{
#if BX_CPU_LEVEL < 2
  BX_PANIC(("BOUND_GvMa: not supported on 8086!"));
#else

  if (i->modC0()) {
    /* undefined opcode exception */
    BX_PANIC(("bound: op2 must be memory reference"));
    UndefinedOpcode(i);
    }

  if (i->os32L()) {
    Bit32s bound_min, bound_max;
    Bit32s op1_32;

    op1_32 = BX_READ_32BIT_REG(i->nnn());

    read_virtual_dword(i->seg(), RMAddr(i), (Bit32u *) &bound_min);
    read_virtual_dword(i->seg(), RMAddr(i)+4, (Bit32u *) &bound_max);

    /* ??? */
    if ( (op1_32 < bound_min) || (op1_32 > bound_max) ) {
      BX_INFO(("BOUND: fails bounds test"));
      exception(5, 0, 0);
      }
    }
  else {
    Bit16s bound_min, bound_max;
    Bit16s op1_16;

    op1_16 = BX_READ_16BIT_REG(i->nnn());

    read_virtual_word(i->seg(), RMAddr(i), (Bit16u *) &bound_min);
    read_virtual_word(i->seg(), RMAddr(i)+2, (Bit16u *) &bound_max);

    /* ??? */
    if ( (op1_16 < bound_min) || (op1_16 > bound_max) ) {
      BX_INFO(("BOUND: fails bounds test"));
      exception(5, 0, 0);
      }
    }

#endif
}

  void
BX_CPU_C::INT1(bxInstruction_c *i)
{
  // This is an undocumented instrucion (opcode 0xf1)
  // which is useful for an ICE system.

#if BX_DEBUGGER
  BX_CPU_THIS_PTR show_flag |= Flag_int;
#endif

#if BX_EXTERNAL_DEBUGGER
  trap_debugger(0);
#endif

  interrupt(1, 1, 0, 0);
  BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
                      EIP);
}

  void
BX_CPU_C::INT3(bxInstruction_c *i)
{
  // INT 3 is not IOPL sensitive

#if BX_DEBUGGER
  BX_CPU_THIS_PTR show_flag |= Flag_int;
#endif

//BX_PANIC(("INT3: bailing"));
  interrupt(3, 1, 0, 0);
  BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
                      EIP);
}

  void
BX_CPU_C::INT_Ib(bxInstruction_c *i)
{
  Bit8u imm8;

#if BX_DEBUGGER
  BX_CPU_THIS_PTR show_flag |= Flag_int;
#endif

  imm8 = i->Ib();

  if (v8086_mode() && (BX_CPU_THIS_PTR get_IOPL()<3)) {
    //BX_INFO(("int_ib: v8086: IOPL<3"));
    exception(BX_GP_EXCEPTION, 0, 0);
    }

#ifdef SHOW_EXIT_STATUS
if ( (imm8 == 0x21) && (AH == 0x4c) ) {
  BX_INFO(("INT 21/4C called AL=0x%02x, BX=0x%04x", (unsigned) AL, (unsigned) BX));
  }
#endif

  interrupt(imm8, 1, 0, 0);
  BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
                      EIP);
}

  void
BX_CPU_C::INTO(bxInstruction_c *i)
{

#if BX_DEBUGGER
  BX_CPU_THIS_PTR show_flag |= Flag_int;
#endif

  /* ??? is this IOPL sensitive ? */
  if (v8086_mode()) BX_PANIC(("soft_int: v8086 mode unsupported"));

  if (get_OF()) {
    interrupt(4, 1, 0, 0);
    BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
                        BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
                        EIP);
    }
}
<commit_msg>clean soft_int code<commit_after>/////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2001  MandrakeSoft S.A.
//
//    MandrakeSoft S.A.
//    43, rue d'Aboukir
//    75002 Paris - France
//    http://www.linux-mandrake.com/
//    http://www.mandrakesoft.com/
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA

#define NEED_CPU_REG_SHORTCUTS 1
#include "bochs.h"
#define LOG_THIS BX_CPU_THIS_PTR

  void
BX_CPU_C::BOUND_GvMa(bxInstruction_c *i)
{
#if BX_CPU_LEVEL < 2
  BX_PANIC(("BOUND: not supported on 8086!"));
#else

  if (i->modC0()) {
    BX_PANIC(("BOUND: op2 must be memory reference"));
    UndefinedOpcode(i);
  }

  if (i->os32L()) {
    Bit32s bound_min, bound_max;
    Bit32s op1_32;

    op1_32 = BX_READ_32BIT_REG(i->nnn());

    read_virtual_dword(i->seg(), RMAddr(i),   (Bit32u *) &bound_min);
    read_virtual_dword(i->seg(), RMAddr(i)+4, (Bit32u *) &bound_max);

    if (op1_32 < bound_min || op1_32 > bound_max) {
      BX_INFO(("BOUND: fails bounds test"));
      exception(BX_BR_EXCEPTION, 0, 0);
    }
  }
  else {
    Bit16s bound_min, bound_max;
    Bit16s op1_16;

    op1_16 = BX_READ_16BIT_REG(i->nnn());

    read_virtual_word(i->seg(), RMAddr(i),   (Bit16u *) &bound_min);
    read_virtual_word(i->seg(), RMAddr(i)+2, (Bit16u *) &bound_max);

    if (op1_16 < bound_min || op1_16 > bound_max) {
      BX_INFO(("BOUND: fails bounds test"));
      exception(BX_BR_EXCEPTION, 0, 0);
    }
  }
#endif
}

  void
BX_CPU_C::INT1(bxInstruction_c *i)
{
  // This is an undocumented instrucion (opcode 0xf1)
  // which is useful for an ICE system.

#if BX_DEBUGGER
  BX_CPU_THIS_PTR show_flag |= Flag_int;
#endif

#if BX_EXTERNAL_DEBUGGER
  trap_debugger(0);
#endif

  interrupt(1, 1, 0, 0);
  BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
                      EIP);
}

  void
BX_CPU_C::INT3(bxInstruction_c *i)
{
  // INT 3 is not IOPL sensitive

#if BX_DEBUGGER
  BX_CPU_THIS_PTR show_flag |= Flag_int;
#endif

  interrupt(3, 1, 0, 0);
  BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
                      EIP);
}

  void
BX_CPU_C::INT_Ib(bxInstruction_c *i)
{
#if BX_DEBUGGER
  BX_CPU_THIS_PTR show_flag |= Flag_int;
#endif

  Bit8u imm8 = i->Ib();

  if (v8086_mode() && (BX_CPU_THIS_PTR get_IOPL()<3))
    exception(BX_GP_EXCEPTION, 0, 0);

#ifdef SHOW_EXIT_STATUS
if ( (imm8 == 0x21) && (AH == 0x4c) ) {
  BX_INFO(("INT 21/4C called AL=0x%02x, BX=0x%04x", (unsigned) AL, (unsigned) BX));
  }
#endif

  interrupt(imm8, 1, 0, 0);
  BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
                      BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
                      EIP);
}

  void
BX_CPU_C::INTO(bxInstruction_c *i)
{
#if BX_DEBUGGER
  BX_CPU_THIS_PTR show_flag |= Flag_int;
#endif

  /* ??? is this IOPL sensitive ? */
  if (v8086_mode()) BX_PANIC(("soft_int: v8086 mode unsupported"));

  if (get_OF()) {
    interrupt(4, 1, 0, 0);
    BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
                        BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
                        EIP);
    }
}
<|endoftext|>


<commit_before>#ifndef TEXT_UTILS_CPP
#define TEXT_UTILS_CPP

#include <sstream>
#include <vector>
#include <algorithm>

using namespace std;

template<typename T>
void split(const string &s, const char delim, T result) {
    stringstream ss;
    ss.str(s);
    string item;
    while (getline(ss, item, delim)) {
        *(result++) = item;
    }
}

inline vector<string> split(const string &s, const char delim) {
    vector<string> elems;
    split(s, delim, back_inserter(elems));
    return elems;
}

inline string get_contained(const string& str, const char start, const char end) {
    size_t first = str.find_first_of(start);
    size_t last = str.find_last_of(end);

    if(first == string::npos || last == string::npos)
        throw "Parse Error : All NFA arguments must be enclosed within {}";

    return str.substr(first+1, last-first-1);
}

inline string strip(string& str, const char c) {
    for (int i = 0; i < str.length(); ++i) {
        char current = str[i];
        if(current == c) {
            str.erase(str.begin() + i);
            i--;
        }
    }

    return str;
}

inline string strip(string& str) {
    return strip(str, ' ');
}

template <typename T, typename V>
inline bool contains(T container, V object){
    return std::find(container.begin(), container.end(), object) != container.end();
}

template <typename T>
inline const string to_string(T container, char delim) {
    typename T::const_iterator pos;

    string out;
    for (pos=container.begin(); pos!=container.end(); ++pos) {
        out += *pos + delim;
        if (delim != ' ')
            out += ' ';
    }

    unsigned long length = out.length();
    if(length > 1)
        out.erase(out.begin() + length - 1);

    if(delim != ' ')
        out.erase(out.begin() + length - 2);

    return out;
}

template <typename T>
inline const string to_string(T container) {
    return to_string(container, ' ');
}

#endif //TEXT_UTILS_CPP<commit_msg>Fixed bug in utils : length check in to_string<commit_after>#ifndef TEXT_UTILS_CPP
#define TEXT_UTILS_CPP

#include <sstream>
#include <vector>
#include <algorithm>

using namespace std;

template<typename T>
void split(const string &s, const char delim, T result) {
    stringstream ss;
    ss.str(s);
    string item;
    while (getline(ss, item, delim)) {
        *(result++) = item;
    }
}

inline vector<string> split(const string &s, const char delim) {
    vector<string> elems;
    split(s, delim, back_inserter(elems));
    return elems;
}

inline string get_contained(const string& str, const char start, const char end) {
    size_t first = str.find_first_of(start);
    size_t last = str.find_last_of(end);

    if(first == string::npos || last == string::npos)
        throw "Parse Error : All NFA arguments must be enclosed within {}";

    return str.substr(first+1, last-first-1);
}

inline string strip(string& str, const char c) {
    for (int i = 0; i < str.length(); ++i) {
        char current = str[i];
        if(current == c) {
            str.erase(str.begin() + i);
            i--;
        }
    }

    return str;
}

inline string strip(string& str) {
    return strip(str, ' ');
}

template <typename T, typename V>
inline bool contains(T container, V object){
    return std::find(container.begin(), container.end(), object) != container.end();
}

template <typename T>
inline const string to_string(T container, char delim) {
    typename T::const_iterator pos;

    string out;
    for (pos=container.begin(); pos!=container.end(); ++pos) {
        out += *pos + delim;
        if (delim != ' ')
            out += ' ';
    }

    unsigned long length = out.length();
    if(length > 1)
        out.erase(out.begin() + length - 1);

    if(length > 1 && delim != ' ')
        out.erase(out.begin() + length - 2);

    return out;
}

template <typename T>
inline const string to_string(T container) {
    return to_string(container, ' ');
}

#endif //TEXT_UTILS_CPP<|endoftext|>


<commit_before><commit_msg>and even commenting<commit_after><|endoftext|>