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

#include <modules/globebrowsing/src/globetranslation.h>

#include <modules/globebrowsing/globebrowsingmodule.h>
#include <modules/globebrowsing/src/renderableglobe.h>
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
#include <openspace/engine/globals.h>
#include <openspace/engine/moduleengine.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/query/query.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/logging/logmanager.h>

namespace {
    constexpr openspace::properties::Property::PropertyInfo GlobeInfo = {
        "Globe",
        "Attached Globe",
        "The globe on which the longitude/latitude is specified"
    };

    constexpr openspace::properties::Property::PropertyInfo LongitudeInfo = {
        "Longitude",
        "Longitude",
        "The longitude of the location on the globe's surface. The value can range from "
        "-180 to 180, with negative values representing the western hemisphere of the "
        "globe. The default value is 0.0"
    };

    constexpr openspace::properties::Property::PropertyInfo LatitudeInfo = {
        "Latitude",
        "Latitude",
        "The latitude of the location on the globe's surface. The value can range from "
        "-90 to 90, with negative values representing the southern hemisphere of the "
        "globe. The default value is 0.0"
    };

    constexpr openspace::properties::Property::PropertyInfo AltitudeInfo = {
        "Altitude",
        "Altitude",
        "The altitude in meters. "
        "If the 'UseHeightmap' property is 'true', this is an offset from the actual "
        "surface of the globe. If not, this is an offset from the reference ellipsoid."
        "The default value is 0.0"
    };

    constexpr openspace::properties::Property::PropertyInfo UseHeightmapInfo = {
        "UseHeightmap",
        "Use Heightmap",
        "If this value is 'true', the altitude specified in 'Altitude' will be treated "
        "as an offset from the heightmap. Otherwise, it will be an offset from the "
        "globe's reference ellipsoid. The default value is 'false'."
    };

    struct [[codegen::Dictionary(GlobeTranslation)]] Parameters {
        // [[codegen::verbatim(GlobeInfo.description)]]
        std::string globe
            [[codegen::annotation("A valid scene graph node with a RenderableGlobe")]];

        // [[codegen::verbatim(LongitudeInfo.description)]]
        std::optional<double> longitude;

        // [[codegen::verbatim(LatitudeInfo.description)]]
        std::optional<double> latitude;

        // [[codegen::verbatim(AltitudeInfo.description)]]
        std::optional<double> altitude;

        // [[codegen::verbatim(UseHeightmapInfo.description)]]
        std::optional<bool> useHeightmap;
    };
#include "globetranslation_codegen.cpp"
} // namespace

namespace openspace::globebrowsing {

documentation::Documentation GlobeTranslation::Documentation() {
    return codegen::doc<Parameters>("space_translation_globetranslation");
}

GlobeTranslation::GlobeTranslation(const ghoul::Dictionary& dictionary)
    : _globe(GlobeInfo)
    , _longitude(LongitudeInfo, 0.0, -180.0, 180.0)
    , _latitude(LatitudeInfo, 0.0, -90.0, 90.0)
    , _altitude(AltitudeInfo, 0.0, 0.0, 1e12)
    , _useHeightmap(UseHeightmapInfo, false)
{
    const Parameters p = codegen::bake<Parameters>(dictionary);

    _globe = p.globe;
    _globe.onChange([this]() {
        fillAttachedNode();
        _positionIsDirty = true;
    });

    _longitude = p.longitude.value_or(_longitude);
    _longitude.onChange([this]() { _positionIsDirty = true; });
    addProperty(_longitude);

    _latitude = p.latitude.value_or(_latitude);
    _latitude.onChange([this]() { _positionIsDirty = true; });
    addProperty(_latitude);

    _altitude = p.altitude.value_or(_altitude);
    _altitude.onChange([this]() { _positionIsDirty = true; });
    addProperty(_altitude);

    _useHeightmap = p.useHeightmap.value_or(_useHeightmap);
    _useHeightmap.onChange([this]() { _positionIsDirty = true; });
    addProperty(_useHeightmap);
}

void GlobeTranslation::fillAttachedNode() {
    SceneGraphNode* n = sceneGraphNode(_globe);
    if (n->renderable() && dynamic_cast<RenderableGlobe*>(n->renderable())) {
        _attachedNode = dynamic_cast<RenderableGlobe*>(n->renderable());
    }
    else {
        LERRORC(
            "GlobeTranslation",
            "Could not set attached node as it does not have a RenderableGlobe"
        );
        if (_attachedNode) {
            // Reset the globe name to it's previous name
            _globe = _attachedNode->identifier();
        }
    }
}

glm::dvec3 GlobeTranslation::position(const UpdateData&) const {
    if (!_attachedNode) {
        // @TODO(abock): The const cast should be removed on a redesign of the translation
        //               to make the position function not constant. Const casting this
        //               away is fine as the factories that create the translations don't
        //               create them as constant objects
        const_cast<GlobeTranslation*>(this)->fillAttachedNode();
        _positionIsDirty = true;
    }

    if (_useHeightmap) {
        // If we use the heightmap, we have to compute the height every frame
        _positionIsDirty = true;
    }

    if (!_positionIsDirty) {
        return _position;
    }

    GlobeBrowsingModule& mod = *(global::moduleEngine->module<GlobeBrowsingModule>());

    if (_useHeightmap) {
        glm::vec3 groundPos = mod.cartesianCoordinatesFromGeo(
            *_attachedNode,
            _latitude,
            _longitude,
            0.0
        );

        SurfacePositionHandle h =
            _attachedNode->calculateSurfacePositionHandle(groundPos);

        _position = mod.cartesianCoordinatesFromGeo(
            *_attachedNode,
            _latitude,
            _longitude,
            h.heightToSurface + _altitude
        );
        return _position;
    }
    else {
        _position = mod.cartesianCoordinatesFromGeo(
            *_attachedNode,
            _latitude,
            _longitude,
            _altitude
        );
        _positionIsDirty = false;
        return _position;
    }
}

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

#include <modules/globebrowsing/src/globetranslation.h>

#include <modules/globebrowsing/globebrowsingmodule.h>
#include <modules/globebrowsing/src/renderableglobe.h>
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
#include <openspace/engine/globals.h>
#include <openspace/engine/moduleengine.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/query/query.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/logging/logmanager.h>

namespace {
    constexpr openspace::properties::Property::PropertyInfo GlobeInfo = {
        "Globe",
        "Attached Globe",
        "The globe on which the longitude/latitude is specified"
    };

    constexpr openspace::properties::Property::PropertyInfo LongitudeInfo = {
        "Longitude",
        "Longitude",
        "The longitude of the location on the globe's surface. The value can range from "
        "-180 to 180, with negative values representing the western hemisphere of the "
        "globe. The default value is 0.0"
    };

    constexpr openspace::properties::Property::PropertyInfo LatitudeInfo = {
        "Latitude",
        "Latitude",
        "The latitude of the location on the globe's surface. The value can range from "
        "-90 to 90, with negative values representing the southern hemisphere of the "
        "globe. The default value is 0.0"
    };

    constexpr openspace::properties::Property::PropertyInfo AltitudeInfo = {
        "Altitude",
        "Altitude",
        "The altitude in meters. "
        "If the 'UseHeightmap' property is 'true', this is an offset from the actual "
        "surface of the globe. If not, this is an offset from the reference ellipsoid."
        "The default value is 0.0"
    };

    constexpr openspace::properties::Property::PropertyInfo UseHeightmapInfo = {
        "UseHeightmap",
        "Use Heightmap",
        "If this value is 'true', the altitude specified in 'Altitude' will be treated "
        "as an offset from the heightmap. Otherwise, it will be an offset from the "
        "globe's reference ellipsoid. The default value is 'false'."
    };

    struct [[codegen::Dictionary(GlobeTranslation)]] Parameters {
        // [[codegen::verbatim(GlobeInfo.description)]]
        std::string globe
            [[codegen::annotation("A valid scene graph node with a RenderableGlobe")]];

        // [[codegen::verbatim(LongitudeInfo.description)]]
        std::optional<double> longitude;

        // [[codegen::verbatim(LatitudeInfo.description)]]
        std::optional<double> latitude;

        // [[codegen::verbatim(AltitudeInfo.description)]]
        std::optional<double> altitude;

