<commit_before>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2011 Francois Beaune
//
// 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.
//

// Interface header.
#include "physicalsurfaceshader.h"

// appleseed.renderer headers.
#include "renderer/kernel/lighting/ilightingengine.h"
#include "renderer/kernel/shading/shadingcontext.h"
#include "renderer/kernel/shading/shadingpoint.h"
#include "renderer/kernel/shading/shadingray.h"
#include "renderer/kernel/shading/shadingresult.h"
#include "renderer/modeling/environment/environment.h"
#include "renderer/modeling/environmentshader/environmentshader.h"
#include "renderer/modeling/input/inputarray.h"
#include "renderer/modeling/input/inputevaluator.h"
#include "renderer/modeling/input/source.h"
#include "renderer/modeling/scene/scene.h"
#include "renderer/modeling/surfaceshader/surfaceshader.h"

// appleseed.foundation headers.
#include "foundation/image/colorspace.h"
#include "foundation/math/vector.h"
#include "foundation/utility/containers/dictionary.h"
#include "foundation/utility/containers/specializedarrays.h"

// Standard headers.
#include <algorithm>
#include <cmath>

// Forward declarations.
namespace renderer  { class Assembly; }
namespace renderer  { class Project; }
namespace renderer  { class TextureCache; }

using namespace foundation;
using namespace std;

namespace renderer
{

namespace
{
    //
    // Physical surface shader.
    //

    const char* Model = "physical_surface_shader";

    class PhysicalSurfaceShader
      : public SurfaceShader
    {
      public:
        PhysicalSurfaceShader(
            const char*             name,
            const ParamArray&       params)
          : SurfaceShader(name, params)
          , m_lighting_conditions(IlluminantCIED65, XYZCMFCIE196410Deg)
          , m_has_alpha_mask(false)
        {
            m_inputs.declare("alpha_mask", InputFormatSpectrum, true);
            m_inputs.declare("aerial_persp_sky_color", InputFormatSpectrum, true);

            const string aerial_persp_mode = m_params.get_required<string>("aerial_persp_mode", "none");
            if (aerial_persp_mode == "none")
                m_aerial_persp_mode = AerialPerspNone;
            else if (aerial_persp_mode == "environment_shader")
                m_aerial_persp_mode = AerialPerspEnvironmentShader;
            else if (aerial_persp_mode == "sky_color")
                m_aerial_persp_mode = AerialPerspSkyColor;
            else
            {
                RENDERER_LOG_ERROR(
                    "invalid value \"%s\" for parameter \"aerial_persp_mode\", ",
                    "using default value \"none\"",
                    aerial_persp_mode.c_str());
                m_aerial_persp_mode = AerialPerspNone;
            }

            m_aerial_persp_rcp_distance = 1.0 / m_params.get_optional<double>("aerial_persp_distance", 1000.0);
            m_aerial_persp_intensity = m_params.get_optional<double>("aerial_persp_intensity", 0.01);
        }

        virtual void release() override
        {
            delete this;
        }

        virtual const char* get_model() const override
        {
            return Model;
        }

        virtual void on_frame_begin(
            const Project&          project,
            const Assembly&         assembly) override
        {
            SurfaceShader::on_frame_begin(project, assembly);

            m_has_alpha_mask = m_inputs.source("alpha_mask") != 0;
        }

        virtual void evaluate(
            SamplingContext&        sampling_context,
            const ShadingContext&   shading_context,
            const ShadingPoint&     shading_point,
            ShadingResult&          shading_result) const override
        {
            // Set color space to spectral.
            shading_result.m_color_space = ColorSpaceSpectral;

            // Retrieve the lighting engine.
            ILightingEngine* lighting_engine =
                shading_context.get_lighting_engine();
            assert(lighting_engine);

            // Compute the lighting.
            lighting_engine->compute_lighting(
                sampling_context,
                shading_context,
                shading_point,
                shading_result.m_color);

            // Evaluate alpha mask.
            evaluate_alpha_mask(
                sampling_context,
                shading_context.get_texture_cache(),
                shading_point,
                shading_result.m_alpha);

            if (m_aerial_persp_mode != AerialPerspNone)
            {
                Spectrum sky_color;

                if (m_aerial_persp_mode == AerialPerspSkyColor)
                {
                    // Evaluate the inputs to obtain the sky color.
                    InputValues values;
                    m_inputs.evaluate(
                        shading_context.get_texture_cache(),
                        shading_point.get_input_params(),
                        &values);
                    sky_color = values.m_aerial_persp_sky_color;
                }
                else
                {
                    // Retrieve the environment shader of the scene.
                    const Scene& scene = shading_point.get_scene();
                    const EnvironmentShader* environment_shader =
                        scene.get_environment()->get_environment_shader();

                    if (environment_shader)
                    {
                        // Execute the environment shader to obtain the sky color in the direction of the ray.
                        InputEvaluator input_evaluator(shading_context.get_texture_cache());
                        const ShadingRay& ray = shading_point.get_ray();
                        const Vector3d direction = normalize(ray.m_dir);
                        ShadingResult sky;
                        environment_shader->evaluate(input_evaluator, direction, sky);
                        sky.transform_to_spectrum(m_lighting_conditions);
                        sky_color = sky.m_color;
                    }
                    else sky_color.set(0.0f);
                }

                // Compute the blend factor.
                const double d = shading_point.get_distance() * m_aerial_persp_rcp_distance;
                const double k = m_aerial_persp_intensity * exp(d);
                const double blend = min(k, 1.0);

                // Blend the shading result and the sky color.
                sky_color *= static_cast<float>(blend);
                shading_result.m_color *= static_cast<float>(1.0 - blend);
                shading_result.m_color += sky_color;
            }
        }

        virtual void evaluate_alpha_mask(
            SamplingContext&        sampling_context,
            TextureCache&           texture_cache,
            const ShadingPoint&     shading_point,
            Alpha&                  alpha) const override
        {
            if (!m_has_alpha_mask)
            {
                // Set alpha channel to full opacity.
                alpha = Alpha(1.0);
            }
            else
            {
                // Evaluate the inputs.
                InputValues values;
                m_inputs.evaluate(
                    texture_cache,
                    shading_point.get_input_params(),
                    &values);

                // Set alpha channel.
                alpha = values.m_alpha_mask_alpha;
            }
        }

      private:
        struct InputValues
        {
            Spectrum    m_alpha_mask_color;             // unused
            Alpha       m_alpha_mask_alpha;

            Spectrum    m_aerial_persp_sky_color;
            Alpha       m_aerial_persp_sky_alpha;       // unused
        };

        enum AerialPerspMode
        {
            AerialPerspNone,
            AerialPerspEnvironmentShader,
            AerialPerspSkyColor
        };

        const LightingConditions    m_lighting_conditions;

        bool                        m_has_alpha_mask;

        AerialPerspMode             m_aerial_persp_mode;
        double                      m_aerial_persp_rcp_distance;
        double                      m_aerial_persp_intensity;
    };
}

//
// PhysicalSurfaceShaderFactory class implementation.
//

const char* PhysicalSurfaceShaderFactory::get_model() const
{
    return Model;
}

const char* PhysicalSurfaceShaderFactory::get_human_readable_model() const
{
    return "Physical";
}

DictionaryArray PhysicalSurfaceShaderFactory::get_widget_definitions() const
{
    DictionaryArray definitions;

    definitions.push_back(
        Dictionary()
            .insert("name", "alpha_mask")
            .insert("label", "Alpha Mask")
            .insert("widget", "entity_picker")
            .insert("entity_types",
                Dictionary()
                    .insert("color", "Colors")
                    .insert("texture_instance", "Textures"))
            .insert("use", "optional")
            .insert("default", ""));

    definitions.push_back(
        Dictionary()
            .insert("name", "aerial_persp_mode")
            .insert("label", "Aerial Perspective Mode")
            .insert("widget", "dropdown_list")
            .insert("dropdown_items",
                Dictionary()
                    .insert("None", "none")
                    .insert("Use Environment Shader", "environment_shader")
                    .insert("Use Sky Color", "sky_color"))
            .insert("use", "optional")
            .insert("default", "none"));

    definitions.push_back(
        Dictionary()
            .insert("name", "aerial_persp_sky_color")
            .insert("label", "Aerial Perspective Sky Color")
            .insert("widget", "entity_picker")
            .insert("entity_types", Dictionary().insert("color", "Colors"))
            .insert("use", "optional")
            .insert("default", ""));

    definitions.push_back(
        Dictionary()
            .insert("name", "aerial_persp_distance")
            .insert("label", "Aerial Perspective Distance")
            .insert("widget", "text_box")
            .insert("default", "1000.0")
            .insert("use", "optional"));

    definitions.push_back(
        Dictionary()
            .insert("name", "aerial_persp_intensity")
            .insert("label", "Aerial Perspective Intensity")
            .insert("widget", "text_box")
            .insert("default", "0.01")
            .insert("use", "optional"));

    return definitions;
}

auto_release_ptr<SurfaceShader> PhysicalSurfaceShaderFactory::create(
    const char*         name,
    const ParamArray&   params) const
{
    return
        auto_release_ptr<SurfaceShader>(
            new PhysicalSurfaceShader(name, params));
}

}   // namespace renderer
<commit_msg>the "aerial_persp_mode" parameter of the Physical surface shader is optional, not required.<commit_after>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2011 Francois Beaune
//
// 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.
//

// Interface header.
#include "physicalsurfaceshader.h"

// appleseed.renderer headers.
#include "renderer/kernel/lighting/ilightingengine.h"
#include "renderer/kernel/shading/shadingcontext.h"
#include "renderer/kernel/shading/shadingpoint.h"
#include "renderer/kernel/shading/shadingray.h"
#include "renderer/kernel/shading/shadingresult.h"
#include "renderer/modeling/environment/environment.h"
#include "renderer/modeling/environmentshader/environmentshader.h"
#include "renderer/modeling/input/inputarray.h"
#include "renderer/modeling/input/inputevaluator.h"
#include "renderer/modeling/input/source.h"
#include "renderer/modeling/scene/scene.h"
#include "renderer/modeling/surfaceshader/surfaceshader.h"

// appleseed.foundation headers.
#include "foundation/image/colorspace.h"
#include "foundation/math/vector.h"
#include "foundation/utility/containers/dictionary.h"
#include "foundation/utility/containers/specializedarrays.h"

// Standard headers.
#include <algorithm>
#include <cmath>

// Forward declarations.
namespace renderer  { class Assembly; }
namespace renderer  { class Project; }
namespace renderer  { class TextureCache; }

using namespace foundation;
using namespace std;

namespace renderer
{

namespace
{
    //
    // Physical surface shader.
    //

    const char* Model = "physical_surface_shader";

    class PhysicalSurfaceShader
      : public SurfaceShader
    {
      public:
        PhysicalSurfaceShader(
            const char*             name,
            const ParamArray&       params)
          : SurfaceShader(name, params)
          , m_lighting_conditions(IlluminantCIED65, XYZCMFCIE196410Deg)
          , m_has_alpha_mask(false)
        {
            m_inputs.declare("alpha_mask", InputFormatSpectrum, true);
            m_inputs.declare("aerial_persp_sky_color", InputFormatSpectrum, true);

            const string aerial_persp_mode = m_params.get_optional<string>("aerial_persp_mode", "none");
            if (aerial_persp_mode == "none")
                m_aerial_persp_mode = AerialPerspNone;
            else if (aerial_persp_mode == "environment_shader")
                m_aerial_persp_mode = AerialPerspEnvironmentShader;
            else if (aerial_persp_mode == "sky_color")
                m_aerial_persp_mode = AerialPerspSkyColor;
            else
            {
                RENDERER_LOG_ERROR(
                    "invalid value \"%s\" for parameter \"aerial_persp_mode\", ",
                    "using default value \"none\"",
                    aerial_persp_mode.c_str());
                m_aerial_persp_mode = AerialPerspNone;
            }

            m_aerial_persp_rcp_distance = 1.0 / m_params.get_optional<double>("aerial_persp_distance", 1000.0);
            m_aerial_persp_intensity = m_params.get_optional<double>("aerial_persp_intensity", 0.01);
        }

        virtual void release() override
        {
            delete this;
        }

        virtual const char* get_model() const override
        {
            return Model;
        }

        virtual void on_frame_begin(
            const Project&          project,
            const Assembly&         assembly) override
        {
            SurfaceShader::on_frame_begin(project, assembly);

            m_has_alpha_mask = m_inputs.source("alpha_mask") != 0;
        }

        virtual void evaluate(
            SamplingContext&        sampling_context,
            const ShadingContext&   shading_context,
            const ShadingPoint&     shading_point,
            ShadingResult&          shading_result) const override
        {
            // Set color space to spectral.
            shading_result.m_color_space = ColorSpaceSpectral;

            // Retrieve the lighting engine.
            ILightingEngine* lighting_engine =
                shading_context.get_lighting_engine();
            assert(lighting_engine);

            // Compute the lighting.
            lighting_engine->compute_lighting(
                sampling_context,
                shading_context,
                shading_point,
                shading_result.m_color);

            // Evaluate alpha mask.
            evaluate_alpha_mask(
                sampling_context,
                shading_context.get_texture_cache(),
                shading_point,
                shading_result.m_alpha);

            if (m_aerial_persp_mode != AerialPerspNone)
            {
                Spectrum sky_color;

                if (m_aerial_persp_mode == AerialPerspSkyColor)
                {
                    // Evaluate the inputs to obtain the sky color.
                    InputValues values;
                    m_inputs.evaluate(
                        shading_context.get_texture_cache(),
                        shading_point.get_input_params(),
                        &values);
                    sky_color = values.m_aerial_persp_sky_color;
                }
                else
                {
                    // Retrieve the environment shader of the scene.
                    const Scene& scene = shading_point.get_scene();
                    const EnvironmentShader* environment_shader =
                        scene.get_environment()->get_environment_shader();

                    if (environment_shader)
                    {
                        // Execute the environment shader to obtain the sky color in the direction of the ray.
                        InputEvaluator input_evaluator(shading_context.get_texture_cache());
                        const ShadingRay& ray = shading_point.get_ray();
                        const Vector3d direction = normalize(ray.m_dir);
                        ShadingResult sky;
                        environment_shader->evaluate(input_evaluator, direction, sky);
                        sky.transform_to_spectrum(m_lighting_conditions);
                        sky_color = sky.m_color;
                    }
                    else sky_color.set(0.0f);
                }

                // Compute the blend factor.
                const double d = shading_point.get_distance() * m_aerial_persp_rcp_distance;
                const double k = m_aerial_persp_intensity * exp(d);
                const double blend = min(k, 1.0);

                // Blend the shading result and the sky color.
                sky_color *= static_cast<float>(blend);
                shading_result.m_color *= static_cast<float>(1.0 - blend);
                shading_result.m_color += sky_color;
            }
        }

        virtual void evaluate_alpha_mask(
            SamplingContext&        sampling_context,
            TextureCache&           texture_cache,
            const ShadingPoint&     shading_point,
            Alpha&                  alpha) const override
        {
            if (!m_has_alpha_mask)
            {
                // Set alpha channel to full opacity.
                alpha = Alpha(1.0);
            }
            else
            {
                // Evaluate the inputs.
                InputValues values;
                m_inputs.evaluate(
                    texture_cache,
                    shading_point.get_input_params(),
                    &values);

                // Set alpha channel.
                alpha = values.m_alpha_mask_alpha;
            }
        }

      private:
        struct InputValues
        {
            Spectrum    m_alpha_mask_color;             // unused
            Alpha       m_alpha_mask_alpha;

            Spectrum    m_aerial_persp_sky_color;
            Alpha       m_aerial_persp_sky_alpha;       // unused
        };

        enum AerialPerspMode
        {
            AerialPerspNone,
            AerialPerspEnvironmentShader,
            AerialPerspSkyColor
        };

        const LightingConditions    m_lighting_conditions;

        bool                        m_has_alpha_mask;

        AerialPerspMode             m_aerial_persp_mode;
        double                      m_aerial_persp_rcp_distance;
        double                      m_aerial_persp_intensity;
    };
}

//
// PhysicalSurfaceShaderFactory class implementation.
//

const char* PhysicalSurfaceShaderFactory::get_model() const
{
    return Model;
}

const char* PhysicalSurfaceShaderFactory::get_human_readable_model() const
{
    return "Physical";
}

DictionaryArray PhysicalSurfaceShaderFactory::get_widget_definitions() const
{
    DictionaryArray definitions;

    definitions.push_back(
        Dictionary()
            .insert("name", "alpha_mask")
            .insert("label", "Alpha Mask")
            .insert("widget", "entity_picker")
            .insert("entity_types",
                Dictionary()
                    .insert("color", "Colors")
                    .insert("texture_instance", "Textures"))
            .insert("use", "optional")
            .insert("default", ""));

    definitions.push_back(
        Dictionary()
            .insert("name", "aerial_persp_mode")
            .insert("label", "Aerial Perspective Mode")
            .insert("widget", "dropdown_list")
            .insert("dropdown_items",
                Dictionary()
                    .insert("None", "none")
                    .insert("Use Environment Shader", "environment_shader")
                    .insert("Use Sky Color", "sky_color"))
            .insert("use", "optional")
            .insert("default", "none"));

    definitions.push_back(
        Dictionary()
            .insert("name", "aerial_persp_sky_color")
            .insert("label", "Aerial Perspective Sky Color")
            .insert("widget", "entity_picker")
            .insert("entity_types", Dictionary().insert("color", "Colors"))
            .insert("use", "optional")
            .insert("default", ""));

    definitions.push_back(
        Dictionary()
            .insert("name", "aerial_persp_distance")
            .insert("label", "Aerial Perspective Distance")
            .insert("widget", "text_box")
            .insert("default", "1000.0")
            .insert("use", "optional"));

    definitions.push_back(
        Dictionary()
            .insert("name", "aerial_persp_intensity")
            .insert("label", "Aerial Perspective Intensity")
            .insert("widget", "text_box")
            .insert("default", "0.01")
            .insert("use", "optional"));

    return definitions;
}

auto_release_ptr<SurfaceShader> PhysicalSurfaceShaderFactory::create(
    const char*         name,
    const ParamArray&   params) const
{
    return
        auto_release_ptr<SurfaceShader>(
            new PhysicalSurfaceShader(name, params));
}

}   // namespace renderer
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <string>

// size_type find_first_not_of(charT c, size_type pos = 0) const;

#include <string>
#include <cassert>

template <class S>
void
test(const S& s, typename S::value_type c, typename S::size_type pos,
     typename S::size_type x)
{
    assert(s.find_first_not_of(c, pos) == x);
    if (x != S::npos)
        assert(pos <= x && x < s.size());
}

template <class S>
void
test(const S& s, typename S::value_type c, typename S::size_type x)
{
    assert(s.find_first_not_of(c) == x);
    if (x != S::npos)
        assert(x < s.size());
}

typedef std::string S;

int main()
{
    test(S(""), 'q', 0, S::npos);
    test(S(""), 'q', 1, S::npos);
    test(S("kitcj"), 'q', 0, 0);
    test(S("qkamf"), 'q', 1, 1);
    test(S("nhmko"), 'q', 2, 2);
    test(S("tpsaf"), 'q', 4, 4);
    test(S("lahfb"), 'q', 5, S::npos);
    test(S("irkhs"), 'q', 6, S::npos);
    test(S("gmfhdaipsr"), 'q', 0, 0);
    test(S("kantesmpgj"), 'q', 1, 1);
    test(S("odaftiegpm"), 'q', 5, 5);
    test(S("oknlrstdpi"), 'q', 9, 9);
    test(S("eolhfgpjqk"), 'q', 10, S::npos);
    test(S("pcdrofikas"), 'q', 11, S::npos);
    test(S("nbatdlmekrgcfqsophij"), 'q', 0, 0);
    test(S("bnrpehidofmqtcksjgla"), 'q', 1, 1);
    test(S("jdmciepkaqgotsrfnhlb"), 'q', 10, 10);
    test(S("jtdaefblsokrmhpgcnqi"), 'q', 19, 19);
    test(S("hkbgspofltajcnedqmri"), 'q', 20, S::npos);
    test(S("oselktgbcapndfjihrmq"), 'q', 21, S::npos);

    test(S(""), 'q', S::npos);
    test(S("csope"), 'q', 0);
    test(S("gfsmthlkon"), 'q', 0);
    test(S("laenfsbridchgotmkqpj"), 'q', 0);
}
<commit_msg>Klaas de Vries:  Fix bug in libc++'s std::string::find_first_not_of.<commit_after>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <string>

// size_type find_first_not_of(charT c, size_type pos = 0) const;

#include <string>
#include <cassert>

template <class S>
void
test(const S& s, typename S::value_type c, typename S::size_type pos,
     typename S::size_type x)
{
    assert(s.find_first_not_of(c, pos) == x);
    if (x != S::npos)
        assert(pos <= x && x < s.size());
}

template <class S>
void
test(const S& s, typename S::value_type c, typename S::size_type x)
{
    assert(s.find_first_not_of(c) == x);
    if (x != S::npos)
        assert(x < s.size());
}

typedef std::string S;