        // [[codegen::verbatim(UseHeightmapInfo.description)]]
        std::optional<bool> useHeightmap;
    };
#include "globetranslation_codegen.cpp"
} // namespace

namespace openspace::globebrowsing {

documentation::Documentation GlobeTranslation::Documentation() {
    return codegen::doc<Parameters>("space_translation_globetranslation");
}

GlobeTranslation::GlobeTranslation(const ghoul::Dictionary& dictionary)
    : _globe(GlobeInfo)
    , _longitude(LongitudeInfo, 0.0, -180.0, 180.0)
    , _latitude(LatitudeInfo, 0.0, -90.0, 90.0)
    , _altitude(AltitudeInfo, 0.0, 0.0, 1e12)
    , _useHeightmap(UseHeightmapInfo, false)
{
    const Parameters p = codegen::bake<Parameters>(dictionary);

    _globe = p.globe;
    _globe.onChange([this]() {
        fillAttachedNode();
        _positionIsDirty = true;
    });

    _longitude = p.longitude.value_or(_longitude);
    _longitude.onChange([this]() { _positionIsDirty = true; });
    addProperty(_longitude);

    _latitude = p.latitude.value_or(_latitude);
    _latitude.onChange([this]() { _positionIsDirty = true; });
    addProperty(_latitude);

    _altitude = p.altitude.value_or(_altitude);
    _altitude.setExponent(10.f);
    _altitude.onChange([this]() { _positionIsDirty = true; });
    addProperty(_altitude);

    _useHeightmap = p.useHeightmap.value_or(_useHeightmap);
    _useHeightmap.onChange([this]() { _positionIsDirty = true; });
    addProperty(_useHeightmap);
}

void GlobeTranslation::fillAttachedNode() {
    SceneGraphNode* n = sceneGraphNode(_globe);
    if (n->renderable() && dynamic_cast<RenderableGlobe*>(n->renderable())) {
        _attachedNode = dynamic_cast<RenderableGlobe*>(n->renderable());
    }
    else {
        LERRORC(
            "GlobeTranslation",
            "Could not set attached node as it does not have a RenderableGlobe"
        );
        if (_attachedNode) {
            // Reset the globe name to it's previous name
            _globe = _attachedNode->identifier();
        }
    }
}

glm::dvec3 GlobeTranslation::position(const UpdateData&) const {
    if (!_attachedNode) {
        // @TODO(abock): The const cast should be removed on a redesign of the translation
        //               to make the position function not constant. Const casting this
        //               away is fine as the factories that create the translations don't
        //               create them as constant objects
        const_cast<GlobeTranslation*>(this)->fillAttachedNode();
        _positionIsDirty = true;
    }

    if (_useHeightmap) {
        // If we use the heightmap, we have to compute the height every frame
        _positionIsDirty = true;
    }

    if (!_positionIsDirty) {
        return _position;
    }

    GlobeBrowsingModule& mod = *(global::moduleEngine->module<GlobeBrowsingModule>());

    if (_useHeightmap) {
        glm::vec3 groundPos = mod.cartesianCoordinatesFromGeo(
            *_attachedNode,
            _latitude,
            _longitude,
            0.0
        );

        SurfacePositionHandle h =
            _attachedNode->calculateSurfacePositionHandle(groundPos);

        _position = mod.cartesianCoordinatesFromGeo(
            *_attachedNode,
            _latitude,
            _longitude,
            h.heightToSurface + _altitude
        );
        return _position;
    }
    else {
        _position = mod.cartesianCoordinatesFromGeo(
            *_attachedNode,
            _latitude,
            _longitude,
            _altitude
        );
        _positionIsDirty = false;
        return _position;
    }
}

} // namespace openspace::globebrowsing
<|endoftext|>


<commit_before>#ifndef CLIENT_SERVER_INSTANCE_HPP
#define CLIENT_SERVER_INSTANCE_HPP

#include <atomic>
#include <thread>
#include <log.hpp>
#include "client_netcom.hpp"
#include "client_server_state.hpp"
#include <server_instance.hpp>

namespace config {
    class state;
}

namespace client {
    class server_instance {
        std::string   server_ip_   = "127.0.0.1";
        std::uint16_t server_port_ = 4444;
        std::string   admin_password_;
        bool          is_admin_ = false;

        std::atomic<bool> shutdown_;

        template<typename T, typename ... Args>
        T& set_state_(Args&& ... args) {
            return set_state_(std::make_unique<T>(*this, std::forward<Args>(args)...));
        }

        template<typename T>
        T& set_state_(std::unique_ptr<T> st) {
            T& ret = *st;

            if (current_state_) {
                current_state_->transition_to(ret);
                on_state_left.dispatch(*current_state_);
            }

            current_state_ = std::move(st);
            on_state_entered.dispatch(ret);

            return ret;
        }

        void set_state_(server::state_id sid);

    protected:
        config::state& conf_;
        logger& out_;

        netcom net_;
        scoped_connection_pool pool_;

        std::unique_ptr<server_state::base> current_state_;

    public :
        explicit server_instance(config::state& conf, logger& log);

        logger& get_log();
        netcom& get_netcom();
        config::state& get_conf();

        bool is_running() const;
        void run();
        void shutdown();
        bool is_admin() const;

        signal_t<void()> on_iter;

        // Signals for connection with server
        signal_t<void(std::string, std::uint16_t)> on_connecting;
        signal_t<void()> on_connected;
        signal_t<void(message::server::connection_failed::reason)> on_connection_failed;
        signal_t<void()> on_disconnecting;
        signal_t<void()> on_disconnected;
        signal_t<void()> on_unexpected_disconnected;

        // Signals for server state
        signal_t<void(server_state::base&)> on_state_left;
        signal_t<void(server_state::base&)> on_state_entered;

        // Signals for administative rights
        signal_t<void(request::server::admin_rights::failure::reason)> on_admin_rights_denied;
        signal_t<void()> on_admin_rights_granted;
    };
}

#ifndef NO_AUTOGEN
#include "autogen/packets/client_server_instance.hpp"
#endif

#endif
<commit_msg>Added debug output<commit_after>#ifndef CLIENT_SERVER_INSTANCE_HPP
#define CLIENT_SERVER_INSTANCE_HPP

#include <atomic>
#include <thread>
#include <log.hpp>
#include "client_netcom.hpp"
#include "client_server_state.hpp"
#include <server_instance.hpp>

namespace config {
    class state;
}

namespace client {
    class server_instance {
        std::string   server_ip_   = "127.0.0.1";
        std::uint16_t server_port_ = 4444;
        std::string   admin_password_;
        bool          is_admin_ = false;

        std::atomic<bool> shutdown_;

        template<typename T, typename ... Args>
        T& set_state_(Args&& ... args) {
            return set_state_(std::make_unique<T>(*this, std::forward<Args>(args)...));
        }

        template<typename T>
        T& set_state_(std::unique_ptr<T> st) {
            T& ret = *st;

            if (current_state_) {
                current_state_->transition_to(ret);
                on_state_left.dispatch(*current_state_);
            }

            current_state_ = std::move(st);
            on_state_entered.dispatch(ret);

            return ret;
        }

        void set_state_(server::state_id sid);

    protected:
        config::state& conf_;
        logger& out_;

        netcom net_;
        scoped_connection_pool pool_;

        std::unique_ptr<server_state::base> current_state_;

    public :
        explicit server_instance(config::state& conf, logger& log);

        logger& get_log();
        netcom& get_netcom();
        config::state& get_conf();

        bool is_running() const;
        void run();
        void shutdown();
        bool is_admin() const;

        signal_t<void()> on_iter;

        // Signals for connection with server
        signal_t<void(std::string, std::uint16_t)> on_connecting;
        signal_t<void()> on_connected;
        signal_t<void(message::server::connection_failed::reason)> on_connection_failed;
        signal_t<void()> on_disconnecting;
        signal_t<void()> on_disconnected;
        signal_t<void()> on_unexpected_disconnected;

        // Signals for server state
        signal_t<void(server_state::base&)> on_state_left;
        signal_t<void(server_state::base&)> on_state_entered;

        // Signals for administative rights
        signal_t<void(request::server::admin_rights::failure::reason)> on_admin_rights_denied;
        signal_t<void()> on_admin_rights_granted;