int main()
{
    test(S(""), 'q', 0, S::npos);
    test(S(""), 'q', 1, S::npos);
    test(S("kitcj"), 'q', 0, 0);
    test(S("qkamf"), 'q', 1, 1);
    test(S("nhmko"), 'q', 2, 2);
    test(S("tpsaf"), 'q', 4, 4);
    test(S("lahfb"), 'q', 5, S::npos);
    test(S("irkhs"), 'q', 6, S::npos);
    test(S("gmfhdaipsr"), 'q', 0, 0);
    test(S("kantesmpgj"), 'q', 1, 1);
    test(S("odaftiegpm"), 'q', 5, 5);
    test(S("oknlrstdpi"), 'q', 9, 9);
    test(S("eolhfgpjqk"), 'q', 10, S::npos);
    test(S("pcdrofikas"), 'q', 11, S::npos);
    test(S("nbatdlmekrgcfqsophij"), 'q', 0, 0);
    test(S("bnrpehidofmqtcksjgla"), 'q', 1, 1);
    test(S("jdmciepkaqgotsrfnhlb"), 'q', 10, 10);
    test(S("jtdaefblsokrmhpgcnqi"), 'q', 19, 19);
    test(S("hkbgspofltajcnedqmri"), 'q', 20, S::npos);
    test(S("oselktgbcapndfjihrmq"), 'q', 21, S::npos);

    test(S(""), 'q', S::npos);
    test(S("q"), 'q', S::npos);
    test(S("qqq"), 'q', S::npos);
    test(S("csope"), 'q', 0);
    test(S("gfsmthlkon"), 'q', 0);
    test(S("laenfsbridchgotmkqpj"), 'q', 0);
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include <QDebug>
#include <QDBusInterface>
#include <QDBusConnection>
#include <QDBusReply>
#include <QSystemNetworkInfo>

QTM_USE_NAMESPACE

const static QString NORMAL_MODE = "normal";
const static QString OFFLINE_MODE = "offline";

static QDBusInterface mceConnectionInterface("com.nokia.mce",
                                             "/com/nokia/mce/request",
                                             "com.nokia.mce.request",
                                             QDBusConnection::systemBus());

/**
 * Starts an event loop that runs until the given signal is received.
 * Optionally the event loop can return earlier on a timeout.
 *
 * \return \p true if the requested signal was received
 *         \p false on timeout
 */
static bool waitForSignal(QObject *obj, const char *signal, int timeout = 0)
{
    QEventLoop loop;
    QObject::connect(obj, signal, &loop, SLOT(quit()));
    QTimer timer;
    QSignalSpy timeoutSpy(&timer, SIGNAL(timeout()));
    if (timeout > 0) {
        QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
        timer.setSingleShot(true);
        timer.start(timeout);
    }
    loop.exec();
    return timeoutSpy.isEmpty();
}

static void log(QString message)
{
    qDebug() << QDateTime::currentDateTime().toTime_t() << " " << message;
}

static void setDeviceMode(QString deviceMode)
{
    mceConnectionInterface.call("req_device_mode_change", deviceMode);
}

class DropNetworkThread : public QThread
{
public:
    void run()
    {
        log("DropNetworkThread: Waiting 2s before dropping the cellular network");
        sleep(2);
        setDeviceMode(OFFLINE_MODE);
        log("DropNetworkThread: Cellular network dropped");
    }
};

class tst_QSystemNetworkInfo : public QObject
{
    Q_OBJECT

public:
    tst_QSystemNetworkInfo();
    virtual ~tst_QSystemNetworkInfo();

public slots:
    void init();
    void cleanup();

private slots:
    void networkSignalStrengthChanged();
    void networkStatusChanged();
    void mobileCountryCodeChanged();
    void mobileNetworkCodeChanged();
    void networkNameChanged();
    void networkModeChanged();

private:
    QSystemNetworkInfo *m_systemNetworkInfo;
    DropNetworkThread *m_dropNetworkThread;
};

tst_QSystemNetworkInfo::tst_QSystemNetworkInfo()
{
    m_dropNetworkThread = new DropNetworkThread();
    m_systemNetworkInfo = new QSystemNetworkInfo();
}

tst_QSystemNetworkInfo::~tst_QSystemNetworkInfo()
{
    delete m_dropNetworkThread, m_dropNetworkThread = 0;
    delete m_systemNetworkInfo, m_systemNetworkInfo = 0;
}

/*
 * Called before each test case
 */
void tst_QSystemNetworkInfo::init()
{
    log("init: setDeviceMode: normal");
    setDeviceMode(NORMAL_MODE);
    QTest::qWait(2000);
    log("init done");
}

/*
 * Called after each test case
 */
void tst_QSystemNetworkInfo::cleanup()
{
    QTest::qWait(2000);
    log("cleanup: setDeviceMode: normal");
    setDeviceMode(NORMAL_MODE);
    QTest::qWait(2000);
    log("cleanup done");
}

/*
 * The test cases
 */
void tst_QSystemNetworkInfo::networkSignalStrengthChanged()
{
    m_dropNetworkThread->start();

    log("Waiting 60s for network signal strength to change");
    QVERIFY(::waitForSignal(m_systemNetworkInfo, SIGNAL(networkSignalStrengthChanged(QSystemNetworkInfo::NetworkMode, int)), 60 * 1000));
    log("networkSignalStrengthChanged");
}

void tst_QSystemNetworkInfo::networkStatusChanged()
{
    m_dropNetworkThread->start();

    log("Waiting 60s for network status to change");
    QVERIFY(::waitForSignal(m_systemNetworkInfo, SIGNAL(networkStatusChanged(QSystemNetworkInfo::NetworkMode,QSystemNetworkInfo::NetworkStatus)), 60 * 1000));
    log("networkStatusChanged");
}

void tst_QSystemNetworkInfo::mobileCountryCodeChanged()
{
    m_dropNetworkThread->start();

    log("Waiting 60s for mobile country code to change");
    QVERIFY(::waitForSignal(m_systemNetworkInfo, SIGNAL(currentMobileCountryCodeChanged(QString)), 60 * 1000));
    log("currentMobileCountryCodeChanged");
}

void tst_QSystemNetworkInfo::mobileNetworkCodeChanged()
{
    m_dropNetworkThread->start();

    log("Waiting 60s for mobile network code to change");
    QVERIFY(::waitForSignal(m_systemNetworkInfo, SIGNAL(currentMobileNetworkCodeChanged(QString)), 60 * 1000));
    log("currentMobileNetworkCodeChanged");
}

void tst_QSystemNetworkInfo::networkNameChanged()
{
    m_dropNetworkThread->start();

    log("Waiting 60s for network name to change");
    QVERIFY(::waitForSignal(m_systemNetworkInfo, SIGNAL(networkNameChanged(QSystemNetworkInfo::NetworkMode,QString)), 60 * 1000));
    log("networkNameChanged");
}

void tst_QSystemNetworkInfo::networkModeChanged()
{
    m_dropNetworkThread->start();

    log("Waiting 60s for network mode to change");
    QVERIFY(::waitForSignal(m_systemNetworkInfo, SIGNAL(networkModeChanged(QSystemNetworkInfo::NetworkMode)), 60 * 1000));
    log("networkModeChanged");
}

QTEST_MAIN(tst_QSystemNetworkInfo)
#include "tst_qsystemnetworkinfo_maemo.moc"
<commit_msg>fix spelling error<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include <QDebug>
#include <QDBusInterface>
#include <QDBusConnection>
#include <QDBusReply>
#include <QSystemInfo/QSystemNetworkInfo>

QTM_USE_NAMESPACE

const static QString NORMAL_MODE = "normal";
const static QString OFFLINE_MODE = "offline";

static QDBusInterface mceConnectionInterface("com.nokia.mce",
                                             "/com/nokia/mce/request",
                                             "com.nokia.mce.request",
                                             QDBusConnection::systemBus());

/**
 * Starts an event loop that runs until the given signal is received.
 * Optionally the event loop can return earlier on a timeout.
 *
 * \return \p true if the requested signal was received
 *         \p false on timeout
 */
static bool waitForSignal(QObject *obj, const char *signal, int timeout = 0)
{
    QEventLoop loop;
    QObject::connect(obj, signal, &loop, SLOT(quit()));
    QTimer timer;
    QSignalSpy timeoutSpy(&timer, SIGNAL(timeout()));
    if (timeout > 0) {
        QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
        timer.setSingleShot(true);
        timer.start(timeout);
    }
    loop.exec();
    return timeoutSpy.isEmpty();
}

static void log(QString message)
{
    qDebug() << QDateTime::currentDateTime().toTime_t() << " " << message;
}

static void setDeviceMode(QString deviceMode)
{
    mceConnectionInterface.call("req_device_mode_change", deviceMode);
}

class DropNetworkThread : public QThread
{
public:
    void run()
    {
        log("DropNetworkThread: Waiting 2s before dropping the cellular network");
        sleep(2);
        setDeviceMode(OFFLINE_MODE);
        log("DropNetworkThread: Cellular network dropped");
    }
};

class tst_QSystemNetworkInfo : public QObject
{
    Q_OBJECT

public:
    tst_QSystemNetworkInfo();
    virtual ~tst_QSystemNetworkInfo();

public slots:
    void init();
    void cleanup();

private slots:
    void networkSignalStrengthChanged();
    void networkStatusChanged();
    void mobileCountryCodeChanged();
    void mobileNetworkCodeChanged();
    void networkNameChanged();
    void networkModeChanged();

private:
    QSystemNetworkInfo *m_systemNetworkInfo;
    DropNetworkThread *m_dropNetworkThread;
};

tst_QSystemNetworkInfo::tst_QSystemNetworkInfo()
{
    m_dropNetworkThread = new DropNetworkThread();
    m_systemNetworkInfo = new QSystemNetworkInfo();
}

tst_QSystemNetworkInfo::~tst_QSystemNetworkInfo()
{
    delete m_dropNetworkThread, m_dropNetworkThread = 0;
    delete m_systemNetworkInfo, m_systemNetworkInfo = 0;
}

/*
 * Called before each test case
 */
void tst_QSystemNetworkInfo::init()
{
    log("init: setDeviceMode: normal");
    setDeviceMode(NORMAL_MODE);
    QTest::qWait(2000);
    log("init done");
}

/*
 * Called after each test case
 */
void tst_QSystemNetworkInfo::cleanup()
{
    QTest::qWait(2000);
    log("cleanup: setDeviceMode: normal");
    setDeviceMode(NORMAL_MODE);
    QTest::qWait(2000);
    log("cleanup done");
}

/*
 * The test cases
 */
void tst_QSystemNetworkInfo::networkSignalStrengthChanged()
{
    m_dropNetworkThread->start();

    log("Waiting 60s for network signal strength to change");
    QVERIFY(::waitForSignal(m_systemNetworkInfo, SIGNAL(networkSignalStrengthChanged(QSystemNetworkInfo::NetworkMode, int)), 60 * 1000));
    log("networkSignalStrengthChanged");
}

void tst_QSystemNetworkInfo::networkStatusChanged()
{
    m_dropNetworkThread->start();

    log("Waiting 60s for network status to change");
    QVERIFY(::waitForSignal(m_systemNetworkInfo, SIGNAL(networkStatusChanged(QSystemNetworkInfo::NetworkMode,QSystemNetworkInfo::NetworkStatus)), 60 * 1000));
    log("networkStatusChanged");
}

void tst_QSystemNetworkInfo::mobileCountryCodeChanged()
{
    m_dropNetworkThread->start();

    log("Waiting 60s for mobile country code to change");
    QVERIFY(::waitForSignal(m_systemNetworkInfo, SIGNAL(currentMobileCountryCodeChanged(QString)), 60 * 1000));
    log("currentMobileCountryCodeChanged");
}

void tst_QSystemNetworkInfo::mobileNetworkCodeChanged()
{
    m_dropNetworkThread->start();

    log("Waiting 60s for mobile network code to change");
    QVERIFY(::waitForSignal(m_systemNetworkInfo, SIGNAL(currentMobileNetworkCodeChanged(QString)), 60 * 1000));
    log("currentMobileNetworkCodeChanged");
}

void tst_QSystemNetworkInfo::networkNameChanged()
{
    m_dropNetworkThread->start();

    log("Waiting 60s for network name to change");
    QVERIFY(::waitForSignal(m_systemNetworkInfo, SIGNAL(networkNameChanged(QSystemNetworkInfo::NetworkMode,QString)), 60 * 1000));
    log("networkNameChanged");
}

void tst_QSystemNetworkInfo::networkModeChanged()
{
    m_dropNetworkThread->start();

    log("Waiting 60s for network mode to change");
    QVERIFY(::waitForSignal(m_systemNetworkInfo, SIGNAL(networkModeChanged(QSystemNetworkInfo::NetworkMode)), 60 * 1000));
    log("networkModeChanged");
}

QTEST_MAIN(tst_QSystemNetworkInfo)
#include "tst_qsystemnetworkinfo_maemo.moc"
<|endoftext|>


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

#include <gtest/gtest.h>

extern "C"
{
#include "media/aeron_udp_channel_transport.h"
#include "media/aeron_udp_channel_transport_loss.h"
#include "protocol/aeron_udp_protocol.h"
#include "util/aeron_netutil.h"

#if !defined(HAVE_STRUCT_MMSGHDR)
struct mmsghdr
{
    struct msghdr msg_hdr;
    unsigned int msg_len;
};
#endif
}

#define TEMP_URL_LEN (128)

class UdpChannelTransporTest : public testing::Test
{
public:
    UdpChannelTransporTest() = default;

protected:
    void SetUp() override
    {
        aeron_driver_context_init(&m_driverContext);
    }

    void TearDown() override
    {
        aeron_driver_context_close(m_driverContext);
    }

    aeron_driver_context_t *m_driverContext = nullptr;
};

void test_revc_func(
    aeron_udp_channel_data_paths_t *data_paths,
    aeron_udp_channel_transport_t *transport,
    void *receiver_clientd,
    void *endpoint_clientd,
    void *destination_clientd,
    uint8_t *buffer,
    size_t length,
    struct sockaddr_storage *addr,
    struct timespec *media_timestamp)
{

}

TEST_F(UdpChannelTransporTest, shouldErrorWithInvalidSendAddress)
{
    aeron_udp_channel_transport_bindings_t *transport_bindings = aeron_udp_channel_transport_bindings_load_media(
        "default");
    aeron_udp_channel_data_paths_t data_paths = {};
    ASSERT_NE(
        -1,
        aeron_udp_channel_data_paths_init(
            &data_paths,
            nullptr,
            nullptr,
            transport_bindings,
            test_revc_func,
            m_driverContext,
            AERON_UDP_CHANNEL_TRANSPORT_AFFINITY_SENDER));

    ASSERT_NE(nullptr, transport_bindings) << aeron_errmsg();

    struct sockaddr_in bind_addr = {};
    struct sockaddr_in send_addr = {};

    ASSERT_NE(
        -1,
        aeron_ip_addr_resolver("127.0.0.1", (struct sockaddr_storage*)&bind_addr, AF_INET, IPPROTO_UDP));
    bind_addr.sin_port = 0;

    ASSERT_NE(
        -1,
        aeron_ip_addr_resolver("0.0.0.0", (struct sockaddr_storage*)&send_addr, AF_INET, IPPROTO_UDP));
    send_addr.sin_port = 6666;

    aeron_udp_channel_transport_t transport = {};
    ASSERT_NE(-1, transport_bindings->init_func(
        &transport,
        (struct sockaddr_storage*)&bind_addr,
        (struct sockaddr_storage*)nullptr,
        0,
        16,
        65536,
        65536,
        false,
        m_driverContext,
        AERON_UDP_CHANNEL_TRANSPORT_AFFINITY_SENDER)) << aeron_errmsg();

    const char *data = "Hello World";

    struct iovec message = {};
    message.iov_base = static_cast<void *>(const_cast<char *>(data));
    message.iov_len = static_cast<unsigned int>(strlen(data));

    struct msghdr header = {};
    header.msg_name = static_cast<void *>(&send_addr);
    header.msg_namelen = sizeof(send_addr);
    header.msg_iov = &message;
    header.msg_iovlen = 1;
    header.msg_control = nullptr;
    header.msg_controllen = 1;
    header.msg_flags = 389475;

    ASSERT_EQ(-1, transport_bindings->sendmsg_func(&data_paths, &transport, &header)) << aeron_errmsg();
}
<commit_msg>[C] Spelling.<commit_after>/*
 * Copyright 2014-2021 Real Logic Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>

extern "C"
{
#include "media/aeron_udp_channel_transport.h"
#include "media/aeron_udp_channel_transport_loss.h"
#include "protocol/aeron_udp_protocol.h"
#include "util/aeron_netutil.h"

#if !defined(HAVE_STRUCT_MMSGHDR)
struct mmsghdr
{
    struct msghdr msg_hdr;
    unsigned int msg_len;
};
#endif
}

#define TEMP_URL_LEN (128)

class UdpChannelTransportTest : public testing::Test
{
public:
    UdpChannelTransportTest() = default;

protected:
    void SetUp() override
    {
        aeron_driver_context_init(&m_driverContext);
    }

    void TearDown() override
    {
        aeron_driver_context_close(m_driverContext);
    }

    aeron_driver_context_t *m_driverContext = nullptr;
};

void test_revc_func(
    aeron_udp_channel_data_paths_t *data_paths,
    aeron_udp_channel_transport_t *transport,
    void *receiver_clientd,
    void *endpoint_clientd,
    void *destination_clientd,
    uint8_t *buffer,
    size_t length,
    struct sockaddr_storage *addr,
    struct timespec *media_timestamp)
{

}

TEST_F(UdpChannelTransportTest, shouldErrorWithInvalidSendAddress)
{
    aeron_udp_channel_transport_bindings_t *transport_bindings = aeron_udp_channel_transport_bindings_load_media(
        "default");
    aeron_udp_channel_data_paths_t data_paths = {};
    ASSERT_NE(
        -1,
        aeron_udp_channel_data_paths_init(
            &data_paths,
            nullptr,
            nullptr,
            transport_bindings,
            test_revc_func,
            m_driverContext,
            AERON_UDP_CHANNEL_TRANSPORT_AFFINITY_SENDER));

    ASSERT_NE(nullptr, transport_bindings) << aeron_errmsg();

    struct sockaddr_in bind_addr = {};
    struct sockaddr_in send_addr = {};

    ASSERT_NE(
        -1,
        aeron_ip_addr_resolver("127.0.0.1", (struct sockaddr_storage*)&bind_addr, AF_INET, IPPROTO_UDP));
    bind_addr.sin_port = 0;

    ASSERT_NE(
        -1,
        aeron_ip_addr_resolver("0.0.0.0", (struct sockaddr_storage*)&send_addr, AF_INET, IPPROTO_UDP));
    send_addr.sin_port = 6666;

    aeron_udp_channel_transport_t transport = {};
    ASSERT_NE(-1, transport_bindings->init_func(
        &transport,
        (struct sockaddr_storage*)&bind_addr,
        (struct sockaddr_storage*)nullptr,
        0,
        16,
        65536,
        65536,
        false,
        m_driverContext,
        AERON_UDP_CHANNEL_TRANSPORT_AFFINITY_SENDER)) << aeron_errmsg();

    const char *data = "Hello World";

    struct iovec message = {};
    message.iov_base = static_cast<void *>(const_cast<char *>(data));
    message.iov_len = static_cast<unsigned int>(strlen(data));

    struct msghdr header = {};
    header.msg_name = static_cast<void *>(&send_addr);
    header.msg_namelen = sizeof(send_addr);
    header.msg_iov = &message;
    header.msg_iovlen = 1;
    header.msg_control = nullptr;
    header.msg_controllen = 1;
    header.msg_flags = 389475;

    ASSERT_EQ(-1, transport_bindings->sendmsg_func(&data_paths, &transport, &header)) << aeron_errmsg();
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2015, Nagoya University
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  * Neither the name of Autoware nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <ros/ros.h>
#include <geometry_msgs/Vector3Stamped.h>
#include <geometry_msgs/PoseStamped.h>
#include "vehicle_socket/CanInfo.h"

namespace
{
ros::Publisher g_vel_publisher;
ros::Publisher g_pose_publisher;

void callbackFromCanInfo(const vehicle_socket::CanInfoConstPtr &msg)
{
  geometry_msgs::Vector3Stamped vel;
  vel.header = msg->header;
  vel.vector.x = (msg->speed * 1000) / (60 * 60);  // km/h -> m/s
  g_vel_publisher.publish(vel);
}

void callbackFromPoseStamped(const geometry_msgs::PoseStampedConstPtr &msg)
{
  g_pose_publisher.publish(*msg);
}

void callbackFromVector3Stamped(const geometry_msgs::Vector3StampedConstPtr &msg)
{
  g_vel_publisher.publish(*msg);
}

}  // namespace

int main(int argc, char **argv)
{
  // set up ros
  ros::init(argc, argv, "vel_pose_mux");

  ros::NodeHandle nh;
  ros::NodeHandle private_nh("~");

  int32_t pose_mux_select, vel_mux_select;
  bool sim_mode;

  // setting params
  private_nh.param<int32_t>("pose_mux_select", pose_mux_select, int32_t(0));
  //ROS_INFO_STREAM("pose_mux_select : " << pose_mux_select);

  private_nh.param<int32_t>("vel_mux_select", vel_mux_select, int32_t(1));
  //ROS_INFO_STREAM("vel_mux_select : " << vel_mux_select);

  private_nh.param<bool>("sim_mode", sim_mode, false);
  //ROS_INFO_STREAM("sim_mode : " << sim_mode);

  // publish topic
  g_vel_publisher = nh.advertise<geometry_msgs::Vector3Stamped>("current_velocity", 10);
  g_pose_publisher = nh.advertise<geometry_msgs::PoseStamped>("current_pose", 10);

  // subscribe topic
  ros::Subscriber pose_subcscriber;
  ros::Subscriber vel_subcscriber;

  if (sim_mode)
  {
    vel_subcscriber = nh.subscribe("sim_velocity", 10, callbackFromVector3Stamped);
    pose_subcscriber = nh.subscribe("sim_pose", 10, callbackFromPoseStamped);
  }
  else
  {
    // pose
    switch (pose_mux_select)
    {
      case 0:  // ndt_localizer
      {
        pose_subcscriber = nh.subscribe("ndt_pose", 10, callbackFromPoseStamped);
        break;
      }
      case 1:  // gnss
      {
        pose_subcscriber = nh.subscribe("gnss_pose", 10, callbackFromPoseStamped);
        break;
      }
      default:
        break;
    }

    // velocity
    switch (vel_mux_select)
    {
      case 0:  // ndt_localizer
      {
        vel_subcscriber = nh.subscribe("estimated_vel", 10, callbackFromVector3Stamped);
        break;
      }
      case 1:  // CAN
      {
        vel_subcscriber = nh.subscribe("can_info", 10, callbackFromCanInfo);
        break;
      }
      default:
        break;
    }
  }

  ros::spin();

  return 0;
}
<commit_msg>Add specific namespace<commit_after>/*
 *  Copyright (c) 2015, Nagoya University
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  * Neither the name of Autoware nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <ros/ros.h>
#include <geometry_msgs/Vector3Stamped.h>
#include <geometry_msgs/PoseStamped.h>
#include "vehicle_socket/CanInfo.h"

namespace vel_pose_mux
{
ros::Publisher g_vel_publisher;
ros::Publisher g_pose_publisher;

void callbackFromCanInfo(const vehicle_socket::CanInfoConstPtr &msg)
{
  geometry_msgs::Vector3Stamped vel;
  vel.header = msg->header;
  vel.vector.x = (msg->speed * 1000) / (60 * 60);  // km/h -> m/s
  g_vel_publisher.publish(vel);
}

void callbackFromPoseStamped(const geometry_msgs::PoseStampedConstPtr &msg)
{
  g_pose_publisher.publish(*msg);
}

void callbackFromVector3Stamped(const geometry_msgs::Vector3StampedConstPtr &msg)
{
  g_vel_publisher.publish(*msg);
}

}  // namespace

int main(int argc, char **argv)
{
  // set up ros
  ros::init(argc, argv, "vel_pose_mux");

  ros::NodeHandle nh;
  ros::NodeHandle private_nh("~");

  int32_t pose_mux_select, vel_mux_select;
  bool sim_mode;

  // setting params
  private_nh.param<int32_t>("pose_mux_select", pose_mux_select, int32_t(0));
  //ROS_INFO_STREAM("pose_mux_select : " << pose_mux_select);

  private_nh.param<int32_t>("vel_mux_select", vel_mux_select, int32_t(1));
  //ROS_INFO_STREAM("vel_mux_select : " << vel_mux_select);

  private_nh.param<bool>("sim_mode", sim_mode, false);
  //ROS_INFO_STREAM("sim_mode : " << sim_mode);

  // publish topic
  g_vel_publisher = nh.advertise<geometry_msgs::Vector3Stamped>("current_velocity", 10);
  g_pose_publisher = nh.advertise<geometry_msgs::PoseStamped>("current_pose", 10);

  // subscribe topic
  ros::Subscriber pose_subcscriber;
  ros::Subscriber vel_subcscriber;

  if (sim_mode)
  {
    vel_subcscriber = nh.subscribe("sim_velocity", 10, callbackFromVector3Stamped);
    pose_subcscriber = nh.subscribe("sim_pose", 10, callbackFromPoseStamped);
  }
  else
  {
    // pose
    switch (pose_mux_select)
    {
      case 0:  // ndt_localizer
      {
        pose_subcscriber = nh.subscribe("ndt_pose", 10, callbackFromPoseStamped);
        break;
      }
      case 1:  // gnss
      {
        pose_subcscriber = nh.subscribe("gnss_pose", 10, callbackFromPoseStamped);
        break;
      }
      default:
        break;
    }

    // velocity
    switch (vel_mux_select)
    {
      case 0:  // ndt_localizer
      {
        vel_subcscriber = nh.subscribe("estimated_vel", 10, callbackFromVector3Stamped);
        break;
      }
      case 1:  // CAN
      {
        vel_subcscriber = nh.subscribe("can_info", 10, callbackFromCanInfo);
        break;
      }
      default:
        break;
    }
  }

  ros::spin();

  return 0;
}
<|endoftext|>


<commit_before>#include "telnetpp/detail/routing_visitor.hpp"
#include "telnetpp/options/naws/client.hpp"
#include "telnetpp/options/naws.hpp"
#include "telnetpp/protocol.hpp"
#include "telnetpp/detail/registration.hpp"
#include "expect_elements.hpp"
#include <gtest/gtest.h>

TEST(routing_visitor_test, text_routes_to_text_function)
{
    telnetpp::detail::command_router cmd_router;
    telnetpp::detail::negotiation_router neg_router;
    telnetpp::detail::subnegotiation_router sub_router;

    std::string text;
    std::string expected_text = "expected text";

    telnetpp::detail::routing_visitor visitor(
        [&text](auto &&new_text) -> std::vector<telnetpp::token>
        {
            text = new_text;
            return {};
        },
        cmd_router,
        neg_router,
        sub_router);

    telnetpp::element text_token(expected_text);
    boost::apply_visitor(visitor, text_token);

    ASSERT_EQ(expected_text, text);
}

TEST(routing_visitor_test, text_does_not_route_to_null_function)
{
    telnetpp::detail::command_router cmd_router;
    telnetpp::detail::negotiation_router neg_router;
    telnetpp::detail::subnegotiation_router sub_router;

    telnetpp::detail::routing_visitor visitor(
        nullptr,
        cmd_router,
        neg_router,
        sub_router);

    telnetpp::element text_token(telnetpp::element("text token"));
    boost::apply_visitor(visitor, text_token);
}

TEST(routing_visitor_test, command_routes_to_command_router)
{
    telnetpp::detail::command_router cmd_router;
    telnetpp::detail::negotiation_router neg_router;
    telnetpp::detail::subnegotiation_router sub_router;

    telnetpp::command cmd(0x00);
    telnetpp::command expected_command(telnetpp::ayt);

    cmd_router.register_route(expected_command,
        [&cmd](auto &&new_cmd) -> std::vector<telnetpp::token>
        {
            cmd = new_cmd;
            return {};
        });

    telnetpp::detail::routing_visitor visitor(
        [](auto &&) -> std::vector<telnetpp::token>
        {
            return {};
        },
        cmd_router,
        neg_router,
        sub_router);

    telnetpp::element cmd_token(expected_command);
    boost::apply_visitor(visitor, cmd_token);

    ASSERT_EQ(expected_command, cmd);
}

TEST(routing_visitor_test, negotiation_routes_to_negotiation_router)
{
    telnetpp::detail::command_router cmd_router;
    telnetpp::detail::negotiation_router neg_router;
    telnetpp::detail::subnegotiation_router sub_router;
    telnetpp::options::naws::client client;
    client.activate();

    bool state_changed = false;
    client.on_state_changed.connect(
        [&state_changed]() -> std::vector<telnetpp::token>
        {
            state_changed = true;
            return {};
        });

    telnetpp::detail::register_client_option(client, neg_router, sub_router);

    telnetpp::detail::routing_visitor visitor(
        [](auto &&) -> std::vector<telnetpp::token>
        {
            return {};
        },
        cmd_router,
        neg_router,
        sub_router);

    telnetpp::element neg_token(
        telnetpp::negotiation(
            telnetpp::will, telnetpp::options::naws::option));

    boost::apply_visitor(visitor, neg_token);

    ASSERT_EQ(true, state_changed);
    ASSERT_EQ(true, client.is_active());
}

TEST(routing_visitor_test, subnegotiation_routes_to_subnegotiation_router)
{
    telnetpp::detail::command_router cmd_router;
    telnetpp::detail::negotiation_router neg_router;
    telnetpp::detail::subnegotiation_router sub_router;
    telnetpp::options::naws::client client;
    client.activate();
    client.negotiate(telnetpp::will);

    telnetpp::u16 width = 0;
    telnetpp::u16 height = 0;
    client.on_window_size_changed.connect(
        [&width, &height](auto &&new_width, auto &&new_height)
            -> std::vector<telnetpp::token>
        {
            width = new_width;
            height = new_height;
            return {};
        });

    telnetpp::detail::register_route_from_subnegotiation_to_option(
        sub_router, client);

    telnetpp::detail::routing_visitor visitor(
        [](auto &&) -> std::vector<telnetpp::token>
        {
            return {};
        },
        cmd_router,
        neg_router,
        sub_router);

    telnetpp::element sub_token(
        telnetpp::subnegotiation(
            telnetpp::options::naws::option,
            {0, 80, 0, 24}));

    boost::apply_visitor(visitor, sub_token);

    telnetpp::u16 expected_width = 80;
    telnetpp::u16 expected_height = 24;

    ASSERT_EQ(expected_width, width);
    ASSERT_EQ(expected_height, height);
}

TEST(routing_visitor_test, subnegotiation_accumulates_responses)
{
    telnetpp::detail::command_router cmd_router;
    telnetpp::detail::negotiation_router neg_router;
    telnetpp::detail::subnegotiation_router sub_router;
    telnetpp::options::naws::client client;

    telnetpp::detail::register_client_option(client, neg_router, sub_router);

    client.on_window_size_changed.connect(
        [&client](auto &&, auto &&)
        {
            return client.deactivate();
        });

    telnetpp::detail::routing_visitor visitor(
        [](auto &&) -> std::vector<telnetpp::token>
        {
            return {};
        },
        cmd_router,
        neg_router,
        sub_router);

    client.activate();
    telnetpp::element do_negotiation_token(
        telnetpp::negotiation(telnetpp::will, telnetpp::options::naws::option));

    expect_elements(
        {},
        boost::apply_visitor(visitor, do_negotiation_token));

    telnetpp::element sub_token(
        telnetpp::subnegotiation(
            telnetpp::options::naws::option,
            {0, 80, 0, 24}));

    expect_elements({
        telnetpp::negotiation(
            telnetpp::dont, telnetpp::options::naws::option)
        },
        boost::apply_visitor(visitor, sub_token));
}
<commit_msg>Fix broken compile of routing test.<commit_after>#include "telnetpp/detail/routing_visitor.hpp"
#include "telnetpp/options/naws/client.hpp"
#include "telnetpp/protocol.hpp"
#include "telnetpp/detail/registration.hpp"
#include "expect_elements.hpp"
#include <gtest/gtest.h>

TEST(routing_visitor_test, text_routes_to_text_function)
{
    telnetpp::detail::command_router cmd_router;
    telnetpp::detail::negotiation_router neg_router;
    telnetpp::detail::subnegotiation_router sub_router;

    std::string text;
    std::string expected_text = "expected text";

    telnetpp::detail::routing_visitor visitor(
        [&text](auto &&new_text) -> std::vector<telnetpp::token>
        {
            text = new_text;
            return {};
        },
        cmd_router,
        neg_router,
        sub_router);

    telnetpp::element text_token(expected_text);
    boost::apply_visitor(visitor, text_token);

    ASSERT_EQ(expected_text, text);
}

TEST(routing_visitor_test, text_does_not_route_to_null_function)
{
    telnetpp::detail::command_router cmd_router;
    telnetpp::detail::negotiation_router neg_router;
    telnetpp::detail::subnegotiation_router sub_router;

    telnetpp::detail::routing_visitor visitor(
        nullptr,
        cmd_router,
        neg_router,
        sub_router);

    telnetpp::element text_token(telnetpp::element("text token"));
    boost::apply_visitor(visitor, text_token);
}

TEST(routing_visitor_test, command_routes_to_command_router)
{
    telnetpp::detail::command_router cmd_router;
    telnetpp::detail::negotiation_router neg_router;
    telnetpp::detail::subnegotiation_router sub_router;

    telnetpp::command cmd(0x00);
    telnetpp::command expected_command(telnetpp::ayt);

    cmd_router.register_route(expected_command,
        [&cmd](auto &&new_cmd) -> std::vector<telnetpp::token>
        {
            cmd = new_cmd;
            return {};
        });

    telnetpp::detail::routing_visitor visitor(
        [](auto &&) -> std::vector<telnetpp::token>
        {
            return {};
        },
        cmd_router,
        neg_router,
        sub_router);

    telnetpp::element cmd_token(expected_command);
    boost::apply_visitor(visitor, cmd_token);

    ASSERT_EQ(expected_command, cmd);
}

TEST(routing_visitor_test, negotiation_routes_to_negotiation_router)
{
    telnetpp::detail::command_router cmd_router;
    telnetpp::detail::negotiation_router neg_router;
    telnetpp::detail::subnegotiation_router sub_router;
    telnetpp::options::naws::client client;
    client.activate();

    bool state_changed = false;
    client.on_state_changed.connect(
        [&state_changed]() -> std::vector<telnetpp::token>
        {
            state_changed = true;
            return {};
        });

    telnetpp::detail::register_client_option(client, neg_router, sub_router);

    telnetpp::detail::routing_visitor visitor(
        [](auto &&) -> std::vector<telnetpp::token>
        {
            return {};
        },
        cmd_router,
        neg_router,
        sub_router);

    telnetpp::element neg_token(
        telnetpp::negotiation(telnetpp::will, client.option()));

    boost::apply_visitor(visitor, neg_token);

    ASSERT_EQ(true, state_changed);
    ASSERT_EQ(true, client.is_active());
}

TEST(routing_visitor_test, subnegotiation_routes_to_subnegotiation_router)
{
    telnetpp::detail::command_router cmd_router;
    telnetpp::detail::negotiation_router neg_router;
    telnetpp::detail::subnegotiation_router sub_router;
    telnetpp::options::naws::client client;
    client.activate();
    client.negotiate(telnetpp::will);

    telnetpp::u16 width = 0;
    telnetpp::u16 height = 0;
    client.on_window_size_changed.connect(
        [&width, &height](auto &&new_width, auto &&new_height)
            -> std::vector<telnetpp::token>
        {
            width = new_width;
            height = new_height;
            return {};
        });

    telnetpp::detail::register_route_from_subnegotiation_to_option(
        sub_router, client);

    telnetpp::detail::routing_visitor visitor(
        [](auto &&) -> std::vector<telnetpp::token>
        {
            return {};
        },
        cmd_router,
        neg_router,
        sub_router);

    telnetpp::element sub_token(
        telnetpp::subnegotiation(client.option(), {0, 80, 0, 24}));

    boost::apply_visitor(visitor, sub_token);

    telnetpp::u16 expected_width = 80;
    telnetpp::u16 expected_height = 24;

    ASSERT_EQ(expected_width, width);
    ASSERT_EQ(expected_height, height);
}

TEST(routing_visitor_test, subnegotiation_accumulates_responses)
{
    telnetpp::detail::command_router cmd_router;
    telnetpp::detail::negotiation_router neg_router;
    telnetpp::detail::subnegotiation_router sub_router;
    telnetpp::options::naws::client client;

    telnetpp::detail::register_client_option(client, neg_router, sub_router);

    client.on_window_size_changed.connect(
        [&client](auto &&, auto &&)
        {
            return client.deactivate();
        });

    telnetpp::detail::routing_visitor visitor(
        [](auto &&) -> std::vector<telnetpp::token>
        {
            return {};
        },
        cmd_router,
        neg_router,
        sub_router);

    client.activate();
    telnetpp::element do_negotiation_token(
        telnetpp::negotiation(telnetpp::will, client.option()));

    expect_elements(
        {},
        boost::apply_visitor(visitor, do_negotiation_token));

    telnetpp::element sub_token(
        telnetpp::subnegotiation(client.option(), {0, 80, 0, 24}));

    expect_elements({
        telnetpp::negotiation(
            telnetpp::dont, client.option())
        },
        boost::apply_visitor(visitor, sub_token));
}
<|endoftext|>


<commit_before>#ifndef __STAN__PROB__DISTRIBUTIONS__MULTI_STUDENT_T_HPP__
#define __STAN__PROB__DISTRIBUTIONS__MULTI_STUDENT_T_HPP__

#include <cstdlib>

#include <boost/math/special_functions/gamma.hpp>
#include <boost/math/special_functions/fpclassify.hpp>

#include <stan/math/error_handling.hpp>
#include <stan/math/matrix_error_handling.hpp>
#include <stan/prob/constants.hpp>
#include <stan/prob/traits.hpp>
#include <stan/prob/distributions/multivariate/continuous/multi_normal.hpp>
#include <stan/prob/distributions/univariate/continuous/inv_gamma.hpp>

#include <boost/random/variate_generator.hpp>

namespace stan {

  namespace prob {

    /**
     * Return the log of the multivariate Student t distribution
     * at the specified arguments.
     *
     * @tparam propto Carry out calculations up to a proportion
     */
    template <bool propto,
              typename T_y, typename T_dof, typename T_loc, typename T_scale>
    typename boost::math::tools::promote_args<T_y,T_dof,T_loc,T_scale>::type
    multi_student_t_log(const Eigen::Matrix<T_y,Eigen::Dynamic,1>& y,
                        const T_dof& nu,
                        const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
                        const
                        Eigen::Matrix<T_scale,
                                      Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
      static const char* function = "stan::prob::multi_student_t(%1%)";

      using stan::math::check_size_match;
      using stan::math::check_finite;
      using stan::math::check_not_nan;
      using stan::math::check_symmetric;
      using stan::math::check_positive;
      using boost::math::tools::promote_args;
      using boost::math::lgamma;
      using stan::math::log_determinant_ldlt;
      using stan::math::mdivide_left_ldlt;
      using stan::math::LDLT_factor;

      typename promote_args<T_y,T_dof,T_loc,T_scale>::type lp(0.0);
      if (!check_size_match(function,
          y.size(), "Size of random variable",
          mu.size(), "size of location parameter",
          &lp))
        return lp;
      if (!check_size_match(function,
          y.size(), "Size of random variable",
          Sigma.rows(), "rows of scale parameter",
          &lp))
        return lp;
      if (!check_size_match(function,
          y.size(), "Size of random variable",
          Sigma.cols(), "columns of scale parameter",
          &lp))
        return lp;
      if (!check_finite(function, mu, "Location parameter", &lp))
        return lp;
      if (!check_not_nan(function, y, "Random variable", &lp))
        return lp;
      if (!check_symmetric(function, Sigma, "Scale parameter", &lp))
        return lp;

      LDLT_factor<T_scale,Eigen::Dynamic,Eigen::Dynamic> ldlt_Sigma(Sigma);
      if (!ldlt_Sigma.success()) {
        std::ostringstream message;
        message << "Scale matrix is not positive definite. "
        << "Sigma(0,0) is %1%.";
        std::string str(message.str());
        stan::math::dom_err(function,Sigma(0,0),"Scale matrix",str.c_str(),"",&lp);
        return lp;
      }

      // allows infinities
      if (!check_not_nan(function, nu,
                         "Degrees of freedom parameter", &lp))
        return lp;
      if (!check_positive(function, nu,
                          "Degrees of freedom parameter", &lp))
        return lp;

      using boost::math::isinf;

      if (isinf(nu)) // already checked nu > 0
        return multi_normal_log(y,mu,Sigma);

      double d = y.size();

      if (include_summand<propto,T_dof>::value) {
        lp += lgamma(0.5 * (nu + d));
        lp -= lgamma(0.5 * nu);
        lp -= (0.5 * d) * log(nu);
      }

      if (include_summand<propto>::value)
        lp -= (0.5 * d) * LOG_PI;

      using stan::math::multiply;
      using stan::math::dot_product;
      using stan::math::subtract;
      using Eigen::Array;

      if (include_summand<propto,T_scale>::value) {
        lp -= 0.5*log_determinant_ldlt(ldlt_Sigma);
      }

      if (include_summand<propto,T_y,T_dof,T_loc,T_scale>::value) {

        Eigen::Matrix<typename promote_args<T_y,T_loc>::type,
                      Eigen::Dynamic,
                      1> y_minus_mu = subtract(y,mu);
        Eigen::Matrix<typename promote_args<T_scale,T_y,T_loc>::type,
                      Eigen::Dynamic,
                      1> invSigma_dy = mdivide_left_ldlt(ldlt_Sigma, y_minus_mu);
        lp -= 0.5
          * (nu + d)
          * log(1.0 + dot_product(y_minus_mu,invSigma_dy) / nu);
      }
      return lp;
    }

    template <typename T_y, typename T_dof, typename T_loc, typename T_scale>
    inline
    typename boost::math::tools::promote_args<T_y,T_dof,T_loc,T_scale>::type
    multi_student_t_log(const Eigen::Matrix<T_y,Eigen::Dynamic,1>& y,
                        const T_dof& nu,
                        const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
                        const
                        Eigen::Matrix<T_scale,
                                      Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
      return multi_student_t_log<false>(y,nu,mu,Sigma);
    }

    template <class RNG>
    inline Eigen::VectorXd
    multi_student_t_rng(const double nu,
                        const Eigen::Matrix<double,Eigen::Dynamic,1>& mu,
                        const Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>& s,
                     RNG& rng) {

      static const char* function = "stan::prob::multi_student_t_rng(%1%)";

      using stan::math::check_finite;
      using stan::math::check_not_nan;
      using stan::math::check_symmetric;
      using stan::math::check_positive;

      check_finite(function, mu, "Location parameter");
      check_symmetric(function, s, "Scale parameter");
      check_not_nan(function, nu,
                    "Degrees of freedom parameter");
      check_positive(function, nu,
                     "Degrees of freedom parameter");

      Eigen::VectorXd z(s.cols());
      z.setZero();

      double w = stan::prob::inv_gamma_rng(nu / 2, nu / 2, rng);
      return mu + std::sqrt(w) * stan::prob::multi_normal_rng(z, s, rng);
    }
  }
}
#endif
<commit_msg>Use trace_inv_quad_form_ldlt() in multi_student_t.<commit_after>#ifndef __STAN__PROB__DISTRIBUTIONS__MULTI_STUDENT_T_HPP__
#define __STAN__PROB__DISTRIBUTIONS__MULTI_STUDENT_T_HPP__