        // Signals for debugging
        signal_t<void(std::string)> on_debug_message;
    };
}

#ifndef NO_AUTOGEN
#include "autogen/packets/client_server_instance.hpp"
#endif

#endif
<|endoftext|>


<commit_before>// @(#)root/base:$Id$
// Author: Rene Brun   26/12/94

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TNamed                                                               //
//                                                                      //
// The TNamed class is the base class for all named ROOT classes        //
// A TNamed contains the essential elements (name, title)               //
// to identify a derived object in containers, directories and files.   //
// Most member functions defined in this base class are in general      //
// overridden by the derived classes.                                   //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "Riostream.h"
#include "Strlen.h"
#include "TNamed.h"
#include "TROOT.h"
#include "TVirtualPad.h"
#include "TClass.h"

ClassImp(TNamed)

////////////////////////////////////////////////////////////////////////////////
/// TNamed copy ctor.

TNamed::TNamed(const TNamed &named) : TObject(named),fName(named.fName),fTitle(named.fTitle)
{
}

////////////////////////////////////////////////////////////////////////////////
/// TNamed assignment operator.

TNamed& TNamed::operator=(const TNamed& rhs)
{
   if (this != &rhs) {
      TObject::operator=(rhs);
      fName  = rhs.fName;
      fTitle = rhs.fTitle;
   }
   return *this;
}

////////////////////////////////////////////////////////////////////////////////
/// Set name and title to empty strings ("").

void TNamed::Clear(Option_t *)
{
   fName  = "";
   fTitle = "";
}

////////////////////////////////////////////////////////////////////////////////
/// Make a clone of an object using the Streamer facility.
/// If newname is specified, this will be the name of the new object.

TObject *TNamed::Clone(const char *newname) const
{
   TNamed *named = (TNamed*)TObject::Clone(newname);
   if (newname && strlen(newname)) named->SetName(newname);
   return named;
}

////////////////////////////////////////////////////////////////////////////////
/// Compare two TNamed objects. Returns 0 when equal, -1 when this is
/// smaller and +1 when bigger (like strcmp).

Int_t TNamed::Compare(const TObject *obj) const
{
   if (this == obj) return 0;
   return fName.CompareTo(obj->GetName());
}

////////////////////////////////////////////////////////////////////////////////
/// Copy this to obj.

void TNamed::Copy(TObject &obj) const
{
   TObject::Copy(obj);
   ((TNamed&)obj).fName  = fName;
   ((TNamed&)obj).fTitle = fTitle;
}

////////////////////////////////////////////////////////////////////////////////
/// Encode TNamed into output buffer.

void TNamed::FillBuffer(char *&buffer)
{
   fName.FillBuffer(buffer);
   fTitle.FillBuffer(buffer);
}

////////////////////////////////////////////////////////////////////////////////
/// List TNamed name and title.

void TNamed::ls(Option_t *opt) const
{
   TROOT::IndentLevel();
   if (opt && strstr(opt,"noaddr")) {
      std::cout <<"OBJ: " << IsA()->GetName() << "\t" << GetName() << "\t" << GetTitle() << " : "
                << Int_t(TestBit(kCanDelete)) << std::endl;
   } else {
      std::cout <<"OBJ: " << IsA()->GetName() << "\t" << GetName() << "\t" << GetTitle() << " : "
                 << Int_t(TestBit(kCanDelete)) << " at: "<<this<< std::endl;
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Print TNamed name and title.

void TNamed::Print(Option_t *) const
{
   std::cout <<"OBJ: " << IsA()->GetName() << "\t" << GetName() << "\t" << GetTitle() << std::endl;
}

////////////////////////////////////////////////////////////////////////////////
/// Change (i.e. set) the name of the TNamed.
/// WARNING: if the object is a member of a THashTable or THashList container
/// the container must be Rehash()'ed after SetName(). For example the list
/// of objects in the current directory is a THashList.

void TNamed::SetName(const char *name)
{
   fName = name;
   if (gPad && TestBit(kMustCleanup)) gPad->Modified();
}

////////////////////////////////////////////////////////////////////////////////
/// Change (i.e. set) all the TNamed parameters (name and title).
/// WARNING: if the name is changed and the object is a member of a
/// THashTable or THashList container the container must be Rehash()'ed
/// after SetName(). For example the list of objects in the current
/// directory is a THashList.

void TNamed::SetNameTitle(const char *name, const char *title)
{
   fName  = name;
   fTitle = title;
   if (gPad && TestBit(kMustCleanup)) gPad->Modified();
}

////////////////////////////////////////////////////////////////////////////////
/// Change (i.e. set) the title of the TNamed.

void TNamed::SetTitle(const char *title)
{
   fTitle = title;
   if (gPad && TestBit(kMustCleanup)) gPad->Modified();
}

////////////////////////////////////////////////////////////////////////////////
/// Return size of the TNamed part of the TObject.

Int_t TNamed::Sizeof() const
{
   Int_t nbytes = fName.Sizeof() + fTitle.Sizeof();
   return nbytes;
}
<commit_msg>Doxygen<commit_after>// @(#)root/base:$Id$
// Author: Rene Brun   26/12/94

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

/** \class TNamed
The TNamed class is the base class for all named ROOT classes.

A TNamed contains the essential elements (name, title)
to identify a derived object in containers, directories and files.
Most member functions defined in this base class are in general
overridden by the derived classes.
*/

#include "Riostream.h"
#include "Strlen.h"
#include "TNamed.h"
#include "TROOT.h"
#include "TVirtualPad.h"
#include "TClass.h"

ClassImp(TNamed)

////////////////////////////////////////////////////////////////////////////////
/// TNamed copy ctor.

TNamed::TNamed(const TNamed &named) : TObject(named),fName(named.fName),fTitle(named.fTitle)
{
}

////////////////////////////////////////////////////////////////////////////////
/// TNamed assignment operator.

TNamed& TNamed::operator=(const TNamed& rhs)
{
   if (this != &rhs) {
      TObject::operator=(rhs);
      fName  = rhs.fName;
      fTitle = rhs.fTitle;
   }
   return *this;
}

////////////////////////////////////////////////////////////////////////////////
/// Set name and title to empty strings ("").

void TNamed::Clear(Option_t *)
{
   fName  = "";
   fTitle = "";
}

////////////////////////////////////////////////////////////////////////////////
/// Make a clone of an object using the Streamer facility.
/// If newname is specified, this will be the name of the new object.

TObject *TNamed::Clone(const char *newname) const
{
   TNamed *named = (TNamed*)TObject::Clone(newname);
   if (newname && strlen(newname)) named->SetName(newname);
   return named;
}

////////////////////////////////////////////////////////////////////////////////
/// Compare two TNamed objects. Returns 0 when equal, -1 when this is
/// smaller and +1 when bigger (like strcmp).

Int_t TNamed::Compare(const TObject *obj) const
{
   if (this == obj) return 0;
   return fName.CompareTo(obj->GetName());
}

////////////////////////////////////////////////////////////////////////////////
/// Copy this to obj.

void TNamed::Copy(TObject &obj) const
{
   TObject::Copy(obj);
   ((TNamed&)obj).fName  = fName;
   ((TNamed&)obj).fTitle = fTitle;
}

////////////////////////////////////////////////////////////////////////////////
/// Encode TNamed into output buffer.

void TNamed::FillBuffer(char *&buffer)
{
   fName.FillBuffer(buffer);
   fTitle.FillBuffer(buffer);
}

////////////////////////////////////////////////////////////////////////////////
/// List TNamed name and title.

void TNamed::ls(Option_t *opt) const
{
   TROOT::IndentLevel();
   if (opt && strstr(opt,"noaddr")) {
      std::cout <<"OBJ: " << IsA()->GetName() << "\t" << GetName() << "\t" << GetTitle() << " : "
                << Int_t(TestBit(kCanDelete)) << std::endl;
   } else {
      std::cout <<"OBJ: " << IsA()->GetName() << "\t" << GetName() << "\t" << GetTitle() << " : "
                 << Int_t(TestBit(kCanDelete)) << " at: "<<this<< std::endl;
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Print TNamed name and title.

void TNamed::Print(Option_t *) const
{
   std::cout <<"OBJ: " << IsA()->GetName() << "\t" << GetName() << "\t" << GetTitle() << std::endl;
}

////////////////////////////////////////////////////////////////////////////////
/// Change (i.e. set) the name of the TNamed.
/// WARNING: if the object is a member of a THashTable or THashList container
/// the container must be Rehash()'ed after SetName(). For example the list
/// of objects in the current directory is a THashList.

void TNamed::SetName(const char *name)
{
   fName = name;
   if (gPad && TestBit(kMustCleanup)) gPad->Modified();
}

////////////////////////////////////////////////////////////////////////////////
/// Change (i.e. set) all the TNamed parameters (name and title).
//
/// WARNING: if the name is changed and the object is a member of a
/// THashTable or THashList container the container must be Rehash()'ed
/// after SetName(). For example the list of objects in the current
/// directory is a THashList.

void TNamed::SetNameTitle(const char *name, const char *title)
{
   fName  = name;
   fTitle = title;
   if (gPad && TestBit(kMustCleanup)) gPad->Modified();
}

////////////////////////////////////////////////////////////////////////////////
/// Change (i.e. set) the title of the TNamed.

void TNamed::SetTitle(const char *title)
{
   fTitle = title;
   if (gPad && TestBit(kMustCleanup)) gPad->Modified();
}

////////////////////////////////////////////////////////////////////////////////
/// Return size of the TNamed part of the TObject.

Int_t TNamed::Sizeof() const
{
   Int_t nbytes = fName.Sizeof() + fTitle.Sizeof();
   return nbytes;
}
<|endoftext|>


<commit_before><commit_msg>planning: delete obstacle history trajectory points if too old<commit_after><|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2018 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <modules/qtwidgets/properties/colorlineedit.h>
#include <modules/qtwidgets/inviwoqtutils.h>
#include <inviwo/core/util/colorconversion.h>
#include <inviwo/core/util/assertion.h>

#include <warn/push>
#include <warn/ignore/all>
#include <QRegularExpressionValidator>
#include <QRegularExpression>
#include <QLocale>
#include <QStyle>
#include <QEvent>
#include <QKeyEvent>
#include <warn/pop>

namespace inviwo {

ColorLineEdit::ColorLineEdit(QWidget *parent)
    : QLineEdit(parent), validator_(new QRegularExpressionValidator(this)) {
    setObjectName("ColorLineEdit");
    updateRegExp();
    setValidator(validator_);

    connect(this, &QLineEdit::editingFinished, this, &ColorLineEdit::updateColor);

    connect(this, &QLineEdit::textChanged, this, [&](const QString &) {
        if (hasFocus()) {
            setProperty("input", hasAcceptableInput() ? "valid" : "invalid");
            style()->unpolish(this);
            style()->polish(this);
        }
    });
}

void ColorLineEdit::setColor(ivec3 v, ColorRepresentation rep) {
    color_ = dvec4(glm::clamp(v, ivec3(0), ivec3(255)), 1.0) / 255.0;
    hasAlpha_ = false;
    representation_ = rep;
    updateText();
}

void ColorLineEdit::setColor(ivec4 v, ColorRepresentation rep) {
    color_ = dvec4(glm::clamp(v, ivec4(0), ivec4(255))) / 255.0;
    hasAlpha_ = true;
    representation_ = rep;
    updateText();
}

void ColorLineEdit::setColor(vec3 v, ColorRepresentation rep) { setColor(dvec3(v), rep); }

void ColorLineEdit::setColor(vec4 v, ColorRepresentation rep) { setColor(dvec4(v), rep); }

void ColorLineEdit::setColor(dvec3 v, ColorRepresentation rep) {
    color_ = dvec4(v, 1.0);
    hasAlpha_ = false;
    representation_ = rep;
    updateText();
}

void ColorLineEdit::setColor(dvec4 v, ColorRepresentation rep) {
    color_ = v;
    hasAlpha_ = true;
    representation_ = rep;
    updateText();
}

bool ColorLineEdit::hasAlpha() const { return hasAlpha_; }

void ColorLineEdit::setRepresentation(ColorRepresentation rep) {
    if (rep != representation_) {
        representation_ = rep;
        updateText();
    }
}

ColorLineEdit::ColorRepresentation ColorLineEdit::getRepresentation() const {
    return representation_;
}

void ColorLineEdit::changeEvent(QEvent *event) {
    switch (event->type()) {
        case QEvent::LocaleChange:
            updateRegExp();
            break;
        default:
            break;
    }
    QLineEdit::changeEvent(event);
}

void ColorLineEdit::focusInEvent(QFocusEvent *event) {
    setProperty("input", hasAcceptableInput() ? "valid" : "invalid");
    style()->unpolish(this);
    style()->polish(this);

    QLineEdit::focusInEvent(event);
}

void ColorLineEdit::focusOutEvent(QFocusEvent *event) {
    if (!hasAcceptableInput()) {
        // discard changes if invalid
        updateText();
    }

    setProperty("input", "none");
    style()->unpolish(this);
    style()->polish(this);

    QLineEdit::focusOutEvent(event);
}

void ColorLineEdit::keyPressEvent(QKeyEvent *event) {
    if (event->key() == Qt::Key_Escape) {
        // discard changes
        updateText();
        event->accept();
    }
    QLineEdit::keyPressEvent(event);
}

void ColorLineEdit::updateText() {
    // create appropriate textual representation
    QString str;
    switch (representation_) {
        case inviwo::ColorLineEdit::ColorRepresentation::Integer: {
            auto c = util::glm_convert<ivec4>(color_ * 255.0);
            str = QString("%1 %2 %3").arg(c.r).arg(c.g).arg(c.b);
            if (hasAlpha_) {
                str.append(QString(" %1").arg(c.a));
            }
        } break;
        case inviwo::ColorLineEdit::ColorRepresentation::Hexadecimal:
            if (hasAlpha_) {
                str = utilqt::toQString(color::rgba2hex(vec4(color_)));
            } else {
                str = utilqt::toQString(color::rgb2hex(vec4(color_)));
            }
            break;
        case inviwo::ColorLineEdit::ColorRepresentation::FloatingPoint:
        default:
            str = QString("%L1 %L2 %L3")
                      .arg(color_.r, 0, 'f', 3)
                      .arg(color_.g, 0, 'f', 3)
                      .arg(color_.b, 0, 'f', 3);
            if (hasAlpha_) {
                str.append(QString(" %L1").arg(color_.a, 0, 'f', 3));
            }
            break;
    }
    setText(str);
}

void ColorLineEdit::updateColor() {
    QStringList tokens = text().split(QRegularExpression("\\s+"));

    ivwAssert((tokens.size() == 1) || (tokens.size() == 3) || (tokens.size() == 4),
              "Invalid number of color components");
    ivwAssert((tokens.size() == 1) && tokens.front().startsWith("#"),
              "Invalid single component (expected hex color code starting with '#')");

    if (tokens.size() == 1) {
        // it is a hex color code
        color_ = color::hex2rgba(utilqt::fromQString(tokens.front()));
    } else {
        auto locale = QLocale::system();

        dvec4 color(0.0);
        for (int i = 0; i < tokens.size(); ++i) {
            color[i] = locale.toDouble(tokens[i]);
        }

        // detect type of representation based on first number
        // If it contains a decimal point it must be a float range color, i.e. [0,1]
        if (!tokens.front().contains(locale.decimalPoint())) {
            // assuming uint8 representation, renormalize values to [0,1]
            color /= 255.0;
        }
        if (!hasAlpha_) {
            color.a = 1.0;
        }
        color_ = color;
    }

    // ensure that line edit shows proper color representation
    updateText();
    emit colorChanged();
}

void ColorLineEdit::updateRegExp() {
    QString decimalPoint = QLocale::system().decimalPoint();
    if (decimalPoint == ".") {
        decimalPoint = "\\.";
    }

    // create a regular expression matching either
    //   - hex color codes #RRGGBB, #RRGGBBAA, #RGB, #RGBA
    //   - uint8 colors (rgb, rgba)
    //   - double colors [0,1] (rgb, rgba)
    validator_->setRegularExpression(QRegularExpression(
        QString("((((?:^|\\s+)#([0-9a-fA-F]{2}){3,4})|((?:^|\\s+)#[0-9a-fA-F]{3,4}))"
                "|(((?:^|\\s+)([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5]))){3,4})"
                "|((?:^|\\s+)([-+]?(((\\d+%1\\d*)|(%1\\d+))+([eE][-+]?\\d+)?|\\d+([eE][-+]?\\d+))))"
                "{3,4})\\s*")
            .arg(decimalPoint)));
}

template <>
dvec3 ColorLineEdit::getColor<dvec3>() const {
    return color_;
}
template <>
dvec4 ColorLineEdit::getColor<dvec4>() const {
    return color_;
}

}  // namespace inviwo
<commit_msg>QtWidgets: assertion fix<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2018 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <modules/qtwidgets/properties/colorlineedit.h>
#include <modules/qtwidgets/inviwoqtutils.h>
#include <inviwo/core/util/colorconversion.h>
#include <inviwo/core/util/assertion.h>

#include <warn/push>
#include <warn/ignore/all>
#include <QRegularExpressionValidator>
#include <QRegularExpression>
#include <QLocale>
#include <QStyle>
#include <QEvent>
#include <QKeyEvent>
#include <warn/pop>

namespace inviwo {

ColorLineEdit::ColorLineEdit(QWidget *parent)
    : QLineEdit(parent), validator_(new QRegularExpressionValidator(this)) {
    setObjectName("ColorLineEdit");
    updateRegExp();
    setValidator(validator_);

    connect(this, &QLineEdit::editingFinished, this, &ColorLineEdit::updateColor);

    connect(this, &QLineEdit::textChanged, this, [&](const QString &) {
        if (hasFocus()) {
            setProperty("input", hasAcceptableInput() ? "valid" : "invalid");
            style()->unpolish(this);
            style()->polish(this);
        }
    });
}

void ColorLineEdit::setColor(ivec3 v, ColorRepresentation rep) {
    color_ = dvec4(glm::clamp(v, ivec3(0), ivec3(255)), 1.0) / 255.0;
    hasAlpha_ = false;
    representation_ = rep;
    updateText();
}

void ColorLineEdit::setColor(ivec4 v, ColorRepresentation rep) {
    color_ = dvec4(glm::clamp(v, ivec4(0), ivec4(255))) / 255.0;
    hasAlpha_ = true;
    representation_ = rep;
    updateText();
}

void ColorLineEdit::setColor(vec3 v, ColorRepresentation rep) { setColor(dvec3(v), rep); }

void ColorLineEdit::setColor(vec4 v, ColorRepresentation rep) { setColor(dvec4(v), rep); }

void ColorLineEdit::setColor(dvec3 v, ColorRepresentation rep) {
    color_ = dvec4(v, 1.0);
    hasAlpha_ = false;
    representation_ = rep;
    updateText();
}

void ColorLineEdit::setColor(dvec4 v, ColorRepresentation rep) {
    color_ = v;
    hasAlpha_ = true;
    representation_ = rep;
    updateText();
}

bool ColorLineEdit::hasAlpha() const { return hasAlpha_; }

void ColorLineEdit::setRepresentation(ColorRepresentation rep) {
    if (rep != representation_) {
        representation_ = rep;
        updateText();
    }
}

ColorLineEdit::ColorRepresentation ColorLineEdit::getRepresentation() const {
    return representation_;
}

void ColorLineEdit::changeEvent(QEvent *event) {
    switch (event->type()) {
        case QEvent::LocaleChange:
            updateRegExp();
            break;
        default:
            break;
    }
    QLineEdit::changeEvent(event);
}

void ColorLineEdit::focusInEvent(QFocusEvent *event) {
    setProperty("input", hasAcceptableInput() ? "valid" : "invalid");
    style()->unpolish(this);
    style()->polish(this);

    QLineEdit::focusInEvent(event);
}

void ColorLineEdit::focusOutEvent(QFocusEvent *event) {
    if (!hasAcceptableInput()) {
        // discard changes if invalid
        updateText();
    }

    setProperty("input", "none");
    style()->unpolish(this);
    style()->polish(this);

    QLineEdit::focusOutEvent(event);
}

void ColorLineEdit::keyPressEvent(QKeyEvent *event) {
    if (event->key() == Qt::Key_Escape) {
        // discard changes
        updateText();
        event->accept();
    }
    QLineEdit::keyPressEvent(event);
}

void ColorLineEdit::updateText() {
    // create appropriate textual representation
    QString str;
    switch (representation_) {
        case inviwo::ColorLineEdit::ColorRepresentation::Integer: {
            auto c = util::glm_convert<ivec4>(color_ * 255.0);
            str = QString("%1 %2 %3").arg(c.r).arg(c.g).arg(c.b);
            if (hasAlpha_) {
                str.append(QString(" %1").arg(c.a));
            }
        } break;
        case inviwo::ColorLineEdit::ColorRepresentation::Hexadecimal:
            if (hasAlpha_) {
                str = utilqt::toQString(color::rgba2hex(vec4(color_)));
            } else {
                str = utilqt::toQString(color::rgb2hex(vec4(color_)));
            }
            break;
        case inviwo::ColorLineEdit::ColorRepresentation::FloatingPoint:
        default:
            str = QString("%L1 %L2 %L3")
                      .arg(color_.r, 0, 'f', 3)
                      .arg(color_.g, 0, 'f', 3)
                      .arg(color_.b, 0, 'f', 3);
            if (hasAlpha_) {
                str.append(QString(" %L1").arg(color_.a, 0, 'f', 3));
            }
            break;
    }
    setText(str);
}

void ColorLineEdit::updateColor() {
    QStringList tokens = text().split(QRegularExpression("\\s+"));

    ivwAssert((tokens.size() == 1) || (tokens.size() == 3) || (tokens.size() == 4),
              "Invalid number of color components");
    ivwAssert((tokens.size() > 1) || ((tokens.size() == 1) && tokens.front().startsWith("#")),
              "Invalid single component (expected hex color code starting with '#')");

    if (tokens.size() == 1) {
        // it is a hex color code
        color_ = color::hex2rgba(utilqt::fromQString(tokens.front()));
    } else {
        auto locale = QLocale::system();

        dvec4 color(0.0);
        for (int i = 0; i < tokens.size(); ++i) {
            color[i] = locale.toDouble(tokens[i]);
        }

        // detect type of representation based on first number
        // If it contains a decimal point it must be a float range color, i.e. [0,1]
        if (!tokens.front().contains(locale.decimalPoint())) {
            // assuming uint8 representation, renormalize values to [0,1]
            color /= 255.0;
        }
        if (!hasAlpha_) {
            color.a = 1.0;
        }
        color_ = color;
    }

    // ensure that line edit shows proper color representation
    updateText();
    emit colorChanged();
}

void ColorLineEdit::updateRegExp() {
    QString decimalPoint = QLocale::system().decimalPoint();
    if (decimalPoint == ".") {
        decimalPoint = "\\.";
    }

    // create a regular expression matching either
    //   - hex color codes #RRGGBB, #RRGGBBAA, #RGB, #RGBA
    //   - uint8 colors (rgb, rgba)
    //   - double colors [0,1] (rgb, rgba)
    validator_->setRegularExpression(QRegularExpression(
        QString("((((?:^|\\s+)#([0-9a-fA-F]{2}){3,4})|((?:^|\\s+)#[0-9a-fA-F]{3,4}))"
                "|(((?:^|\\s+)([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5]))){3,4})"
                "|((?:^|\\s+)([-+]?(((\\d+%1\\d*)|(%1\\d+))+([eE][-+]?\\d+)?|\\d+([eE][-+]?\\d+))))"
                "{3,4})\\s*")
            .arg(decimalPoint)));
}

template <>
dvec3 ColorLineEdit::getColor<dvec3>() const {
    return color_;
}
template <>
dvec4 ColorLineEdit::getColor<dvec4>() const {
    return color_;
}

}  // namespace inviwo
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <limits>
#include <stan/math/prim/mat.hpp>
#include <string>
#include <vector>

template <typename T_m, typename T_a>
std::string pull_msg(Eigen::Matrix<T_m, -1, -1> &mat, T_a to_add) {
  std::string message;
  try {
    stan::math::add_diag(mat, to_add);
  } catch (std::domain_error &e) {
    message = e.what();
  } catch (...) {
    message = "Threw the wrong exection";
  }
  return message;
}

TEST(MathPrimMat, double_mat_double_add_diag) {
  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> mat(2, 3);
  mat << 1, 1, 1, 1, 1, 1;

  double jitter = 1e-10;

  Eigen::MatrixXd out_mat;
  EXPECT_NO_THROW(out_mat = stan::math::add_diag(mat, jitter));
  for (int i = 0; i < 2; ++i)
    EXPECT_FLOAT_EQ(1.0 + jitter, out_mat(i, i))
        << "index: ( " << i << ", " << i << ")";
}

TEST(MathPrimMat, double_mat_double_vec_add_diag) {
  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> mat(2, 3);
  mat << 1, 1, 1, 1, 1, 1;

  Eigen::Matrix<double, 1, -1> to_add(2);
  to_add << 0, 1;

  Eigen::MatrixXd out_mat;
  EXPECT_NO_THROW(out_mat = stan::math::add_diag(mat, to_add));
  for (int i = 0; i < 2; ++i)
    EXPECT_FLOAT_EQ(1 + to_add[i], out_mat(i, i))
        << "index: ( " << i << ", " << i << ")";
}

TEST(MathPrimMat, double_mat_double_rvec_add_diag) {
  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> mat(2, 3);
  mat << 1, 1, 1, 1, 1, 1;

  Eigen::Matrix<double, -1, 1> to_add(2);
  to_add << 0, 1;

  Eigen::MatrixXd out_mat;
  EXPECT_NO_THROW(out_mat = stan::math::add_diag(mat, to_add));
  for (int i = 0; i < 2; ++i)
    EXPECT_FLOAT_EQ(1 + to_add[i], out_mat(i, i))
        << "index: ( " << i << ", " << i << ")";
}

TEST(MathPrimMat, var_mat_double_vec_add_diag) {
  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> mat(2, 3);
  mat << 1, 1, 1, 1, 1, 1;

  Eigen::Matrix<double, 1, -1> to_add(2);
  to_add << 0, 1;

  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> out_mat;
  EXPECT_NO_THROW(out_mat = stan::math::add_diag(mat, to_add));
  for (int i = 0; i < 2; ++i)
    EXPECT_FLOAT_EQ(1 + to_add[i], out_mat(i, i))
        << "index: ( " << i << ", " << i << ")";
}

TEST(MathPrimMat, var_mat_double_rvec_add_diag) {
  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> mat(2, 3);
  mat << 1, 1, 1, 1, 1, 1;

  Eigen::Matrix<double, -1, 1> to_add(2);
  to_add << 0, 1;

  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> out_mat;
  EXPECT_NO_THROW(out_mat = stan::math::add_diag(mat, to_add));
  for (int i = 0; i < 2; ++i)
    EXPECT_FLOAT_EQ(1 + to_add[i], out_mat(i, i))
        << "index: ( " << i << ", " << i << ")";
}
<commit_msg>Update add_diag_test.cpp<commit_after>#include <gtest/gtest.h>
#include <stan/math/prim/mat.hpp>
#include <limits>
#include <string>
#include <vector>

template <typename T_m, typename T_a>
std::string pull_msg(Eigen::Matrix<T_m, -1, -1> &mat, T_a to_add) {
  std::string message;
  try {
    stan::math::add_diag(mat, to_add);
  } catch (std::domain_error &e) {
    message = e.what();
  } catch (...) {
    message = "Threw the wrong exection";
  }
  return message;
}

TEST(MathPrimMat, double_mat_double_add_diag) {
  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> mat(2, 3);
  mat << 1, 1, 1, 1, 1, 1;

  double jitter = 1e-10;

  Eigen::MatrixXd out_mat;
  EXPECT_NO_THROW(out_mat = stan::math::add_diag(mat, jitter));
  for (int i = 0; i < 2; ++i)
    EXPECT_FLOAT_EQ(1.0 + jitter, out_mat(i, i))
        << "index: ( " << i << ", " << i << ")";
}

TEST(MathPrimMat, double_mat_double_vec_add_diag) {
  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> mat(2, 3);
  mat << 1, 1, 1, 1, 1, 1;

  Eigen::Matrix<double, 1, -1> to_add(2);
  to_add << 0, 1;

  Eigen::MatrixXd out_mat;
  EXPECT_NO_THROW(out_mat = stan::math::add_diag(mat, to_add));
  for (int i = 0; i < 2; ++i)
    EXPECT_FLOAT_EQ(1 + to_add[i], out_mat(i, i))
        << "index: ( " << i << ", " << i << ")";
}

TEST(MathPrimMat, double_mat_double_rvec_add_diag) {
  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> mat(2, 3);
  mat << 1, 1, 1, 1, 1, 1;

  Eigen::Matrix<double, -1, 1> to_add(2);
  to_add << 0, 1;

  Eigen::MatrixXd out_mat;
  EXPECT_NO_THROW(out_mat = stan::math::add_diag(mat, to_add));
  for (int i = 0; i < 2; ++i)
    EXPECT_FLOAT_EQ(1 + to_add[i], out_mat(i, i))
        << "index: ( " << i << ", " << i << ")";
}

TEST(MathPrimMat, var_mat_double_vec_add_diag) {
  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> mat(2, 3);
  mat << 1, 1, 1, 1, 1, 1;

  Eigen::Matrix<double, 1, -1> to_add(2);
  to_add << 0, 1;

  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> out_mat;
  EXPECT_NO_THROW(out_mat = stan::math::add_diag(mat, to_add));
  for (int i = 0; i < 2; ++i)
    EXPECT_FLOAT_EQ(1 + to_add[i], out_mat(i, i))
        << "index: ( " << i << ", " << i << ")";
}

TEST(MathPrimMat, var_mat_double_rvec_add_diag) {
  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> mat(2, 3);
  mat << 1, 1, 1, 1, 1, 1;

  Eigen::Matrix<double, -1, 1> to_add(2);
  to_add << 0, 1;

  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> out_mat;
  EXPECT_NO_THROW(out_mat = stan::math::add_diag(mat, to_add));
  for (int i = 0; i < 2; ++i)
    EXPECT_FLOAT_EQ(1 + to_add[i], out_mat(i, i))
        << "index: ( " << i << ", " << i << ")";
}
<|endoftext|>


<commit_before>// Copyright 2021 Google LLC
//
// 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 "google/cloud/iam/iam_credentials_client.h"
#include "google/cloud/spanner/admin/instance_admin_client.h"
#include "google/cloud/common_options.h"
#include "google/cloud/grpc_options.h"
#include "google/cloud/internal/getenv.h"
#include "google/cloud/log.h"
#include "google/cloud/project.h"
#include "google/cloud/testing_util/example_driver.h"
#include "absl/strings/str_split.h"
#include "absl/time/time.h"  // NOLINT(modernize-deprecated-headers)
#include <curl/curl.h>
#include <hello_world_grpc/hello_world.grpc.pb.h>
#include <chrono>
#include <stdexcept>
#include <thread>

namespace {

auto constexpr kTokenValidationPeriod = std::chrono::seconds(30);

extern "C" size_t CurlOnWriteData(char* ptr, size_t size, size_t nmemb,
                                  void* userdata) {
  auto* buffer = reinterpret_cast<std::string*>(userdata);
  buffer->append(ptr, size * nmemb);
  return size * nmemb;
}

google::cloud::StatusOr<std::string> HttpGet(std::string const& url,
                                             std::string const& token) {
  static auto const kCurlInit = [] {
    return curl_global_init(CURL_GLOBAL_ALL);
  }();
  (void)kCurlInit;
  auto const authorization = "Authorization: Bearer " + token;
  using Headers = std::unique_ptr<curl_slist, decltype(&curl_slist_free_all)>;
  auto const headers = Headers{
      curl_slist_append(nullptr, authorization.c_str()), curl_slist_free_all};
  using CurlHandle = std::unique_ptr<CURL, decltype(&curl_easy_cleanup)>;
  auto curl = CurlHandle(curl_easy_init(), curl_easy_cleanup);
  if (!curl) throw std::runtime_error("Failed to create CurlHandle");
  std::string buffer;
  curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str());
  curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, headers.get());
  curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, &CurlOnWriteData);
  curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &buffer);

  CURLcode code = curl_easy_perform(curl.get());
  if (code != CURLE_OK) throw std::runtime_error(curl_easy_strerror(code));
  long status;  // NOLINT(google-runtime-int)
  code = curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE, &status);
  if (code != CURLE_OK) throw std::runtime_error(curl_easy_strerror(code));

  // Handle common errors as Status, this is not exhaustive.
  using ::google::cloud::Status;
  using ::google::cloud::StatusCode;
  if (status == 400) return Status(StatusCode::kInvalidArgument, buffer);
  if (status == 401) return Status(StatusCode::kUnauthenticated, buffer);
  if (status == 403) return Status(StatusCode::kPermissionDenied, buffer);
  if (status >= 500) return Status(StatusCode::kInternal, buffer);
  if (status < 200 || status >= 300) {
    std::ostringstream os;
    os << "HTTP error [" << status << "]: " << buffer;
    return Status(StatusCode::kUnknown, buffer);
  }
  return buffer;
}

// TODO(#6185) - this should be done by the generated code
std::set<std::string> DefaultTracingComponents() {
  return absl::StrSplit(
      google::cloud::internal::GetEnv("GOOGLE_CLOUD_CPP_ENABLE_TRACING")
          .value_or(""),
      ',');
}

google::iam::credentials::v1::GenerateAccessTokenResponse UseAccessToken(
    google::cloud::iam::IAMCredentialsClient client,
    std::vector<std::string> const& argv) {
  namespace iam = ::google::cloud::iam;
  return [](iam::IAMCredentialsClient client,
            std::string const& service_account, std::string const& project_id) {
    google::protobuf::Duration duration;
    duration.set_seconds(
        std::chrono::seconds(2 * kTokenValidationPeriod).count());
    auto token = client.GenerateAccessToken(
        "projects/-/serviceAccounts/" + service_account, /*delegates=*/{},
        /*scope=*/{"https://www.googleapis.com/auth/cloud-platform"}, duration);
    if (!token) throw std::runtime_error(token.status().message());

    auto const expiration =
        std::chrono::system_clock::from_time_t(token->expire_time().seconds());
    std::cout << "Fetched token starting with "
              << token->access_token().substr(0, 8)
              << ", which will expire around " << absl::FromChrono(expiration)
              << std::endl;

    auto credentials = grpc::CompositeChannelCredentials(
        grpc::SslCredentials({}),
        grpc::AccessTokenCredentials(token->access_token()));

    google::cloud::spanner_admin::InstanceAdminClient admin(
        google::cloud::spanner_admin::MakeInstanceAdminConnection(
            google::cloud::Options{}.set<google::cloud::GrpcCredentialOption>(
                credentials)));
    for (auto instance :
         admin.ListInstances(google::cloud::Project(project_id).FullName())) {
      if (!instance) throw std::runtime_error(instance.status().message());
      std::cout << "Instance: " << instance->name() << "\n";
    }

    return *std::move(token);
  }(std::move(client), argv.at(0), argv.at(1));
}

void UseAccessTokenUntilExpired(google::cloud::iam::IAMCredentialsClient client,
                                std::vector<std::string> const& argv) {
  auto token = UseAccessToken(std::move(client), argv);
  auto const project_id = argv.at(1);
  auto const expiration =
      std::chrono::system_clock::from_time_t(token.expire_time().seconds());
  auto const deadline = expiration + 4 * kTokenValidationPeriod;
  std::cout << "Running until " << absl::FromChrono(deadline)
            << ". This is past the access token expiration time ("
            << absl::FromChrono(expiration) << ")" << std::endl;

  auto iteration = [=](bool expired) {
    auto credentials = grpc::CompositeChannelCredentials(
        grpc::SslCredentials({}),
        grpc::AccessTokenCredentials(token.access_token()));
    google::cloud::spanner_admin::InstanceAdminClient admin(
        google::cloud::spanner_admin::MakeInstanceAdminConnection(
            google::cloud::Options{}.set<google::cloud::GrpcCredentialOption>(
                credentials)));
    for (auto instance :
         admin.ListInstances(google::cloud::Project(project_id).FullName())) {
      // kUnauthenticated receives special treatment, it is the error received
      // when the token expires.
      if (instance.status().code() ==
          google::cloud::StatusCode::kUnauthenticated) {
        std::cout << "error [" << instance.status() << "]";
        if (!expired) {
          std::cout << ": unexpected, but could be a race condition."
                    << " Trying again\n";
          return true;
        }
        std::cout << ": this is expected as the token is expired\n";
        return false;
      }
      if (!instance) throw std::runtime_error(instance.status().message());
      std::cout << "success (" << instance->name() << ")\n";
      return true;
    }
    return false;
  };

  for (auto now = std::chrono::system_clock::now(); now < deadline;
       now = std::chrono::system_clock::now()) {
    auto const expired = (now > expiration);
    std::cout << absl::FromChrono(now) << ": running iteration with "
              << (expired ? "an expired" : "a valid") << " token ";
    if (!iteration(expired)) break;
    std::this_thread::sleep_for(kTokenValidationPeriod);
  }
}

void UseIdTokenHttp(google::cloud::iam::IAMCredentialsClient client,
                    std::vector<std::string> const& argv) {
  namespace iam = ::google::cloud::iam;
  [](iam::IAMCredentialsClient client, std::string const& service_account,
     std::string const& hello_world_url) {
    auto token = client.GenerateIdToken(
        "projects/-/serviceAccounts/" + service_account, /*delegates=*/{},
        /*audience=*/{hello_world_url},
        /*include_email=*/true);
    if (!token) throw std::runtime_error(token.status().message());

    auto backoff = std::chrono::milliseconds(250);
    for (int i = 0; i != 3; ++i) {
      auto text = HttpGet(hello_world_url, token->token());
      if (text.ok()) {
        std::cout << "Server says: " << *text << "\n";
        return;
      }
      std::this_thread::sleep_for(backoff);
      backoff *= 2;
    }
    throw std::runtime_error("Could not contact server after 3 attempts");
  }(std::move(client), argv.at(0), argv.at(1));
}

void UseIdTokenGrpc(google::cloud::iam::IAMCredentialsClient client,
                    std::vector<std::string> const& argv) {
  namespace iam = ::google::cloud::iam;
  [](iam::IAMCredentialsClient client, std::string const& service_account,
     std::string const& url) {
    auto token = client.GenerateIdToken(
        "projects/-/serviceAccounts/" + service_account, /*delegates=*/{},
        /*audience=*/{url},
        /*include_email=*/true);
    if (!token) throw std::runtime_error(token.status().message());

    auto const prefix = std::string{"https://"};
    if (url.rfind(prefix, 0) != 0) {
      throw std::runtime_error("Invalid URL" + url);
    }
    auto endpoint = url.substr(prefix.length()) + ":443";
    auto credentials = grpc::CompositeChannelCredentials(
        grpc::SslCredentials(grpc::SslCredentialsOptions{}),
        grpc::AccessTokenCredentials(token->token()));
    auto channel = grpc::CreateChannel(endpoint, credentials);
    auto stub = google::cloud::examples::Greet::NewStub(channel);
    auto request = google::cloud::examples::HelloRequest{};
    auto backoff = std::chrono::milliseconds(250);
    for (int i = 0; i != 3; ++i) {
      grpc::ClientContext context;
      google::cloud::examples::HelloResponse response;
      auto status = stub->Hello(&context, request, &response);
      if (status.ok()) {
        std::cout << "Servers says: " << response.greeting() << "\n";
        return;
      }
      std::cout << "Server returned error=" << status.error_code()
                << ", message=" << status.error_message() << "\n";
      std::this_thread::sleep_for(backoff);
      backoff *= 2;
    }
    throw std::runtime_error("Could not contact server after 3 attempts");
  }(std::move(client), argv.at(0), argv.at(1));
}

void AutoRun(std::vector<std::string> const& argv) {
  namespace examples = ::google::cloud::testing_util;
  using ::google::cloud::internal::GetEnv;

  if (!argv.empty()) throw examples::Usage{"auto"};
  examples::CheckEnvironmentVariablesAreSet({
      "GOOGLE_CLOUD_PROJECT",
      "GOOGLE_CLOUD_CPP_IAM_TEST_SERVICE_ACCOUNT",
      "GOOGLE_CLOUD_CPP_TEST_HELLO_WORLD_SERVICE_ACCOUNT",
      "GOOGLE_CLOUD_CPP_TEST_HELLO_WORLD_HTTP_URL",
      "GOOGLE_CLOUD_CPP_TEST_HELLO_WORLD_GRPC_URL",
  });
  auto project_id = GetEnv("GOOGLE_CLOUD_PROJECT").value();
  auto const test_iam_service_account =
      GetEnv("GOOGLE_CLOUD_CPP_IAM_TEST_SERVICE_ACCOUNT").value_or("");
  auto const hello_world_service_account =
      GetEnv("GOOGLE_CLOUD_CPP_TEST_HELLO_WORLD_SERVICE_ACCOUNT").value_or("");
  auto const hello_world_http_url =
      GetEnv("GOOGLE_CLOUD_CPP_TEST_HELLO_WORLD_HTTP_URL").value_or("");
  auto const hello_world_grpc_url =
      GetEnv("GOOGLE_CLOUD_CPP_TEST_HELLO_WORLD_GRPC_URL").value_or("");

  auto client = google::cloud::iam::IAMCredentialsClient(
      google::cloud::iam::MakeIAMCredentialsConnection(
          google::cloud::Options{}
              .set<google::cloud::TracingComponentsOption>(
                  DefaultTracingComponents())
              .set<google::cloud::GrpcTracingOptionsOption>(
                  // There are some credentials returned by RPCs. On an error
                  // these are printed. This truncates them, making the output
                  // safe, and yet useful for debugging.
                  google::cloud::TracingOptions{}.SetOptions(
                      "truncate_string_field_longer_than=32"))));

  std::cout << "\nRunning UseAccessToken() example" << std::endl;
  UseAccessToken(client, {test_iam_service_account, project_id});

  std::cout << "\nRunning UseAccessTokenUntilExpired() example" << std::endl;
  UseAccessTokenUntilExpired(client, {test_iam_service_account, project_id});

  std::cout << "\nRunning UseIdTokenHttp() example" << std::endl;
  UseIdTokenHttp(client, {hello_world_service_account, hello_world_http_url});

  std::cout << "\nRunning UseIdTokenGrpc() example" << std::endl;
  UseIdTokenGrpc(client, {hello_world_service_account, hello_world_grpc_url});
}

}  // namespace

int main(int argc, char* argv[]) {  // NOLINT(bugprone-exception-escape)
  using ::google::cloud::testing_util::Example;

  using ClientCommand = std::function<void(
      google::cloud::iam::IAMCredentialsClient, std::vector<std::string> argv)>;

  auto make_entry = [](std::string name,
                       std::vector<std::string> const& arg_names,
                       ClientCommand const& command) {
    auto adapter = [=](std::vector<std::string> argv) {
      if ((argv.size() == 1 && argv[0] == "--help") ||
          argv.size() != arg_names.size()) {
        std::string usage = name;
        for (auto const& a : arg_names) usage += " <" + a + ">";
        throw google::cloud::testing_util::Usage{std::move(usage)};
      }
      auto client = google::cloud::iam::IAMCredentialsClient(
          google::cloud::iam::MakeIAMCredentialsConnection(
              google::cloud::Options{}
                  .set<google::cloud::TracingComponentsOption>(
                      DefaultTracingComponents())));
      command(client, std::move(argv));
    };
    return google::cloud::testing_util::Commands::value_type(std::move(name),
                                                             adapter);
  };

  Example example({
      make_entry("use-access-token", {"service-account", "project-id"},
                 UseAccessToken),
      make_entry("use-access-token-until-expired",
                 {"service-account", "project-id"}, UseAccessTokenUntilExpired),
      make_entry("use-id-token-http",
                 {"service-account", "hello-world-http-url"}, UseIdTokenHttp),
      make_entry("use-id-token-grpc",
                 {"service-account", "hello-world-http-url"}, UseIdTokenGrpc),
      {"auto", AutoRun},
  });
  return example.Run(argc, argv);
}
<commit_msg>cleanup: miscellanous clang-tidy 14 fixes (#8718)<commit_after>// Copyright 2021 Google LLC
//
// 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 "google/cloud/iam/iam_credentials_client.h"
#include "google/cloud/spanner/admin/instance_admin_client.h"
#include "google/cloud/common_options.h"
#include "google/cloud/grpc_options.h"
#include "google/cloud/internal/getenv.h"
#include "google/cloud/log.h"
#include "google/cloud/project.h"
#include "google/cloud/testing_util/example_driver.h"
#include "absl/strings/str_split.h"
#include "absl/time/time.h"  // NOLINT(modernize-deprecated-headers)
#include <curl/curl.h>
#include <hello_world_grpc/hello_world.grpc.pb.h>
#include <chrono>
#include <stdexcept>
#include <thread>

namespace {

auto constexpr kTokenValidationPeriod = std::chrono::seconds(30);

extern "C" size_t CurlOnWriteData(char* ptr, size_t size, size_t nmemb,
                                  void* userdata) {
  auto* buffer = reinterpret_cast<std::string*>(userdata);
  buffer->append(ptr, size * nmemb);
  return size * nmemb;
}

google::cloud::StatusOr<std::string> HttpGet(std::string const& url,
                                             std::string const& token) {
  static auto const kCurlInit = [] {
    return curl_global_init(CURL_GLOBAL_ALL);
  }();
  (void)kCurlInit;
  auto const authorization = "Authorization: Bearer " + token;
  using Headers = std::unique_ptr<curl_slist, decltype(&curl_slist_free_all)>;
  auto const headers = Headers{
      curl_slist_append(nullptr, authorization.c_str()), curl_slist_free_all};
  using CurlHandle = std::unique_ptr<CURL, decltype(&curl_easy_cleanup)>;
  auto curl = CurlHandle(curl_easy_init(), curl_easy_cleanup);
  if (!curl) throw std::runtime_error("Failed to create CurlHandle");
  std::string buffer;
  curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str());
  curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, headers.get());
  curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, &CurlOnWriteData);
  curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &buffer);

  CURLcode code = curl_easy_perform(curl.get());
  if (code != CURLE_OK) throw std::runtime_error(curl_easy_strerror(code));
  long status;  // NOLINT(google-runtime-int)
  code = curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE, &status);
  if (code != CURLE_OK) throw std::runtime_error(curl_easy_strerror(code));

  // Handle common errors as Status, this is not exhaustive.
  using ::google::cloud::Status;
  using ::google::cloud::StatusCode;
  if (status == 400) return Status(StatusCode::kInvalidArgument, buffer);
  if (status == 401) return Status(StatusCode::kUnauthenticated, buffer);
  if (status == 403) return Status(StatusCode::kPermissionDenied, buffer);
  if (status >= 500) return Status(StatusCode::kInternal, buffer);
  if (status < 200 || status >= 300) {
    std::ostringstream os;
    os << "HTTP error [" << status << "]: " << buffer;
    return Status(StatusCode::kUnknown, buffer);
  }
  return buffer;
}