#include <cstdlib>

#include <boost/math/special_functions/gamma.hpp>
#include <boost/math/special_functions/fpclassify.hpp>

#include <stan/math/error_handling.hpp>
#include <stan/math/matrix_error_handling.hpp>
#include <stan/prob/constants.hpp>
#include <stan/prob/traits.hpp>
#include <stan/prob/distributions/multivariate/continuous/multi_normal.hpp>
#include <stan/prob/distributions/univariate/continuous/inv_gamma.hpp>

#include <boost/random/variate_generator.hpp>

namespace stan {

  namespace prob {

    /**
     * Return the log of the multivariate Student t distribution
     * at the specified arguments.
     *
     * @tparam propto Carry out calculations up to a proportion
     */
    template <bool propto,
              typename T_y, typename T_dof, typename T_loc, typename T_scale>
    typename boost::math::tools::promote_args<T_y,T_dof,T_loc,T_scale>::type
    multi_student_t_log(const Eigen::Matrix<T_y,Eigen::Dynamic,1>& y,
                        const T_dof& nu,
                        const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
                        const
                        Eigen::Matrix<T_scale,
                                      Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
      static const char* function = "stan::prob::multi_student_t(%1%)";

      using stan::math::check_size_match;
      using stan::math::check_finite;
      using stan::math::check_not_nan;
      using stan::math::check_symmetric;
      using stan::math::check_positive;
      using boost::math::tools::promote_args;
      using boost::math::lgamma;
      using stan::math::log_determinant_ldlt;
      using stan::math::LDLT_factor;

      typename promote_args<T_y,T_dof,T_loc,T_scale>::type lp(0.0);
      if (!check_size_match(function,
          y.size(), "Size of random variable",
          mu.size(), "size of location parameter",
          &lp))
        return lp;
      if (!check_size_match(function,
          y.size(), "Size of random variable",
          Sigma.rows(), "rows of scale parameter",
          &lp))
        return lp;
      if (!check_size_match(function,
          y.size(), "Size of random variable",
          Sigma.cols(), "columns of scale parameter",
          &lp))
        return lp;
      if (!check_finite(function, mu, "Location parameter", &lp))
        return lp;
      if (!check_not_nan(function, y, "Random variable", &lp))
        return lp;
      if (!check_symmetric(function, Sigma, "Scale parameter", &lp))
        return lp;

      LDLT_factor<T_scale,Eigen::Dynamic,Eigen::Dynamic> ldlt_Sigma(Sigma);
      if (!ldlt_Sigma.success()) {
        std::ostringstream message;
        message << "Scale matrix is not positive definite. "
        << "Sigma(0,0) is %1%.";
        std::string str(message.str());
        stan::math::dom_err(function,Sigma(0,0),"Scale matrix",str.c_str(),"",&lp);
        return lp;
      }

      // allows infinities
      if (!check_not_nan(function, nu,
                         "Degrees of freedom parameter", &lp))
        return lp;
      if (!check_positive(function, nu,
                          "Degrees of freedom parameter", &lp))
        return lp;

      using boost::math::isinf;

      if (isinf(nu)) // already checked nu > 0
        return multi_normal_log(y,mu,Sigma);

      double d = y.size();

      if (include_summand<propto,T_dof>::value) {
        lp += lgamma(0.5 * (nu + d));
        lp -= lgamma(0.5 * nu);
        lp -= (0.5 * d) * log(nu);
      }

      if (include_summand<propto>::value)
        lp -= (0.5 * d) * LOG_PI;

      using stan::math::multiply;
      using stan::math::dot_product;
      using stan::math::subtract;
      using Eigen::Array;

      if (include_summand<propto,T_scale>::value) {
        lp -= 0.5*log_determinant_ldlt(ldlt_Sigma);
      }

      if (include_summand<propto,T_y,T_dof,T_loc,T_scale>::value) {

        Eigen::Matrix<typename promote_args<T_y,T_loc>::type,
                      Eigen::Dynamic,
                      1> y_minus_mu = subtract(y,mu);
        lp -= 0.5
          * (nu + d)
          * log(1.0 + trace_inv_quad_form_ldlt(ldlt_Sigma,y_minus_mu) / nu);
      }
      return lp;
    }