// TODO(#6185) - this should be done by the generated code
std::set<std::string> DefaultTracingComponents() {
  return absl::StrSplit(
      google::cloud::internal::GetEnv("GOOGLE_CLOUD_CPP_ENABLE_TRACING")
          .value_or(""),
      ',');
}

google::iam::credentials::v1::GenerateAccessTokenResponse UseAccessToken(
    google::cloud::iam::IAMCredentialsClient client,
    std::vector<std::string> const& argv) {
  namespace iam = ::google::cloud::iam;
  return [](iam::IAMCredentialsClient client,
            std::string const& service_account, std::string const& project_id) {
    google::protobuf::Duration duration;
    duration.set_seconds(
        std::chrono::seconds(2 * kTokenValidationPeriod).count());
    auto token = client.GenerateAccessToken(
        "projects/-/serviceAccounts/" + service_account, /*delegates=*/{},
        /*scope=*/{"https://www.googleapis.com/auth/cloud-platform"}, duration);
    if (!token) throw std::runtime_error(token.status().message());

    auto const expiration =
        std::chrono::system_clock::from_time_t(token->expire_time().seconds());
    std::cout << "Fetched token starting with "
              << token->access_token().substr(0, 8)
              << ", which will expire around " << absl::FromChrono(expiration)
              << std::endl;

    auto credentials = grpc::CompositeChannelCredentials(
        grpc::SslCredentials({}),
        grpc::AccessTokenCredentials(token->access_token()));

    google::cloud::spanner_admin::InstanceAdminClient admin(
        google::cloud::spanner_admin::MakeInstanceAdminConnection(
            google::cloud::Options{}.set<google::cloud::GrpcCredentialOption>(
                credentials)));
    for (auto instance :
         admin.ListInstances(google::cloud::Project(project_id).FullName())) {
      if (!instance) throw std::runtime_error(instance.status().message());
      std::cout << "Instance: " << instance->name() << "\n";
    }

    return *std::move(token);
  }(std::move(client), argv.at(0), argv.at(1));
}