    template <typename T_y, typename T_dof, typename T_loc, typename T_scale>
    inline
    typename boost::math::tools::promote_args<T_y,T_dof,T_loc,T_scale>::type
    multi_student_t_log(const Eigen::Matrix<T_y,Eigen::Dynamic,1>& y,
                        const T_dof& nu,
                        const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
                        const
                        Eigen::Matrix<T_scale,
                                      Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
      return multi_student_t_log<false>(y,nu,mu,Sigma);
    }

    template <class RNG>
    inline Eigen::VectorXd
    multi_student_t_rng(const double nu,
                        const Eigen::Matrix<double,Eigen::Dynamic,1>& mu,
                        const Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>& s,
                     RNG& rng) {

      static const char* function = "stan::prob::multi_student_t_rng(%1%)";

      using stan::math::check_finite;
      using stan::math::check_not_nan;
      using stan::math::check_symmetric;
      using stan::math::check_positive;

      check_finite(function, mu, "Location parameter");
      check_symmetric(function, s, "Scale parameter");
      check_not_nan(function, nu,
                    "Degrees of freedom parameter");
      check_positive(function, nu,
                     "Degrees of freedom parameter");

      Eigen::VectorXd z(s.cols());
      z.setZero();

      double w = stan::prob::inv_gamma_rng(nu / 2, nu / 2, rng);
      return mu + std::sqrt(w) * stan::prob::multi_normal_rng(z, s, rng);
    }
  }
}
#endif
<|endoftext|>