void UseAccessTokenUntilExpired(google::cloud::iam::IAMCredentialsClient client,
                                std::vector<std::string> const& argv) {
  auto token = UseAccessToken(std::move(client), argv);
  auto const& project_id = argv.at(1);
  auto const expiration =
      std::chrono::system_clock::from_time_t(token.expire_time().seconds());
  auto const deadline = expiration + 4 * kTokenValidationPeriod;
  std::cout << "Running until " << absl::FromChrono(deadline)
            << ". This is past the access token expiration time ("
            << absl::FromChrono(expiration) << ")" << std::endl;

  auto iteration = [=](bool expired) {
    auto credentials = grpc::CompositeChannelCredentials(
        grpc::SslCredentials({}),
        grpc::AccessTokenCredentials(token.access_token()));
    google::cloud::spanner_admin::InstanceAdminClient admin(
        google::cloud::spanner_admin::MakeInstanceAdminConnection(
            google::cloud::Options{}.set<google::cloud::GrpcCredentialOption>(
                credentials)));
    for (auto instance :
         admin.ListInstances(google::cloud::Project(project_id).FullName())) {
      // kUnauthenticated receives special treatment, it is the error received
      // when the token expires.
      if (instance.status().code() ==
          google::cloud::StatusCode::kUnauthenticated) {
        std::cout << "error [" << instance.status() << "]";
        if (!expired) {
          std::cout << ": unexpected, but could be a race condition."
                    << " Trying again\n";
          return true;
        }
        std::cout << ": this is expected as the token is expired\n";
        return false;
      }
      if (!instance) throw std::runtime_error(instance.status().message());
      std::cout << "success (" << instance->name() << ")\n";
      return true;
    }
    return false;
  };

  for (auto now = std::chrono::system_clock::now(); now < deadline;
       now = std::chrono::system_clock::now()) {
    auto const expired = (now > expiration);
    std::cout << absl::FromChrono(now) << ": running iteration with "
              << (expired ? "an expired" : "a valid") << " token ";
    if (!iteration(expired)) break;
    std::this_thread::sleep_for(kTokenValidationPeriod);
  }
}

void UseIdTokenHttp(google::cloud::iam::IAMCredentialsClient client,
                    std::vector<std::string> const& argv) {
  namespace iam = ::google::cloud::iam;
  [](iam::IAMCredentialsClient client, std::string const& service_account,
     std::string const& hello_world_url) {
    auto token = client.GenerateIdToken(
        "projects/-/serviceAccounts/" + service_account, /*delegates=*/{},
        /*audience=*/{hello_world_url},
        /*include_email=*/true);
    if (!token) throw std::runtime_error(token.status().message());

    auto backoff = std::chrono::milliseconds(250);
    for (int i = 0; i != 3; ++i) {
      auto text = HttpGet(hello_world_url, token->token());
      if (text.ok()) {
        std::cout << "Server says: " << *text << "\n";
        return;
      }
      std::this_thread::sleep_for(backoff);
      backoff *= 2;
    }
    throw std::runtime_error("Could not contact server after 3 attempts");
  }(std::move(client), argv.at(0), argv.at(1));
}

void UseIdTokenGrpc(google::cloud::iam::IAMCredentialsClient client,
                    std::vector<std::string> const& argv) {
  namespace iam = ::google::cloud::iam;
  [](iam::IAMCredentialsClient client, std::string const& service_account,
     std::string const& url) {
    auto token = client.GenerateIdToken(
        "projects/-/serviceAccounts/" + service_account, /*delegates=*/{},
        /*audience=*/{url},
        /*include_email=*/true);
    if (!token) throw std::runtime_error(token.status().message());

    auto const prefix = std::string{"https://"};
    if (url.rfind(prefix, 0) != 0) {
      throw std::runtime_error("Invalid URL" + url);
    }
    auto endpoint = url.substr(prefix.length()) + ":443";
    auto credentials = grpc::CompositeChannelCredentials(
        grpc::SslCredentials(grpc::SslCredentialsOptions{}),
        grpc::AccessTokenCredentials(token->token()));
    auto channel = grpc::CreateChannel(endpoint, credentials);
    auto stub = google::cloud::examples::Greet::NewStub(channel);
    auto request = google::cloud::examples::HelloRequest{};
    auto backoff = std::chrono::milliseconds(250);
    for (int i = 0; i != 3; ++i) {
      grpc::ClientContext context;
      google::cloud::examples::HelloResponse response;
      auto status = stub->Hello(&context, request, &response);
      if (status.ok()) {
        std::cout << "Servers says: " << response.greeting() << "\n";
        return;
      }
      std::cout << "Server returned error=" << status.error_code()
                << ", message=" << status.error_message() << "\n";
      std::this_thread::sleep_for(backoff);
      backoff *= 2;
    }
    throw std::runtime_error("Could not contact server after 3 attempts");
  }(std::move(client), argv.at(0), argv.at(1));
}