<commit_before>#include "catch.hpp"

#include <iostream>
#include <exception> // std::bad_function_call, std::runtime_error
#include <thread> // std::thread, std::this_thread::yield
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
#include <functional> // std::function

class EventThreader {
public:
    std::condition_variable event_waiter;
    std::condition_variable calling_waiter;
    std::unique_lock<std::mutex>* event_lock = nullptr;
    std::unique_lock<std::mutex>* calling_lock = nullptr;
    std::mutex mtx;
    std::mutex allocation_mtx;
    std::thread event_thread;
    void switchToCallingThread();
    bool require_switch_from_event = false;
    std::function<void(void)> event_cleanup;
    std::runtime_error* exception_from_the_event_thread;
    void deallocate();
public:
    EventThreader(std::function<void (std::function<void (void)>)> func);
    ~EventThreader();
    void switchToEventThread();
    void join();
    void setEventCleanup(std::function<void(void)>);
};

EventThreader::EventThreader(std::function<void (std::function<void (void)>)> func) {
}

EventThreader::~EventThreader() {
}

void EventThreader::deallocate() {
}

void EventThreader::switchToCallingThread() {
}

void EventThreader::switchToEventThread() {
}

void EventThreader::join() {
}

void EventThreader::setEventCleanup(std::function<void(void)> cleanup) {
    event_cleanup = cleanup;
}