void AutoRun(std::vector<std::string> const& argv) {
  namespace examples = ::google::cloud::testing_util;
  using ::google::cloud::internal::GetEnv;

  if (!argv.empty()) throw examples::Usage{"auto"};
  examples::CheckEnvironmentVariablesAreSet({
      "GOOGLE_CLOUD_PROJECT",
      "GOOGLE_CLOUD_CPP_IAM_TEST_SERVICE_ACCOUNT",
      "GOOGLE_CLOUD_CPP_TEST_HELLO_WORLD_SERVICE_ACCOUNT",
      "GOOGLE_CLOUD_CPP_TEST_HELLO_WORLD_HTTP_URL",
      "GOOGLE_CLOUD_CPP_TEST_HELLO_WORLD_GRPC_URL",
  });
  auto project_id = GetEnv("GOOGLE_CLOUD_PROJECT").value();
  auto const test_iam_service_account =
      GetEnv("GOOGLE_CLOUD_CPP_IAM_TEST_SERVICE_ACCOUNT").value_or("");
  auto const hello_world_service_account =
      GetEnv("GOOGLE_CLOUD_CPP_TEST_HELLO_WORLD_SERVICE_ACCOUNT").value_or("");
  auto const hello_world_http_url =
      GetEnv("GOOGLE_CLOUD_CPP_TEST_HELLO_WORLD_HTTP_URL").value_or("");
  auto const hello_world_grpc_url =
      GetEnv("GOOGLE_CLOUD_CPP_TEST_HELLO_WORLD_GRPC_URL").value_or("");

  auto client = google::cloud::iam::IAMCredentialsClient(
      google::cloud::iam::MakeIAMCredentialsConnection(
          google::cloud::Options{}
              .set<google::cloud::TracingComponentsOption>(
                  DefaultTracingComponents())
              .set<google::cloud::GrpcTracingOptionsOption>(
                  // There are some credentials returned by RPCs. On an error
                  // these are printed. This truncates them, making the output
                  // safe, and yet useful for debugging.
                  google::cloud::TracingOptions{}.SetOptions(
                      "truncate_string_field_longer_than=32"))));

  std::cout << "\nRunning UseAccessToken() example" << std::endl;
  UseAccessToken(client, {test_iam_service_account, project_id});

  std::cout << "\nRunning UseAccessTokenUntilExpired() example" << std::endl;
  UseAccessTokenUntilExpired(client, {test_iam_service_account, project_id});

  std::cout << "\nRunning UseIdTokenHttp() example" << std::endl;
  UseIdTokenHttp(client, {hello_world_service_account, hello_world_http_url});

  std::cout << "\nRunning UseIdTokenGrpc() example" << std::endl;
  UseIdTokenGrpc(client, {hello_world_service_account, hello_world_grpc_url});
}

}  // namespace

int main(int argc, char* argv[]) {  // NOLINT(bugprone-exception-escape)
  using ::google::cloud::testing_util::Example;

  using ClientCommand = std::function<void(
      google::cloud::iam::IAMCredentialsClient, std::vector<std::string> argv)>;

  auto make_entry = [](std::string name,
                       std::vector<std::string> const& arg_names,
                       ClientCommand const& command) {
    auto adapter = [=](std::vector<std::string> argv) {
      if ((argv.size() == 1 && argv[0] == "--help") ||
          argv.size() != arg_names.size()) {
        std::string usage = name;
        for (auto const& a : arg_names) usage += " <" + a + ">";
        throw google::cloud::testing_util::Usage{std::move(usage)};
      }
      auto client = google::cloud::iam::IAMCredentialsClient(
          google::cloud::iam::MakeIAMCredentialsConnection(
              google::cloud::Options{}
                  .set<google::cloud::TracingComponentsOption>(
                      DefaultTracingComponents())));
      command(client, std::move(argv));
    };
    return google::cloud::testing_util::Commands::value_type(std::move(name),
                                                             adapter);
  };

  Example example({
      make_entry("use-access-token", {"service-account", "project-id"},
                 UseAccessToken),
      make_entry("use-access-token-until-expired",
                 {"service-account", "project-id"}, UseAccessTokenUntilExpired),
      make_entry("use-id-token-http",
                 {"service-account", "hello-world-http-url"}, UseIdTokenHttp),
      make_entry("use-id-token-grpc",
                 {"service-account", "hello-world-http-url"}, UseIdTokenGrpc),
      {"auto", AutoRun},
  });
  return example.Run(argc, argv);
}
<|endoftext|>


<commit_before>#include "OneDMomentumFriction.h"
#include "EquationOfState.h"

template<>
InputParameters validParams<OneDMomentumFriction>()
{
  InputParameters params = validParams<Kernel>();

  // Required coupled variables
  params.addRequiredCoupledVar("rhoA", "density term");
  params.addRequiredCoupledVar("rhouA", "momentum term");
  params.addRequiredCoupledVar("u", "velocity");
  params.addRequiredCoupledVar("hydraulic_diameter", "The hydraulic diameter. Depends on A(x).");

  return params;
}

OneDMomentumFriction::OneDMomentumFriction(const std::string & name, InputParameters parameters) :
    Kernel(name, parameters),
    _u_vel(coupledValue("u")),
    _rhouA(coupledValue("rhouA")),
    _hydraulic_diameter(coupledValue("hydraulic_diameter")),
    _rhoA_var_number(coupled("rhoA")),
    _friction(getMaterialProperty<Real>("friction"))
{
}

Real
OneDMomentumFriction::computeQpResidual()
{
  // Contribution due to friction.
  return (0.5*_friction[_qp]/_hydraulic_diameter[_qp]) * _rhouA[_qp] * std::abs(_u_vel[_qp]) * _test[_i][_qp];
}

Real
OneDMomentumFriction::computeQpJacobian()
{
  return (0.5*_friction[_qp]/_hydraulic_diameter[_qp]) * 2. * std::abs(_u_vel[_qp]) * _phi[_j][_qp] * _test[_i][_qp];
}

Real
OneDMomentumFriction::computeQpOffDiagJacobian(unsigned int jvar)
{
  if (jvar == _rhoA_var_number)
    return (0.5*_friction[_qp]/_hydraulic_diameter[_qp]) * (-_u_vel[_qp]) * std::abs(_u_vel[_qp]) * _phi[_j][_qp] * _test[_i][_qp];
  else
    return 0.;
}
<commit_msg>Removing EoS system from the code<commit_after>#include "OneDMomentumFriction.h"

template<>
InputParameters validParams<OneDMomentumFriction>()
{
  InputParameters params = validParams<Kernel>();

  // Required coupled variables
  params.addRequiredCoupledVar("rhoA", "density term");
  params.addRequiredCoupledVar("rhouA", "momentum term");
  params.addRequiredCoupledVar("u", "velocity");
  params.addRequiredCoupledVar("hydraulic_diameter", "The hydraulic diameter. Depends on A(x).");

  return params;
}

OneDMomentumFriction::OneDMomentumFriction(const std::string & name, InputParameters parameters) :
    Kernel(name, parameters),
    _u_vel(coupledValue("u")),
    _rhouA(coupledValue("rhouA")),
    _hydraulic_diameter(coupledValue("hydraulic_diameter")),
    _rhoA_var_number(coupled("rhoA")),
    _friction(getMaterialProperty<Real>("friction"))
{
}

Real
OneDMomentumFriction::computeQpResidual()
{
  // Contribution due to friction.
  return (0.5*_friction[_qp]/_hydraulic_diameter[_qp]) * _rhouA[_qp] * std::abs(_u_vel[_qp]) * _test[_i][_qp];
}

Real
OneDMomentumFriction::computeQpJacobian()
{
  return (0.5*_friction[_qp]/_hydraulic_diameter[_qp]) * 2. * std::abs(_u_vel[_qp]) * _phi[_j][_qp] * _test[_i][_qp];
}

Real
OneDMomentumFriction::computeQpOffDiagJacobian(unsigned int jvar)
{
  if (jvar == _rhoA_var_number)
    return (0.5*_friction[_qp]/_hydraulic_diameter[_qp]) * (-_u_vel[_qp]) * std::abs(_u_vel[_qp]) * _phi[_j][_qp] * _test[_i][_qp];
  else
    return 0.;
}
<|endoftext|>