TEST_CASE( "EventThreader", "[EventThreader]" ) {
	std::stringstream ss;

	SECTION("Finding the error") {
		EventThreader et([](std::function<void(void)> f){});
		// class variables
	    std::mutex mtx;
	    bool require_switch_from_event = false;
	    std::function<void(void)> event_cleanup;
	    std::runtime_error* exception_from_the_event_thread;

	    // class functions

		auto deallocate = [&]() {
		    et.allocation_mtx.lock();
			if (exception_from_the_event_thread != nullptr) {
				delete exception_from_the_event_thread;
				exception_from_the_event_thread = nullptr;
			}
			if (et.calling_lock != nullptr) {
				delete et.calling_lock;
				et.calling_lock = nullptr;
			}
			if (et.event_lock != nullptr) {
				delete et.event_lock;
				et.event_lock = nullptr;
			}
			et.allocation_mtx.unlock();
		};

		auto join = [&]() {
		    et.allocation_mtx.lock();
		    delete et.calling_lock; // remove lock on this thread, allow event to run
		    et.calling_lock = nullptr;
		    et.allocation_mtx.unlock();
		    if (et.event_lock != nullptr) {
		        et.event_waiter.notify_one();
		        std::this_thread::yield();
		    }
		    et.event_thread.join();
		    if (exception_from_the_event_thread != nullptr) {
		        /* an exception occured */
		        std::runtime_error e_copy(exception_from_the_event_thread->what());
		        et.allocation_mtx.lock();
		        delete exception_from_the_event_thread;
		        exception_from_the_event_thread = nullptr;
		        et.allocation_mtx.unlock();
		        throw e_copy;
		    }
		    deallocate();
		};

	    auto switchToCallingThread = [&]() {
		    if (!require_switch_from_event) {
		        throw std::runtime_error("switch to calling not matched with a switch to event");
		    }
		    require_switch_from_event = false;
		    /* switch to calling */
		    et.calling_waiter.notify_one();
		    std::this_thread::yield();
		    et.event_waiter.wait(*(et.event_lock));
		    std::this_thread::yield();
		    /* back from calling */
		};

		auto switchToEventThread= [&]() {
		    if (require_switch_from_event) {
		        throw std::runtime_error("switch to event not matched with a switch to calling");
		    }
		    require_switch_from_event = true;
		    /* switch to event */
		    et.event_waiter.notify_one();
		    std::this_thread::yield();
		    et.calling_waiter.wait(*et.calling_lock);
		    std::this_thread::yield();
		    /* back from event */
		    if (require_switch_from_event) {
		        /* this exception is thrown if switchToCallingThread() was not used, which means the thread ended */
		        join();
		    }
		};

		/* Example of most basic use */
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			for(int i = 0; i < 100; i++) { ss << "*"; }
			switchToMainThread();
			for(int i = 0; i < 50; i++) { ss << "*"; }
			switchToMainThread();
		};
		std::function<void (std::function<void (void)>)> func = f;

		// Start construction
		et.allocation_mtx.lock();
	    exception_from_the_event_thread = nullptr;
	    et.event_lock = nullptr;
	    et.calling_lock = nullptr;
	    et.calling_lock = new std::unique_lock<std::mutex>(mtx);
	    et.allocation_mtx.unlock();
	    exception_from_the_event_thread = nullptr;

	    event_cleanup = [](){}; // empty function
	    auto event = [&](){
	        /* mtx force switch to calling - blocked by the mutex */
	        et.allocation_mtx.lock();
	        et.event_lock = new std::unique_lock<std::mutex>(mtx);
	        et.allocation_mtx.unlock();

	        et.calling_waiter.notify_one();
	        et.event_waiter.wait(*(et.event_lock));
	        std::this_thread::yield();
	        try {
	            func([&](){switchToCallingThread();});
	            if (require_switch_from_event) { // the event has ended, but not ready to join
	                // rejoin the calling thread after dealing with this exception
	                throw std::runtime_error("switch to event not matched with a switch to calling");
	            }
	        } catch (const std::runtime_error &e) {
	            /* report the exception to the calling thread */
	            et.allocation_mtx.lock();
	            exception_from_the_event_thread = new std::runtime_error(e);
	            et.allocation_mtx.unlock();
	            et.calling_waiter.notify_one();
	            std::this_thread::yield();
	        }
	        et.allocation_mtx.lock();
	        delete et.event_lock;
	        et.event_lock = nullptr;
	        et.allocation_mtx.unlock();
	        event_cleanup();
	    };

	    et.event_thread = std::thread(event);
	    std::this_thread::yield();
	    et.calling_waiter.wait(*(et.calling_lock));
	    std::this_thread::yield();
		// End constuction
		//EventThreader et(f);
		switchToEventThread();
		for(int i = 0; i < 75; i++) { ss << "$"; }
		switchToEventThread();
		for(int i = 0; i < 25; i++) { ss << "$"; }
		join();

		/* Generate what the result should look like */
		std::string requirement;
		for(int i = 0; i < 100; i++) { requirement += "*"; }
		for(int i = 0; i < 75; i++) { requirement += "$"; }
		for(int i = 0; i < 50; i++) { requirement += "*"; }
		for(int i = 0; i < 25; i++) { requirement += "$"; }
		REQUIRE( requirement == ss.str());

		deallocate();

	}

	/* SECTION("Abitrary use") {
		// Example of most basic use
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			for(int i = 0; i < 100; i++) { ss << "*"; }
			switchToMainThread();
			for(int i = 0; i < 50; i++) { ss << "*"; }
			switchToMainThread();
		};
		EventThreader et(f);
		switchToEventThread();
		for(int i = 0; i < 75; i++) { ss << "$"; }
		switchToEventThread();
		for(int i = 0; i < 25; i++) { ss << "$"; }
		join();

		// Generate what the result should look like
		std::string requirement;
		for(int i = 0; i < 100; i++) { requirement += "*"; }
		for(int i = 0; i < 75; i++) { requirement += "$"; }
		for(int i = 0; i < 50; i++) { requirement += "*"; }
		for(int i = 0; i < 25; i++) { requirement += "$"; }
		REQUIRE( requirement == ss.str());

	} */
}
<commit_msg>moving lock ptrs<commit_after>#include "catch.hpp"

#include <iostream>
#include <exception> // std::bad_function_call, std::runtime_error
#include <thread> // std::thread, std::this_thread::yield
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
#include <functional> // std::function

class EventThreader {
public:
    std::condition_variable event_waiter;
    std::condition_variable calling_waiter;
    std::unique_lock<std::mutex>* event_lock = nullptr;
    std::unique_lock<std::mutex>* calling_lock = nullptr;
    std::mutex mtx;
    std::mutex allocation_mtx;
    std::thread event_thread;
    void switchToCallingThread();
    bool require_switch_from_event = false;
    std::function<void(void)> event_cleanup;
    std::runtime_error* exception_from_the_event_thread;
    void deallocate();
public:
    EventThreader(std::function<void (std::function<void (void)>)> func);
    ~EventThreader();
    void switchToEventThread();
    void join();
    void setEventCleanup(std::function<void(void)>);
};

EventThreader::EventThreader(std::function<void (std::function<void (void)>)> func) {
}

EventThreader::~EventThreader() {
}

void EventThreader::deallocate() {
}

void EventThreader::switchToCallingThread() {
}

void EventThreader::switchToEventThread() {
}

void EventThreader::join() {
}

void EventThreader::setEventCleanup(std::function<void(void)> cleanup) {
    event_cleanup = cleanup;
}

TEST_CASE( "EventThreader", "[EventThreader]" ) {
	std::stringstream ss;

	SECTION("Finding the error") {
		EventThreader et([](std::function<void(void)> f){});
		// class variables
	    std::mutex mtx;
	    std::function<void(void)> event_cleanup;
	    std::runtime_error* exception_from_the_event_thread;

	    // class functions

		auto deallocate = [&]() {
		    et.allocation_mtx.lock();
			if (exception_from_the_event_thread != nullptr) {
				delete exception_from_the_event_thread;
				exception_from_the_event_thread = nullptr;
			}
			if (et.calling_lock != nullptr) {
				delete et.calling_lock;
				et.calling_lock = nullptr;
			}
			if (et.event_lock != nullptr) {
				delete et.event_lock;
				et.event_lock = nullptr;
			}
			et.allocation_mtx.unlock();
		};

		auto join = [&]() {
		    et.allocation_mtx.lock();
		    delete et.calling_lock; // remove lock on this thread, allow event to run
		    et.calling_lock = nullptr;
		    et.allocation_mtx.unlock();
		    if (et.event_lock != nullptr) {
		        et.event_waiter.notify_one();
		        std::this_thread::yield();
		    }
		    et.event_thread.join();
		    if (exception_from_the_event_thread != nullptr) {
		        /* an exception occured */
		        std::runtime_error e_copy(exception_from_the_event_thread->what());
		        et.allocation_mtx.lock();
		        delete exception_from_the_event_thread;
		        exception_from_the_event_thread = nullptr;
		        et.allocation_mtx.unlock();
		        throw e_copy;
		    }
		    deallocate();
		};

	    auto switchToCallingThread = [&]() {
		    if (!et.require_switch_from_event) {
		        throw std::runtime_error("switch to calling not matched with a switch to event");
		    }
		    et.require_switch_from_event = false;
		    /* switch to calling */
		    et.calling_waiter.notify_one();
		    std::this_thread::yield();
		    et.event_waiter.wait(*(et.event_lock));
		    std::this_thread::yield();
		    /* back from calling */
		};

		auto switchToEventThread= [&]() {
		    if (et.require_switch_from_event) {
		        throw std::runtime_error("switch to event not matched with a switch to calling");
		    }
		    et.require_switch_from_event = true;
		    /* switch to event */
		    et.event_waiter.notify_one();
		    std::this_thread::yield();
		    et.calling_waiter.wait(*et.calling_lock);
		    std::this_thread::yield();
		    /* back from event */
		    if (et.require_switch_from_event) {
		        /* this exception is thrown if switchToCallingThread() was not used, which means the thread ended */
		        join();
		    }
		};

		/* Example of most basic use */
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			for(int i = 0; i < 100; i++) { ss << "*"; }
			switchToMainThread();
			for(int i = 0; i < 50; i++) { ss << "*"; }
			switchToMainThread();
		};
		std::function<void (std::function<void (void)>)> func = f;

		// Start construction
		et.allocation_mtx.lock();
	    exception_from_the_event_thread = nullptr;
	    et.event_lock = nullptr;
	    et.calling_lock = nullptr;
	    et.calling_lock = new std::unique_lock<std::mutex>(mtx);
	    et.allocation_mtx.unlock();
	    exception_from_the_event_thread = nullptr;

	    event_cleanup = [](){}; // empty function
	    auto event = [&](){
	        /* mtx force switch to calling - blocked by the mutex */
	        et.allocation_mtx.lock();
	        et.event_lock = new std::unique_lock<std::mutex>(mtx);
	        et.allocation_mtx.unlock();

	        et.calling_waiter.notify_one();
	        et.event_waiter.wait(*(et.event_lock));
	        std::this_thread::yield();
	        try {
	            func([&](){switchToCallingThread();});
	            if (et.require_switch_from_event) { // the event has ended, but not ready to join
	                // rejoin the calling thread after dealing with this exception
	                throw std::runtime_error("switch to event not matched with a switch to calling");
	            }
	        } catch (const std::runtime_error &e) {
	            /* report the exception to the calling thread */
	            et.allocation_mtx.lock();
	            exception_from_the_event_thread = new std::runtime_error(e);
	            et.allocation_mtx.unlock();
	            et.calling_waiter.notify_one();
	            std::this_thread::yield();
	        }
	        et.allocation_mtx.lock();
	        delete et.event_lock;
	        et.event_lock = nullptr;
	        et.allocation_mtx.unlock();
	        event_cleanup();
	    };

	    et.event_thread = std::thread(event);
	    std::this_thread::yield();
	    et.calling_waiter.wait(*(et.calling_lock));
	    std::this_thread::yield();
		// End constuction
		//EventThreader et(f);
		switchToEventThread();
		for(int i = 0; i < 75; i++) { ss << "$"; }
		switchToEventThread();
		for(int i = 0; i < 25; i++) { ss << "$"; }
		join();

		/* Generate what the result should look like */
		std::string requirement;
		for(int i = 0; i < 100; i++) { requirement += "*"; }
		for(int i = 0; i < 75; i++) { requirement += "$"; }
		for(int i = 0; i < 50; i++) { requirement += "*"; }
		for(int i = 0; i < 25; i++) { requirement += "$"; }
		REQUIRE( requirement == ss.str());

		deallocate();

	}

	/* SECTION("Abitrary use") {
		// Example of most basic use
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			for(int i = 0; i < 100; i++) { ss << "*"; }
			switchToMainThread();
			for(int i = 0; i < 50; i++) { ss << "*"; }
			switchToMainThread();
		};
		EventThreader et(f);
		switchToEventThread();
		for(int i = 0; i < 75; i++) { ss << "$"; }
		switchToEventThread();
		for(int i = 0; i < 25; i++) { ss << "$"; }
		join();

		// Generate what the result should look like
		std::string requirement;
		for(int i = 0; i < 100; i++) { requirement += "*"; }
		for(int i = 0; i < 75; i++) { requirement += "$"; }
		for(int i = 0; i < 50; i++) { requirement += "*"; }
		for(int i = 0; i < 25; i++) { requirement += "$"; }
		REQUIRE( requirement == ss.str());

	} */
}
<|endoftext|>