<commit_before>/*
 * Copyright (c) 2011-2013 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef LIBBITCOIN_DEFINE_HPP
#define LIBBITCOIN_DEFINE_HPP

// Create bc namespace alias.
namespace libbitcoin {
} // namespace libbitcoin

namespace bc = libbitcoin;

// Logger definitions. You can add your own to the logger.
// Better to use a define because you get type safety.
#define LOG_NETWORK     "network"
#define LOG_BLOCKCHAIN  "blockchain"
#define LOG_VALIDATE    "validate"
#define LOG_PROTOCOL    "protocol"
#define LOG_POLLER      "poller"
#define LOG_SESSION     "session"
#define LOG_SCRIPT      "script"
#define LOG_TXPOOL      "transaction_pool"
#define LOG_TXIDX       "transaction_indexer"

// See http://gcc.gnu.org/wiki/Visibility

// Generic helper definitions for shared library support
#if defined _MSC_VER || defined __CYGWIN__
    #define BC_HELPER_DLL_IMPORT __declspec(dllimport)
    #define BC_HELPER_DLL_EXPORT __declspec(dllexport)
    #define BC_HELPER_DLL_LOCAL
#else
    #if __GNUC__ >= 4
        #define BC_HELPER_DLL_IMPORT __attribute__ ((visibility ("default")))
        #define BC_HELPER_DLL_EXPORT __attribute__ ((visibility ("default")))
        #define BC_HELPER_DLL_LOCAL  __attribute__ ((visibility ("internal")))
    #else
        #define BC_HELPER_DLL_IMPORT
        #define BC_HELPER_DLL_EXPORT
        #define BC_HELPER_DLL_LOCAL
    #endif
#endif

// Now we use the generic helper definitions above to
// define BC_API and BC_INTERNAL.
// BC_API is used for the public API symbols. It either DLL imports or
// DLL exports (or does nothing for static build)
// BC_INTERNAL is used for non-api symbols.

#if defined BC_STATIC
    #define BC_API
    #define BC_INTERNAL
#elif defined BC_DLL
    #define BC_API      BC_HELPER_DLL_EXPORT
    #define BC_INTERNAL BC_HELPER_DLL_LOCAL
#else
    #define BC_API      BC_HELPER_DLL_IMPORT
    #define BC_INTERNAL BC_HELPER_DLL_LOCAL
#endif

// Tag to deprecate functions and methods.
// Gives a compiler warning when they are used.
#if defined _MSC_VER || defined __CYGWIN__
    #define BC_DEPRECATED __declspec(deprecated)
#else
    #if __GNUC__ >= 4
        #define BC_DEPRECATED __attribute__((deprecated))
    #else
        #define BC_DEPRECATED
    #endif
#endif

// Remove this when cURL dependency is fully removed.
#define NO_CURL

#endif

<commit_msg>Define lcov exclusion macros.<commit_after>/*
 * Copyright (c) 2011-2013 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef LIBBITCOIN_DEFINE_HPP
#define LIBBITCOIN_DEFINE_HPP

// Create bc namespace alias.
namespace libbitcoin {
} // namespace libbitcoin

namespace bc = libbitcoin;

// Logger definitions. You can add your own to the logger.
// Better to use a define because you get type safety.
#define LOG_NETWORK     "network"
#define LOG_BLOCKCHAIN  "blockchain"
#define LOG_VALIDATE    "validate"
#define LOG_PROTOCOL    "protocol"
#define LOG_POLLER      "poller"
#define LOG_SESSION     "session"
#define LOG_SCRIPT      "script"
#define LOG_TXPOOL      "transaction_pool"
#define LOG_TXIDX       "transaction_indexer"

// See http://gcc.gnu.org/wiki/Visibility

// Generic helper definitions for shared library support
#if defined _MSC_VER || defined __CYGWIN__
    #define BC_HELPER_DLL_IMPORT __declspec(dllimport)
    #define BC_HELPER_DLL_EXPORT __declspec(dllexport)
    #define BC_HELPER_DLL_LOCAL
#else
    #if __GNUC__ >= 4
        #define BC_HELPER_DLL_IMPORT __attribute__ ((visibility ("default")))
        #define BC_HELPER_DLL_EXPORT __attribute__ ((visibility ("default")))
        #define BC_HELPER_DLL_LOCAL  __attribute__ ((visibility ("internal")))
    #else
        #define BC_HELPER_DLL_IMPORT
        #define BC_HELPER_DLL_EXPORT
        #define BC_HELPER_DLL_LOCAL
    #endif
#endif

// Now we use the generic helper definitions above to
// define BC_API and BC_INTERNAL.
// BC_API is used for the public API symbols. It either DLL imports or
// DLL exports (or does nothing for static build)
// BC_INTERNAL is used for non-api symbols.

#if defined BC_STATIC
    #define BC_API
    #define BC_INTERNAL
#elif defined BC_DLL
    #define BC_API      BC_HELPER_DLL_EXPORT
    #define BC_INTERNAL BC_HELPER_DLL_LOCAL
#else
    #define BC_API      BC_HELPER_DLL_IMPORT
    #define BC_INTERNAL BC_HELPER_DLL_LOCAL
#endif

// Tag to deprecate functions and methods.
// Gives a compiler warning when they are used.
#if defined _MSC_VER || defined __CYGWIN__
    #define BC_DEPRECATED __declspec(deprecated)
#else
    #if __GNUC__ >= 4
        #define BC_DEPRECATED __attribute__((deprecated))
    #else
        #define BC_DEPRECATED
    #endif
#endif

// Define so we can have better visibility of lcov exclusion ranges.
#define LCOV_EXCL_START(text)
#define LCOV_EXCL_STOP()

// Remove this when cURL dependency is fully removed.
#define NO_CURL

#endif

<|endoftext|>


<commit_before>/*
 * The MIT License
 *
 * Copyright 2017-2018 Norwegian University of Technology
 *
 * 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.
 */

#ifndef FMICPP_FMU_HPP
#define FMICPP_FMU_HPP

#include <memory>
#include <vector>
#include <boost/filesystem.hpp>

#include "../xml/ModelDescription.hpp"

namespace fs = boost::filesystem;

using std::string;
using std::unique_ptr;
using fmicpp::fmi2::xml::ModelDescription;

namespace fmicpp::fmi2::import {

    class Fmu {

        friend class CoSimulationSlaveBuilder;
        friend class ModelExchangeInstanceBuilder;

    public:
        explicit Fmu(const string &fmu_file);

        const string getGuid() const;
        const string getModelName() const;
        const string getModelDescriptionXml() const;
        const ModelDescription &getModelDescription() const;

        const bool supportsModelExchange() const;
        const bool supportsCoSimulation() const;

        CoSimulationSlaveBuilder &asCoSimulationFmu();
        ModelExchangeInstanceBuilder &asModelExchangeFmu();

        ~Fmu();

    private:

        fs::path tmp_path_;
        const string fmu_file_;
        unique_ptr<ModelDescription> modelDescription_;
        unique_ptr<CoSimulationSlaveBuilder> csBuilder_;
        unique_ptr<ModelExchangeInstanceBuilder> meBuilder_;

        const string getModelDescriptionPath() const;
        const string getResourcePath() const;
        const string getAbsoluteLibraryPath(string modelIdentifier) const;

    };

}

#endif //FMICPP_FMU_HPP
<commit_msg>fix compile error<commit_after>/*
 * The MIT License
 *
 * Copyright 2017-2018 Norwegian University of Technology
 *
 * 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.
 */

#ifndef FMICPP_FMU_HPP
#define FMICPP_FMU_HPP

#include <memory>
#include <vector>
#include <boost/filesystem.hpp>

#include "../xml/ModelDescription.hpp"

namespace fs = boost::filesystem;

using std::string;
using std::unique_ptr;
using fmicpp::fmi2::xml::ModelDescription;

namespace fmicpp::fmi2::import {

    class CoSimulationSlaveBuilder;
    class ModelExchangeInstanceBuilder;

    class Fmu {

        friend class CoSimulationSlaveBuilder;
        friend class ModelExchangeInstanceBuilder;

    public:
        explicit Fmu(const string &fmu_file);

        const string getGuid() const;
        const string getModelName() const;
        const string getModelDescriptionXml() const;
        const ModelDescription &getModelDescription() const;

        const bool supportsModelExchange() const;
        const bool supportsCoSimulation() const;

        CoSimulationSlaveBuilder &asCoSimulationFmu();
        ModelExchangeInstanceBuilder &asModelExchangeFmu();

        ~Fmu();

    private:

        fs::path tmp_path_;
        const string fmu_file_;
        unique_ptr<ModelDescription> modelDescription_;
        unique_ptr<CoSimulationSlaveBuilder> csBuilder_;
        unique_ptr<ModelExchangeInstanceBuilder> meBuilder_;

        const string getModelDescriptionPath() const;
        const string getResourcePath() const;
        const string getAbsoluteLibraryPath(string modelIdentifier) const;

    };

}

#endif //FMICPP_FMU_HPP
<|endoftext|>


<commit_before>#include "per_vertex_normals.h"

#include "per_face_normals.h"
#include "normalize_row_lengths.h"

template <typename DerivedV, typename DerivedF>
IGL_INLINE void igl::per_vertex_normals(
  const Eigen::PlainObjectBase<DerivedV>& V,
  const Eigen::PlainObjectBase<DerivedF>& F,
  Eigen::PlainObjectBase<DerivedV> & N)
{
  Eigen::PlainObjectBase<DerivedV> PFN;
  igl::per_face_normals(V,F,PFN);
  return igl::per_vertex_normals(V,F,PFN,N);

  //// Resize for output
  //N = Eigen::PlainObjectBase<DerivedV>::Zero(V.rows(),3);

  //// loop over faces
  //for(int i = 0; i < F.rows();i++)
  //{
  //  // throw normal at each corner
  //  for(int j = 0; j < 3;j++)
  //  {
  //    N.row(F(i,j)) += PFN.row(i);
  //  }
  //}
  //// normalize each row
  //igl::normalize_row_lengths(N,N);
}

template <typename DerivedV, typename DerivedF>
IGL_INLINE void igl::per_vertex_normals(
  const Eigen::PlainObjectBase<DerivedV>& V,
  const Eigen::PlainObjectBase<DerivedF>& F,
  const Eigen::PlainObjectBase<DerivedV>& FN,
  Eigen::PlainObjectBase<DerivedV> & N)
{
  // Resize for output
  N.resize(V.rows(),3);

  // loop over faces
  int Frows = F.rows();
#pragma omp parallel for
  for(int i = 0; i < Frows;i++)
  {
    // throw normal at each corner
    for(int j = 0; j < 3;j++)
    {
      N.row(F(i,j)) += FN.row(i);
    }
  }
  // normalize each row
  igl::normalize_row_lengths(N,N);
}
#ifndef IGL_HEADER_ONLY
// Explicit template specialization
// generated by autoexplicit.sh
template void igl::per_vertex_normals<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
template void igl::per_vertex_normals<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, -1, 1, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<unsigned int, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&);
template void igl::per_vertex_normals<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
#endif
<commit_msg>Fixed initialization of N matrix<commit_after>#include "per_vertex_normals.h"

#include "per_face_normals.h"
#include "normalize_row_lengths.h"

template <typename DerivedV, typename DerivedF>
IGL_INLINE void igl::per_vertex_normals(
  const Eigen::PlainObjectBase<DerivedV>& V,
  const Eigen::PlainObjectBase<DerivedF>& F,
  Eigen::PlainObjectBase<DerivedV> & N)
{
  Eigen::PlainObjectBase<DerivedV> PFN;
  igl::per_face_normals(V,F,PFN);
  return igl::per_vertex_normals(V,F,PFN,N);

  //// Resize for output
  //N = Eigen::PlainObjectBase<DerivedV>::Zero(V.rows(),3);

  //// loop over faces
  //for(int i = 0; i < F.rows();i++)
  //{
  //  // throw normal at each corner
  //  for(int j = 0; j < 3;j++)
  //  {
  //    N.row(F(i,j)) += PFN.row(i);
  //  }
  //}
  //// normalize each row
  //igl::normalize_row_lengths(N,N);
}

template <typename DerivedV, typename DerivedF>
IGL_INLINE void igl::per_vertex_normals(
  const Eigen::PlainObjectBase<DerivedV>& V,
  const Eigen::PlainObjectBase<DerivedF>& F,
  const Eigen::PlainObjectBase<DerivedV>& FN,
  Eigen::PlainObjectBase<DerivedV> & N)
{
  // Resize for output
  N.setZero(V.rows(),3);

  // loop over faces
  int Frows = F.rows();
#pragma omp parallel for
  for(int i = 0; i < Frows;i++)
  {
    // throw normal at each corner
    for(int j = 0; j < 3;j++)
    {
      N.row(F(i,j)) += FN.row(i);
    }
  }
  cout << "N.row()" << N.row(0) << endl;
  // normalize each row
  igl::normalize_row_lengths(N,N);
}
#ifndef IGL_HEADER_ONLY
// Explicit template specialization
// generated by autoexplicit.sh
template void igl::per_vertex_normals<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
template void igl::per_vertex_normals<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, -1, 1, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<unsigned int, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&);
template void igl::per_vertex_normals<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
#endif
<|endoftext|>


<commit_before>namespace mant {

}
<commit_msg>devel: Added some definitions to the property base class<commit_after>namespace mant {
  template <typename ParameterType>
  class Property {
    public:
      explicit Property();

      double getPlausibility() const noexcept;

    protected:
      double plausibility_;
  };

  //
  // Implementation
  //

  template <typename ParameterType>
  Property<ParameterType>::Property()
    : plausibility_(0) {

  }

  template <typename ParameterType>
  double Property<ParameterType>::getPlausibility() const noexcept {
    return plausibility_;
  }
}
<|endoftext|>


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

  nomlib - C++11 cross-platform game engine

Copyright (c) 2013, Jeffrey Carpenter <jeffrey.carp@gmail.com>
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.

******************************************************************************/
#ifndef NOMLIB_SDL_CANVAS_HEADERS
#define NOMLIB_SDL_CANVAS_HEADERS

#include <iostream>
#include <string>
#include <memory>

#include <SDL/SDL.h>

#include "nomlib/config.hpp"
//#include "nomlib/graphics/ICanvas.hpp"
#include "nomlib/sdl/utils.hpp"
#include "nomlib/math/Color.hpp"
#include "nomlib/math/Coords.hpp"
#include "nomlib/system/ObjectCache.hpp"
#include "nomlib/graphics/Image.hpp"
#include "nomlib/graphics/Rectangle.hpp"

namespace nom {
  namespace priv {

/// Custom deleter for SDL_Surface* smart pointers; can be used as a debugging
/// aid.
void Canvas_FreeSurface ( SDL_Surface* );

  } // namespace priv
} // namespace nom

namespace nom {

/// Available rescaling algorithms
enum ResizeAlgorithm
{
  None = 0, // No resizing is applied
  scale2x,
  scale3x, // Reserved for future implementation
  scale4x, // Reserved for future implementation
  hq2x,
  hq3x, // Reserved for future implementation
  hq4x // Reserved for future implementation
};

class Canvas
{
  public:
    typedef std::shared_ptr<Canvas> SharedPtr;
    /// Default constructor; initializes object to its respective defaults
    Canvas ( void );

    /// Constructor variant for creating a video surface object with existing
    /// video surface memory.
    ///
    /// \deprecated Likely to be removed in the future.
    Canvas ( void* video_buffer );

    /// Copy constructor; create a video surface object from an existing Canvas
    /// object.
    Canvas ( const Canvas& other );

    /// Constructor variant for creating a fresh, empty video surface. You should
    /// be sure to read over the details gory details scattered throughout the
    /// documentation for SDL.
    ///
    /// The SDL_SWSURFACE flag is passed by default if an argument is not
    /// specified -- this is optimal for writing to the video memory buffer
    /// directly (pixel manipulation).
    ///
    /// As per libSDL docs, this must be called only after video initialization;
    /// (SDL_SetVideoMode).
    ///
    /// See http://sdl.beuc.net/sdl.wiki/SDL_CreateRGBSurface
    Canvas ( int32 width, int32 height, uint8 bitsPerPixel, uint32 Rmask, uint32 Gmask, uint32 Bmask, uint32 Amask, uint32 flags = SDL_SWSURFACE );

    /// Construct a video surface object using the data from an existing surface;
    /// you can think of this as a copy method. As with the previous method, you
    /// ought to read over the technicalities that the SDL library documentation
    /// covers.
    ///
    /// You remain the owner of the pointer leading to your existing data and
    /// therefore are responsible for memory management.
    ///
    /// See http://sdl.beuc.net/sdl.wiki/SDL_CreateRGBSurfaceFrom
    Canvas ( Pixels pixels, int32 width, int32 height, int32 depth, uint16 pitch, uint32 Rmask, uint32 Gmask, uint32 Bmask, uint32 Amask );

    /// Lazy destructor -- does nothing.
    ~Canvas ( void );

    /// Return a std::shared_ptr copy of this instance
    /// \todo Test me out!
    Canvas::SharedPtr clone ( void ) const;

    /// Copy assignment operator
    Canvas& operator = ( const Canvas& other );

    /// Is this object initialized -- not nullptr?
    bool valid ( void ) const;

    /// Reset the video surface object with another video surface object.
    void setCanvas ( const Canvas& surface );

    void setPosition ( const Coords& coords_ );
    void setOffsets ( const Coords& offsets_ );

    const int32 getCanvasWidth ( void ) const;
    const int32 getCanvasHeight ( void ) const;
    uint32 getCanvasFlags ( void ) const;
    uint16 getCanvasPitch ( void ) const;
    const Pixels getCanvasPixels ( void ) const;
    const uint8 getCanvasBitsPerPixel ( void ) const;

    /// \todo Rename to getCanvasPixelFormat
    const Pixels getCanvasPixelsFormat ( void ) const;

    /// Obtain the pixel value of the set transparent color
    const Color getCanvasColorKey ( void ) const;

    /// Obtain the overall surface alpha value
    const uint8 getCanvasAlphaValue ( void ) const;

    /// Obtain the video surface's red *ALPHA* mask
    const uint32 getCanvasRedMask ( void ) const;

    /// Obtain the video surface's green *ALPHA* mask
    const uint32 getCanvasGreenMask ( void ) const;

    /// Obtain the video surface's blue *ALPHA* mask
    const uint32 getCanvasBlueMask ( void ) const;

    /// Obtain the video surface's alpha mask
    const uint32 getCanvasAlphaMask ( void ) const;

    const Coords getCanvasBounds ( void ) const;
    void setCanvasBounds ( const Coords& clip_bounds );

    /// Convenience Helper method for calculating the canvas color depth; for
    /// the time being, this is merely for the convenience of readability in
    /// our code.
    ///
    /// Returns an integer of 8, 16, 24 or 32 upon successful determination of
    /// the current color depth.
    ///
    /// Returns -1 on err; perhaps an unsupported color depth or an
    /// uninitialized video surface?
    int32 getCanvasColorDepth ( void ) const;

    /// I think that we are accessing the value of an
    /// (internal?) property of the SDL_Surface structure that is described as being
    /// "private" as per the docs.
    ///
    /// Return value of this internal property is presumed to be boolean -- no
    /// verification has been made of this. Testing of this method *appears*
    /// to be in working order.
    bool getCanvasLock ( void ) const;

    /// Lock the video surface for writing directly to video memory.
    bool lock ( void ) const;

    /// Unlocks the video surface; this must be done after you are finished
    /// writing to the video buffer. During the time that the video surface is
    /// locked, no updates (think: rendering) outside of your local access can
    /// occur until the surfaces affected by the lock are relinquished.
    void unlock ( void ) const;

    /// Sets transparency only if colorkey Color alpha value is -1, also
    /// important to note is that we only have an alpha channel surface set
    /// if Color value is not -1 (the default)
    ///
    /// \internal
    /// Clean up this documentation note and also verify that it is
    /// sane to assume that you would not use transparency when you have alpha
    /// surface enabled
    /// \endinternal
    bool load ( const std::string& filename, const Color&
                colorkey = Color ( -1, -1, -1, -1 ),
                bool use_cache = false,
                uint32 flags = SDL_RLEACCEL | SDL_SRCCOLORKEY
              );

    bool Update ( void* video_buffer );
    void Draw ( void* video_buffer ) const;

    bool setAlpha ( uint8 opacity, uint32 flags = SDL_SRCALPHA );

    bool setTransparent ( const Color& color = Color ( 0, 0, 0, -1 ),
                          uint32 flags = SDL_RLEACCEL | SDL_SRCCOLORKEY
                        );

    /// As per libSDL docs, we must first initialize the video subsystem before using
    /// this method call, otherwise an access violation fault is sure to occur.
    bool displayFormat ( void );
    /// As per libSDL docs, we must first initialize the video subsystem before using
    /// this method call, otherwise an access violation fault is sure to occur.
    bool displayFormatAlpha ( void );

    /// \internal
    /// Note: this method is not meant to be called inside a loop; memory usage may
    /// run a mock (seems to be fixed by Rectangle::~Rectangle() inside the
    /// Rectangle class, although it eludes me as to why precisely
    /// \endinternal
    void clear ( const Color& color = Color::Blue ) const;

    /// Pixel reading -- supports 8-bit, 15/16-bit, 24-bit & 32-bit color modes
    ///
    /// Returns -1 on error
    ///
    /// You are responsible for locking & unlocking of the canvas before-hand
    ///
    /// \todo Test 8-bit, 15/16-bit & 24-bit pixels
    int32 getPixel ( int32 x, int32 y );

    /// Resize the video surface with the chosen rescaling algorithm.
    ///
    /// See the ResizeAlgorithm enum for available rescaling algorithms
    bool resize ( enum ResizeAlgorithm scaling_algorithm );

  private:
    /// Internal method used for checking to see if the video surface actually
    /// needs to be locked before doing so for performance sake.
    bool mustLock ( void ) const;

    /// Return the correct scaling factor of the chosen algorithm
    int32 getResizeScaleFactor ( enum ResizeAlgorithm scaling_algorithm );

    std::shared_ptr<void> canvas_buffer; // SDL_Surface*
    /// Holds surface position
    Coords coords;
    /// Holds surface bounds (input clipping)
    Coords offsets;
};

} // namespace nom

#endif // NOMLIB_SDL_CANVAS_HEADERS defined
<commit_msg>Make getResizeScaleFactor method public<commit_after>/******************************************************************************

  nomlib - C++11 cross-platform game engine

Copyright (c) 2013, Jeffrey Carpenter <jeffrey.carp@gmail.com>
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.

******************************************************************************/
#ifndef NOMLIB_SDL_CANVAS_HEADERS
#define NOMLIB_SDL_CANVAS_HEADERS

#include <iostream>
#include <string>
#include <memory>

#include <SDL/SDL.h>

#include "nomlib/config.hpp"
//#include "nomlib/graphics/ICanvas.hpp"
#include "nomlib/sdl/utils.hpp"
#include "nomlib/math/Color.hpp"
#include "nomlib/math/Coords.hpp"
#include "nomlib/system/ObjectCache.hpp"
#include "nomlib/graphics/Image.hpp"
#include "nomlib/graphics/Rectangle.hpp"

namespace nom {
  namespace priv {

/// Custom deleter for SDL_Surface* smart pointers; can be used as a debugging
/// aid.
void Canvas_FreeSurface ( SDL_Surface* );

  } // namespace priv
} // namespace nom

namespace nom {

/// Available rescaling algorithms
enum ResizeAlgorithm
{
  None = 0, // No resizing is applied
  scale2x,
  scale3x, // Reserved for future implementation
  scale4x, // Reserved for future implementation
  hq2x,
  hq3x,
  hq4x
};

class Canvas
{
  public:
    typedef std::shared_ptr<Canvas> SharedPtr;
    /// Default constructor; initializes object to its respective defaults
    Canvas ( void );

    /// Constructor variant for creating a video surface object with existing
    /// video surface memory.
    ///
    /// \deprecated Likely to be removed in the future.
    Canvas ( void* video_buffer );

    /// Copy constructor; create a video surface object from an existing Canvas
    /// object.
    Canvas ( const Canvas& other );

    /// Constructor variant for creating a fresh, empty video surface. You should
    /// be sure to read over the details gory details scattered throughout the
    /// documentation for SDL.
    ///
    /// The SDL_SWSURFACE flag is passed by default if an argument is not
    /// specified -- this is optimal for writing to the video memory buffer
    /// directly (pixel manipulation).
    ///
    /// As per libSDL docs, this must be called only after video initialization;
    /// (SDL_SetVideoMode).
    ///
    /// See http://sdl.beuc.net/sdl.wiki/SDL_CreateRGBSurface
    Canvas ( int32 width, int32 height, uint8 bitsPerPixel, uint32 Rmask, uint32 Gmask, uint32 Bmask, uint32 Amask, uint32 flags = SDL_SWSURFACE );

    /// Construct a video surface object using the data from an existing surface;
    /// you can think of this as a copy method. As with the previous method, you
    /// ought to read over the technicalities that the SDL library documentation
    /// covers.
    ///
    /// You remain the owner of the pointer leading to your existing data and
    /// therefore are responsible for memory management.
    ///
    /// See http://sdl.beuc.net/sdl.wiki/SDL_CreateRGBSurfaceFrom
    Canvas ( Pixels pixels, int32 width, int32 height, int32 depth, uint16 pitch, uint32 Rmask, uint32 Gmask, uint32 Bmask, uint32 Amask );

    /// Lazy destructor -- does nothing.
    ~Canvas ( void );

    /// Return a std::shared_ptr copy of this instance
    /// \todo Test me out!
    Canvas::SharedPtr clone ( void ) const;

    /// Copy assignment operator
    Canvas& operator = ( const Canvas& other );

    /// Is this object initialized -- not nullptr?
    bool valid ( void ) const;

    /// Reset the video surface object with another video surface object.
    void setCanvas ( const Canvas& surface );

    void setPosition ( const Coords& coords_ );
    void setOffsets ( const Coords& offsets_ );

    const int32 getCanvasWidth ( void ) const;
    const int32 getCanvasHeight ( void ) const;
    uint32 getCanvasFlags ( void ) const;
    uint16 getCanvasPitch ( void ) const;
    const Pixels getCanvasPixels ( void ) const;
    const uint8 getCanvasBitsPerPixel ( void ) const;

    /// \todo Rename to getCanvasPixelFormat
    const Pixels getCanvasPixelsFormat ( void ) const;

    /// Obtain the pixel value of the set transparent color
    const Color getCanvasColorKey ( void ) const;

    /// Obtain the overall surface alpha value
    const uint8 getCanvasAlphaValue ( void ) const;

    /// Obtain the video surface's red *ALPHA* mask
    const uint32 getCanvasRedMask ( void ) const;

    /// Obtain the video surface's green *ALPHA* mask
    const uint32 getCanvasGreenMask ( void ) const;

    /// Obtain the video surface's blue *ALPHA* mask
    const uint32 getCanvasBlueMask ( void ) const;

    /// Obtain the video surface's alpha mask
    const uint32 getCanvasAlphaMask ( void ) const;

    const Coords getCanvasBounds ( void ) const;
    void setCanvasBounds ( const Coords& clip_bounds );

    /// Convenience Helper method for calculating the canvas color depth; for
    /// the time being, this is merely for the convenience of readability in
    /// our code.
    ///
    /// Returns an integer of 8, 16, 24 or 32 upon successful determination of
    /// the current color depth.
    ///
    /// Returns -1 on err; perhaps an unsupported color depth or an
    /// uninitialized video surface?
    int32 getCanvasColorDepth ( void ) const;

    /// I think that we are accessing the value of an
    /// (internal?) property of the SDL_Surface structure that is described as being
    /// "private" as per the docs.
    ///
    /// Return value of this internal property is presumed to be boolean -- no
    /// verification has been made of this. Testing of this method *appears*
    /// to be in working order.
    bool getCanvasLock ( void ) const;

    /// Lock the video surface for writing directly to video memory.
    bool lock ( void ) const;

    /// Unlocks the video surface; this must be done after you are finished
    /// writing to the video buffer. During the time that the video surface is
    /// locked, no updates (think: rendering) outside of your local access can
    /// occur until the surfaces affected by the lock are relinquished.
    void unlock ( void ) const;

    /// Sets transparency only if colorkey Color alpha value is -1, also
    /// important to note is that we only have an alpha channel surface set
    /// if Color value is not -1 (the default)
    ///
    /// \internal
    /// Clean up this documentation note and also verify that it is
    /// sane to assume that you would not use transparency when you have alpha
    /// surface enabled
    /// \endinternal
    bool load ( const std::string& filename, const Color&
                colorkey = Color ( -1, -1, -1, -1 ),
                bool use_cache = false,
                uint32 flags = SDL_RLEACCEL | SDL_SRCCOLORKEY
              );

    bool Update ( void* video_buffer );
    void Draw ( void* video_buffer ) const;

    bool setAlpha ( uint8 opacity, uint32 flags = SDL_SRCALPHA );

    bool setTransparent ( const Color& color = Color ( 0, 0, 0, -1 ),
                          uint32 flags = SDL_RLEACCEL | SDL_SRCCOLORKEY
                        );

    /// As per libSDL docs, we must first initialize the video subsystem before using
    /// this method call, otherwise an access violation fault is sure to occur.
    bool displayFormat ( void );
    /// As per libSDL docs, we must first initialize the video subsystem before using
    /// this method call, otherwise an access violation fault is sure to occur.
    bool displayFormatAlpha ( void );

    /// \internal
    /// Note: this method is not meant to be called inside a loop; memory usage may
    /// run a mock (seems to be fixed by Rectangle::~Rectangle() inside the
    /// Rectangle class, although it eludes me as to why precisely
    /// \endinternal
    void clear ( const Color& color = Color::Blue ) const;

    /// Pixel reading -- supports 8-bit, 15/16-bit, 24-bit & 32-bit color modes
    ///
    /// Returns -1 on error
    ///
    /// You are responsible for locking & unlocking of the canvas before-hand
    ///
    /// \todo Test 8-bit, 15/16-bit & 24-bit pixels
    int32 getPixel ( int32 x, int32 y );

    /// Resize the video surface with the chosen rescaling algorithm.
    ///
    /// See the ResizeAlgorithm enum for available rescaling algorithms
    bool resize ( enum ResizeAlgorithm scaling_algorithm );

    /// Return the correct scaling factor of the chosen algorithm
    int32 getResizeScaleFactor ( enum ResizeAlgorithm scaling_algorithm );

  private:
    /// Internal method used for checking to see if the video surface actually
    /// needs to be locked before doing so for performance sake.
    bool mustLock ( void ) const;

    std::shared_ptr<void> canvas_buffer; // SDL_Surface*
    /// Holds surface position
    Coords coords;
    /// Holds surface bounds (input clipping)
    Coords offsets;
};

} // namespace nom

#endif // NOMLIB_SDL_CANVAS_HEADERS defined
<|endoftext|>


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

  nomlib - C++11 cross-platform game engine

Copyright (c) 2013, Jeffrey Carpenter <jeffrey.carp@gmail.com>
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.

******************************************************************************/
#ifndef NOMLIB_POINT2D_HEADERS
#define NOMLIB_POINT2D_HEADERS

#include <iostream>

#include "nomlib/config.hpp"

namespace nom {

const std::string point_delimiter = ", ";

/// \brief 2D Point class
template <typename T>
class Point2
{
  public:
    /// Default constructor; sets all values to their respective defaults
    Point2 ( void ) : x ( 0 ), y ( 0 ) {}

    /// Destructor
    ~Point2 ( void ) {}

    /// Constructor variant for initializing x, y at construction
    Point2 ( T x, T y ) : x ( x ), y ( y ) {}

    /// Copy constructor
    template <typename U>
    Point2<T> ( const Point2<U>& copy )
    {
      this->x = static_cast<T> ( copy.x );
      this->y = static_cast<T> ( copy.y );
    }

    /// Copy assignment operator
    Point2& operator = ( const T& other )
    {
      this->x = other.x;
      this->y = other.y;
    }

  public:
    T x;
    T y;
};

/// Pretty print a Point2 object using the following formatting:
///
///     <Point2.x>, <Point2.y>
///
/// An example print:
///
///     128, 144
template <typename T>
std::ostream& operator << ( std::ostream& os, const Point2<T>& coords )
{
  os  << coords.x << point_delimiter
      << coords.y;
  return os;
}

/// Point2D object defined with 32-bit signed integers
typedef Point2<int32> Point2i;

/// Point2D object defined with 32-bit unsigned integers
typedef Point2<uint32> Point2u;

/// Point2D object defined with floating-point integers.
typedef Point2<float> Point2f;

/// Point2D object defined with double precision floating-point integers.
typedef Point2<double> Point2d;

} // namespace nom

#endif // include guard defined
<commit_msg>math/Point2-inl: Fix a couple missed bugs<commit_after>/******************************************************************************

  nomlib - C++11 cross-platform game engine

Copyright (c) 2013, Jeffrey Carpenter <jeffrey.carp@gmail.com>
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.

******************************************************************************/
#ifndef NOMLIB_POINT2D_HEADERS
#define NOMLIB_POINT2D_HEADERS

#include <iostream>

#include "nomlib/config.hpp"

namespace nom {

const std::string point_delimiter = ", ";

/// \brief 2D point container
template <typename T>
class Point2
{
  public:
    /// Default constructor; sets all values to their respective defaults
    Point2 ( void ) : x ( 0 ), y ( 0 ) {}

    /// Destructor
    ~Point2 ( void ) {}

    /// Constructor variant for initializing x, y at construction
    Point2 ( T x, T y ) : x ( x ), y ( y ) {}

    /// Copy constructor
    template <typename U>
    Point2 ( const Point2<U>& copy )
    {
      this->x = static_cast<T> ( copy.x );
      this->y = static_cast<T> ( copy.y );
    }

    /// Copy assignment operator
    template <typename U>
    Point2<T>& operator = ( const Point2<U>& other )
    {
      this->x = static_cast<T> ( other.x );
      this->y = static_cast<T> ( other.y );

      return *this;
    }

  public:
    T x;
    T y;
};

/// Pretty print a Point2 object using the following formatting:
///
///     <Point2.x>, <Point2.y>
///
/// An example print:
///
///     128, 144
template <typename T>
std::ostream& operator << ( std::ostream& os, const Point2<T>& coords )
{
  os  << coords.x << point_delimiter
      << coords.y;
  return os;
}

/// Point2D object defined with 32-bit signed integers
typedef Point2<int32> Point2i;

/// Point2D object defined with 32-bit unsigned integers
typedef Point2<uint32> Point2u;

/// Point2D object defined with floating-point integers.
typedef Point2<float> Point2f;

/// Point2D object defined with double precision floating-point integers.
typedef Point2<double> Point2d;

} // namespace nom

#endif // include guard defined
<|endoftext|>


<commit_before>/*
 * This file is part of otf2xx (https://github.com/tud-zih-energy/otf2xx)
 * otf2xx - A wrapper for the Open Trace Format 2 library
 *
 * Copyright (c) 2013-2016, Technische Universität Dresden, Germany
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of the copyright holder 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.
 *
 */

#ifndef INCLUDE_OTF2XX_CHRONO_DURATION_HPP
#define INCLUDE_OTF2XX_CHRONO_DURATION_HPP

#include <chrono>
#include <iostream>

using namespace std::literals::chrono_literals;

namespace otf2
{
namespace chrono
{

    /**
     * \brief typedef for duration of lenght picosecond
     */
    typedef std::chrono::duration<int64_t, std::pico> picoseconds;

    /**
     * \brief typedef for duration of lenght nanosecond
     */
    typedef std::chrono::nanoseconds nanoseconds;

    /**
     * \brief typedef for duration of lenght microseconds
     */
    typedef std::chrono::microseconds microseconds;

    /**
     * \brief typedef for duration of lenght milliseconds
     */
    typedef std::chrono::milliseconds milliseconds;

    /**
     * \brief typedef for duration of lenght seconds
     */
    typedef std::chrono::seconds seconds;

    /**
     * \brief typedef for duration of lenght minutes
     */
    typedef std::chrono::minutes minutes;

    /**
     * \brief typedef for duration of lenght hours
     */
    typedef std::chrono::hours hours;

    /**
     * \brief otf2::chrono::duration defaults to nanoseconds or picoseconds
     * This can be configured using the build system.
     */
    typedef OTF2XX_CHRONO_DURATION_TYPE duration;

    /**
     * \brief convert between durations
     *
     * This ain't a simple cast, it also takes different prefixes into account.
     * e.g. duration_cast<seconds>milliseconds(1000) == seconds(1)
     *
     * But this could also mean, that there is information loss.
     * e.g. duration_cast<seconds>milliseconds(1300) == seconds(1)
     *
     * \tparam FromDuration type of source duration
     * \tparam ToDuration type of target duration, defaults to @see otf2::chrono::duration
     * \param[in] dtn duration which is casted
     *
     * \return duration to which is casted
     */
    template <typename FromDuration, typename ToDuration = otf2::chrono::duration>
    constexpr ToDuration duration_cast(const FromDuration& dtn)
    {
        return std::chrono::duration_cast<ToDuration>(dtn);
    }
} // namespace chrono
} // namespace otf2

namespace std
{
namespace chrono
{

    // HACK: BE AWARE OF DEAD KITTENS

    inline std::ostream& operator<<(std::ostream& s, otf2::chrono::picoseconds dur)
    {
        return s << dur.count() << "ps";
    }

    inline std::ostream& operator<<(std::ostream& s, nanoseconds dur)
    {
        return s << dur.count() << "ns";
    }

    inline std::ostream& operator<<(std::ostream& s, microseconds dur)
    {
        return s << dur.count() << "us";
    }

    inline std::ostream& operator<<(std::ostream& s, milliseconds dur)
    {
        return s << dur.count() << "ms";
    }

    inline std::ostream& operator<<(std::ostream& s, seconds dur)
    {
        return s << dur.count() << "s";
    }

    inline std::ostream& operator<<(std::ostream& s, minutes dur)
    {
        return s << dur.count() << "min";
    }

    inline std::ostream& operator<<(std::ostream& s, hours dur)
    {
        return s << dur.count() << "h";
    }
} // namespace chrono
} // namespace std

// make it posible to serialize otf2::chrono::time_point
namespace boost
{
namespace serialization
{

    template <class Archive>
    inline void save(Archive& ar, const otf2::chrono::duration& dur,
                     __attribute__((unused)) const unsigned int file_version)
    {
        auto count = dur.count();
        ar& count;
    }

    template <class Archive>
    inline void load(Archive& ar, otf2::chrono::duration& dur,
                     __attribute__((unused)) const unsigned int file_version)
    {
        std::int64_t count;

        ar& count;

        dur = otf2::chrono::duration(count);
    }

    // split non-intrusive serialization function member into separate
    // non intrusive save/load member functions
    template <class Archive>
    inline void serialize(Archive& ar, otf2::chrono::duration& dur,
                          __attribute__((unused)) const unsigned int file_version)
    {
        // god bless ADL rules (ღˇ◡ˇ)~♥
        // This can't and won't be checked until a later instantiation phase.
        // So even though split_free is neither declared nor defined, it should be fine until
        // a user instantiated this template. In order to instantiate this template,
        // a user first need to include boost::serialization. So I will be fine. Probably. Maybe?
        split_free(ar, dur, file_version);
    }

} // namespace serialization
} // namespace boost

#endif // INCLUDE_OTF2XX_CHRONO_DURATION_HPP
<commit_msg>Fix wrong duration_cast<commit_after>/*
 * This file is part of otf2xx (https://github.com/tud-zih-energy/otf2xx)
 * otf2xx - A wrapper for the Open Trace Format 2 library
 *
 * Copyright (c) 2013-2016, Technische Universität Dresden, Germany
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of the copyright holder 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.
 *
 */

#ifndef INCLUDE_OTF2XX_CHRONO_DURATION_HPP
#define INCLUDE_OTF2XX_CHRONO_DURATION_HPP

#include <chrono>
#include <iostream>

using namespace std::literals::chrono_literals;

namespace otf2
{
namespace chrono
{

    /**
     * \brief typedef for duration of lenght picosecond
     */
    typedef std::chrono::duration<int64_t, std::pico> picoseconds;

    /**
     * \brief typedef for duration of lenght nanosecond
     */
    typedef std::chrono::nanoseconds nanoseconds;

    /**
     * \brief typedef for duration of lenght microseconds
     */
    typedef std::chrono::microseconds microseconds;

    /**
     * \brief typedef for duration of lenght milliseconds
     */
    typedef std::chrono::milliseconds milliseconds;

    /**
     * \brief typedef for duration of lenght seconds
     */
    typedef std::chrono::seconds seconds;

    /**
     * \brief typedef for duration of lenght minutes
     */
    typedef std::chrono::minutes minutes;

    /**
     * \brief typedef for duration of lenght hours
     */
    typedef std::chrono::hours hours;

    /**
     * \brief otf2::chrono::duration defaults to nanoseconds or picoseconds
     * This can be configured using the build system.
     */
    typedef OTF2XX_CHRONO_DURATION_TYPE duration;

    /**
     * \brief convert between durations
     *
     * This ain't a simple cast, it also takes different prefixes into account.
     * e.g. duration_cast<seconds>milliseconds(1000) == seconds(1)
     *
     * But this could also mean, that there is information loss.
     * e.g. duration_cast<seconds>milliseconds(1300) == seconds(1)
     *
     * \tparam ToDuration type of target duration, defaults to @see otf2::chrono::duration
     * \tparam FromDuration type of source duration
     * \param[in] dtn duration which is casted
     *
     * \return duration to which is casted
     */
    template <typename ToDuration = otf2::chrono::duration, typename FromDuration = otf2::chrono::duration>
    constexpr ToDuration duration_cast(const FromDuration& dtn)
    {
        return std::chrono::duration_cast<ToDuration>(dtn);
    }
} // namespace chrono
} // namespace otf2

namespace std
{
namespace chrono
{

    // HACK: BE AWARE OF DEAD KITTENS

    inline std::ostream& operator<<(std::ostream& s, otf2::chrono::picoseconds dur)
    {
        return s << dur.count() << "ps";
    }

    inline std::ostream& operator<<(std::ostream& s, nanoseconds dur)
    {
        return s << dur.count() << "ns";
    }

    inline std::ostream& operator<<(std::ostream& s, microseconds dur)
    {
        return s << dur.count() << "us";
    }

    inline std::ostream& operator<<(std::ostream& s, milliseconds dur)
    {
        return s << dur.count() << "ms";
    }

    inline std::ostream& operator<<(std::ostream& s, seconds dur)
    {
        return s << dur.count() << "s";
    }

    inline std::ostream& operator<<(std::ostream& s, minutes dur)
    {
        return s << dur.count() << "min";
    }

    inline std::ostream& operator<<(std::ostream& s, hours dur)
    {
        return s << dur.count() << "h";
    }
} // namespace chrono
} // namespace std

// make it posible to serialize otf2::chrono::time_point
namespace boost
{
namespace serialization
{

    template <class Archive>
    inline void save(Archive& ar, const otf2::chrono::duration& dur,
                     __attribute__((unused)) const unsigned int file_version)
    {
        auto count = dur.count();
        ar& count;
    }

    template <class Archive>
    inline void load(Archive& ar, otf2::chrono::duration& dur,
                     __attribute__((unused)) const unsigned int file_version)
    {
        std::int64_t count;

        ar& count;

        dur = otf2::chrono::duration(count);
    }

    // split non-intrusive serialization function member into separate
    // non intrusive save/load member functions
    template <class Archive>
    inline void serialize(Archive& ar, otf2::chrono::duration& dur,
                          __attribute__((unused)) const unsigned int file_version)
    {
        // god bless ADL rules (ღˇ◡ˇ)~♥
        // This can't and won't be checked until a later instantiation phase.
        // So even though split_free is neither declared nor defined, it should be fine until
        // a user instantiated this template. In order to instantiate this template,
        // a user first need to include boost::serialization. So I will be fine. Probably. Maybe?
        split_free(ar, dur, file_version);
    }

} // namespace serialization
} // namespace boost

#endif // INCLUDE_OTF2XX_CHRONO_DURATION_HPP
<|endoftext|>


<commit_before>//===- include/seec/Trace/ThreadState.hpp --------------------------- C++ -===//
//
//                                    SeeC
//
// This file is distributed under The MIT License (MIT). See LICENSE.TXT for
// details.
//
//===----------------------------------------------------------------------===//
///
/// \file
///
//===----------------------------------------------------------------------===//

#ifndef SEEC_TRACE_THREADSTATE_HPP
#define SEEC_TRACE_THREADSTATE_HPP

#include "seec/RuntimeErrors/RuntimeErrors.hpp"
#include "seec/Trace/FunctionState.hpp"
#include "seec/Trace/TraceReader.hpp"
#include "seec/Util/Maybe.hpp"

#include "llvm/Support/raw_ostream.h"

#include <cstdlib>
#include <memory>
#include <type_traits>
#include <vector>

namespace seec {

namespace trace {

class ProcessState; // forward-declare for ThreadState

/// \brief State of a thread at a specific point in time.
///
class ThreadState {
  friend class ProcessState; // Allow ProcessStates to construct ThreadStates.

  /// \name Constants
  /// @{

  /// The ProcessState that this ThreadState belongs to.
  ProcessState &Parent;

  /// The ThreadTrace that this ThreadState was produced from.
  ThreadTrace const &Trace;

  /// @}

  /// \name Variables
  /// @{

  /// The next event to process when moving forward through the trace.
  EventReference NextEvent;

  /// The synthetic process time that this ThreadState represents.
  uint64_t ProcessTime;

  /// The synthetic thread time that this ThreadState represents.
  uint64_t ThreadTime;

  /// The stack of FunctionState objects.
  std::vector<std::unique_ptr<FunctionState>> CallStack;

  /// @}

  /// \brief Constructor.
  ThreadState(ProcessState &Parent,
              ThreadTrace const &Trace);

  // Don't allow copying
  ThreadState(ThreadState const &Other) = delete;
  ThreadState &operator=(ThreadState const &RHS) = delete;

  /// \name Memory state event movement.
  /// @{

  void addMemoryState(EventLocation const &EvLoc,
                      EventRecord<EventType::StateTyped> const &Ev,
                      MemoryState &Memory);

  void restoreMemoryState(EventLocation const &EvLoc,
                          EventRecord<EventType::StateTyped> const &Ev,
                          MemoryState &Memory) {
    addMemoryState(EvLoc, Ev, Memory);
  }

  void restoreMemoryState(EventLocation const &EvLoc,
                          EventRecord<EventType::StateTyped> const &Ev,
                          MemoryArea const &InArea,
                          MemoryState &Memory);

  void addMemoryState(EventLocation const &EvLoc,
                      EventRecord<EventType::StateUntypedSmall> const &Ev,
                      MemoryState &Memory);

  void
  restoreMemoryState(EventLocation const &EvLoc,
                     EventRecord<EventType::StateUntypedSmall> const &Ev,
                     MemoryState &Memory) {
    addMemoryState(EvLoc, Ev, Memory);
  }

  void
  restoreMemoryState(EventLocation const &EvLoc,
                     EventRecord<EventType::StateUntypedSmall> const &Ev,
                     MemoryArea const &InArea,
                     MemoryState &Memory);

  void addMemoryState(EventLocation const &EvLoc,
                      EventRecord<EventType::StateUntyped> const &Ev,
                      MemoryState &Memory);

  void restoreMemoryState(EventLocation const &EvLoc,
                          EventRecord<EventType::StateUntyped> const &Ev,
                          MemoryState &Memory) {
    addMemoryState(EvLoc, Ev, Memory);
  }

  void restoreMemoryState(EventLocation const &EvLoc,
                          EventRecord<EventType::StateUntyped> const &Ev,
                          MemoryArea const &InArea,
                          MemoryState &Memory);

  void addMemoryState(EventLocation const &EvLoc,
                      EventRecord<EventType::StateMemmove> const &Ev,
                      MemoryState &Memory);

  void restoreMemoryState(EventLocation const &EvLoc,
                          EventRecord<EventType::StateMemmove> const &Ev,
                          MemoryState &Memory);

  void restoreMemoryState(EventLocation const &EvLoc,
                          EventRecord<EventType::StateMemmove> const &Ev,
                          MemoryArea const &InArea,
                          MemoryState &Memory);

  template<EventType ET>
  void addMemoryState(
          EventLocation const &EvLoc,
          EventRecord<ET> const &Ev,
          MemoryState &Memory,
          typename std::enable_if<!is_memory_state<ET>::value>::type* = nullptr)
  {
    llvm::errs() << "\ncalled addMemoryState/3 for EventType "
                 << describe(ET) << "\n";
    exit(EXIT_FAILURE);
  }

  template<EventType ET>
  void restoreMemoryState(
          EventLocation const &EvLoc,
          EventRecord<ET> const &Ev,
          MemoryState &Memory,
          typename std::enable_if<!is_memory_state<ET>::value>::type* = nullptr)
  {
    llvm::errs() << "\ncalled restoreMemoryState/3 for EventType "
                 << describe(ET) << "\n";
    exit(EXIT_FAILURE);
  }

  template<EventType ET>
  void restoreMemoryState(
          EventLocation const &EvLoc,
          EventRecord<ET> const &Ev,
          MemoryArea const &InArea,
          MemoryState &Memory,
          typename std::enable_if<!is_memory_state<ET>::value>::type* = nullptr)
  {
    llvm::errs() << "\ncalled restoreMemoryState/4 for EventType "
                 << describe(ET) << "\n";
    exit(EXIT_FAILURE);
  }

  void restoreMemoryState(EventLocation const &Ev,
                          MemoryState &Memory);

  void restoreMemoryState(EventLocation const &Ev,
                          MemoryState &Memory,
                          MemoryArea const &InArea);

  /// @}

  /// \name Movement
  /// @{

  void addEvent(EventRecord<EventType::None> const &);
  void addEvent(EventRecord<EventType::TraceEnd> const &);
  void addEvent(EventRecord<EventType::FunctionStart> const &);
  void addEvent(EventRecord<EventType::FunctionEnd> const &);
  void addEvent(EventRecord<EventType::BasicBlockStart> const &);
  void addEvent(EventRecord<EventType::NewProcessTime> const &);
  void addEvent(EventRecord<EventType::NewThreadTime> const &);
  void addEvent(EventRecord<EventType::PreInstruction> const &);
  void addEvent(EventRecord<EventType::Instruction> const &);
  void addEvent(EventRecord<EventType::InstructionWithSmallValue> const &);
  void addEvent(EventRecord<EventType::InstructionWithValue> const &);
  void addEvent(EventRecord<EventType::InstructionWithLargeValue> const &);
  void addEvent(EventRecord<EventType::StackRestore> const &);
  void addEvent(EventRecord<EventType::Alloca> const &);
  void addEvent(EventRecord<EventType::Malloc> const &);
  void addEvent(EventRecord<EventType::Free> const &);
  void addEvent(EventRecord<EventType::StateTyped> const &);
  void addEvent(EventRecord<EventType::StateUntypedSmall> const &);
  void addEvent(EventRecord<EventType::StateUntyped> const &);
  void addEvent(EventRecord<EventType::StateMemmove> const &);
  void addEvent(EventRecord<EventType::StateClear> const &);
  void addEvent(EventRecord<EventType::KnownRegionAdd> const &);
  void addEvent(EventRecord<EventType::KnownRegionRemove> const &);
  void addEvent(EventRecord<EventType::ByValRegionAdd> const &);
  void addEvent(EventRecord<EventType::RuntimeError> const &);

  /// Swallows unmatched calls to addEvent. This allows us to restrict calls to
  /// addEvent using an if statement when switching over types that do not have
  /// a defined addEvent (i.e. types with the trait is_subservient). Calling
  /// this function at runtime is an error.
  void addEvent(...) { llvm_unreachable("addEvent(...) called!"); }

public:
  /// Add the event referenced by NextEvent to the state, and then increment
  /// NextEvent.
  void addNextEvent();

private:
  void makePreviousInstructionActive(EventReference PriorTo);
  void setPreviousViewOfProcessTime(EventReference PriorTo);

  void removeEvent(EventRecord<EventType::None> const &);
  void removeEvent(EventRecord<EventType::TraceEnd> const &);
  void removeEvent(EventRecord<EventType::FunctionStart> const &);
  void removeEvent(EventRecord<EventType::FunctionEnd> const &);
  void removeEvent(EventRecord<EventType::BasicBlockStart> const &);
  void removeEvent(EventRecord<EventType::NewProcessTime> const &);
  void removeEvent(EventRecord<EventType::NewThreadTime> const &);
  void removeEvent(EventRecord<EventType::PreInstruction> const &);
  void removeEvent(EventRecord<EventType::Instruction> const &);
  void removeEvent(EventRecord<EventType::InstructionWithSmallValue> const &);
  void removeEvent(EventRecord<EventType::InstructionWithValue> const &);
  void removeEvent(EventRecord<EventType::InstructionWithLargeValue> const &);
  void removeEvent(EventRecord<EventType::StackRestore> const &);
  void removeEvent(EventRecord<EventType::Alloca> const &);
  void removeEvent(EventRecord<EventType::Malloc> const &);
  void removeEvent(EventRecord<EventType::Free> const &);
  bool removeEventIfOverwrite(EventReference EvRef);
  void removeEvent(EventRecord<EventType::StateTyped> const &);
  void removeEvent(EventRecord<EventType::StateUntypedSmall> const &);
  void removeEvent(EventRecord<EventType::StateUntyped> const &);
  void removeEvent(EventRecord<EventType::StateMemmove> const &);
  void removeEvent(EventRecord<EventType::StateClear> const &);
  void removeEvent(EventRecord<EventType::StateOverwrite> const &);
  void removeEvent(EventRecord<EventType::StateOverwriteFragment> const &);
  void removeEvent(
    EventRecord<EventType::StateOverwriteFragmentTrimmedRight> const &);
  void removeEvent(
    EventRecord<EventType::StateOverwriteFragmentTrimmedLeft> const &);
  void removeEvent(EventRecord<EventType::StateOverwriteFragmentSplit> const &);
  void removeEvent(EventRecord<EventType::KnownRegionAdd> const &);
  void removeEvent(EventRecord<EventType::KnownRegionRemove> const &);
  void removeEvent(EventRecord<EventType::ByValRegionAdd> const &);
  void removeEvent(EventRecord<EventType::RuntimeError> const &);

  /// Swallows unmatched calls to removeEvent. This allows us to restrict calls
  /// to removeEvent using an if statement when switching over types that do
  /// not have a defined removeEvent (i.e. types with the trait is_subservient).
  /// Calling this function at runtime is an error.
  void removeEvent(...) { llvm_unreachable("removeEvent(...) called!"); }

public:
  /// Decrement NextEvent, and then remove the event it references from the
  /// state.
  void removePreviousEvent();

  /// @} (Movement)

  /// \name Accessors
  /// @{

  /// \brief Get the ProcessState that this ThreadState belongs to.
  ProcessState &getParent() { return Parent; }

  /// \brief Get the ProcessState that this ThreadState belongs to.
  ProcessState const &getParent() const { return Parent; }

  /// \brief Get the ThreadTrace for this thread.
  ThreadTrace const &getTrace() const { return Trace; }

  /// \brief Get the next event to process when moving forward through the
  /// trace.
  EventReference getNextEvent() const { return NextEvent; }

  /// \brief Get the synthetic thread time that this ThreadState represents.
  uint64_t getThreadTime() const { return ThreadTime; }

  /// \brief Get the current stack of FunctionStates.
  decltype(CallStack) const &getCallStack() const { return CallStack; }

  /// @} (Accessors)

  /// \name Queries.
  /// @{

  /// \brief Check if this thread is at the beginning of its trace.
  /// \return true iff this thread has not added any events.
  ///
  bool isAtStart() const { return NextEvent == Trace.events().begin(); }

  /// \brief Check if this thread is at the end of its trace.
  /// \return true iff this thread has no more events to add.
  ///
  bool isAtEnd() const { return NextEvent == Trace.events().end(); }

  /// @} (Queries.)

  /// \name Memory.
  /// @{

  /// \brief Find the allocated range that owns an address.
  ///
  /// This method will search:
  ///  - Functions' stack allocations.
  ///
  seec::Maybe<MemoryArea>
  getContainingMemoryArea(uintptr_t Address) const;

  /// @} (Memory.)

  /// \name Searching
  /// @{

  /// \brief Get the last event that modified the shared process state from this
  /// thread.
  seec::Maybe<EventReference> getLastProcessModifier() const;

  /// @}
};

/// Print a textual description of a ThreadState.
llvm::raw_ostream &operator<<(llvm::raw_ostream &Out,
                              ThreadState const &State);

} // namespace trace (in seec)

} // namespace seec

#endif // SEEC_TRACE_THREADSTATE_HPP
<commit_msg>Add a shorthand method to ThreadState to get a pointer to the active FunctionState if there is one, or a nullptr otherwise.<commit_after>//===- include/seec/Trace/ThreadState.hpp --------------------------- C++ -===//
//
//                                    SeeC
//
// This file is distributed under The MIT License (MIT). See LICENSE.TXT for
// details.
//
//===----------------------------------------------------------------------===//
///
/// \file
///
//===----------------------------------------------------------------------===//

#ifndef SEEC_TRACE_THREADSTATE_HPP
#define SEEC_TRACE_THREADSTATE_HPP

#include "seec/RuntimeErrors/RuntimeErrors.hpp"
#include "seec/Trace/FunctionState.hpp"
#include "seec/Trace/TraceReader.hpp"
#include "seec/Util/Maybe.hpp"

#include "llvm/Support/raw_ostream.h"

#include <cstdlib>
#include <memory>
#include <type_traits>
#include <vector>

namespace seec {

namespace trace {

class ProcessState; // forward-declare for ThreadState

/// \brief State of a thread at a specific point in time.
///
class ThreadState {
  friend class ProcessState; // Allow ProcessStates to construct ThreadStates.

  /// \name Constants
  /// @{

  /// The ProcessState that this ThreadState belongs to.
  ProcessState &Parent;

  /// The ThreadTrace that this ThreadState was produced from.
  ThreadTrace const &Trace;

  /// @}

  /// \name Variables
  /// @{

  /// The next event to process when moving forward through the trace.
  EventReference NextEvent;

  /// The synthetic process time that this ThreadState represents.
  uint64_t ProcessTime;

  /// The synthetic thread time that this ThreadState represents.
  uint64_t ThreadTime;

  /// The stack of FunctionState objects.
  std::vector<std::unique_ptr<FunctionState>> CallStack;

  /// @}

  /// \brief Constructor.
  ThreadState(ProcessState &Parent,
              ThreadTrace const &Trace);

  // Don't allow copying
  ThreadState(ThreadState const &Other) = delete;
  ThreadState &operator=(ThreadState const &RHS) = delete;

  /// \name Memory state event movement.
  /// @{

  void addMemoryState(EventLocation const &EvLoc,
                      EventRecord<EventType::StateTyped> const &Ev,
                      MemoryState &Memory);

  void restoreMemoryState(EventLocation const &EvLoc,
                          EventRecord<EventType::StateTyped> const &Ev,
                          MemoryState &Memory) {
    addMemoryState(EvLoc, Ev, Memory);
  }

  void restoreMemoryState(EventLocation const &EvLoc,
                          EventRecord<EventType::StateTyped> const &Ev,
                          MemoryArea const &InArea,
                          MemoryState &Memory);

  void addMemoryState(EventLocation const &EvLoc,
                      EventRecord<EventType::StateUntypedSmall> const &Ev,
                      MemoryState &Memory);

  void
  restoreMemoryState(EventLocation const &EvLoc,
                     EventRecord<EventType::StateUntypedSmall> const &Ev,
                     MemoryState &Memory) {
    addMemoryState(EvLoc, Ev, Memory);
  }

  void
  restoreMemoryState(EventLocation const &EvLoc,
                     EventRecord<EventType::StateUntypedSmall> const &Ev,
                     MemoryArea const &InArea,
                     MemoryState &Memory);

  void addMemoryState(EventLocation const &EvLoc,
                      EventRecord<EventType::StateUntyped> const &Ev,
                      MemoryState &Memory);

  void restoreMemoryState(EventLocation const &EvLoc,
                          EventRecord<EventType::StateUntyped> const &Ev,
                          MemoryState &Memory) {
    addMemoryState(EvLoc, Ev, Memory);
  }

  void restoreMemoryState(EventLocation const &EvLoc,
                          EventRecord<EventType::StateUntyped> const &Ev,
                          MemoryArea const &InArea,
                          MemoryState &Memory);

  void addMemoryState(EventLocation const &EvLoc,
                      EventRecord<EventType::StateMemmove> const &Ev,
                      MemoryState &Memory);

  void restoreMemoryState(EventLocation const &EvLoc,
                          EventRecord<EventType::StateMemmove> const &Ev,
                          MemoryState &Memory);

  void restoreMemoryState(EventLocation const &EvLoc,
                          EventRecord<EventType::StateMemmove> const &Ev,
                          MemoryArea const &InArea,
                          MemoryState &Memory);

  template<EventType ET>
  void addMemoryState(
          EventLocation const &EvLoc,
          EventRecord<ET> const &Ev,
          MemoryState &Memory,
          typename std::enable_if<!is_memory_state<ET>::value>::type* = nullptr)
  {
    llvm::errs() << "\ncalled addMemoryState/3 for EventType "
                 << describe(ET) << "\n";
    exit(EXIT_FAILURE);
  }

  template<EventType ET>
  void restoreMemoryState(
          EventLocation const &EvLoc,
          EventRecord<ET> const &Ev,
          MemoryState &Memory,
          typename std::enable_if<!is_memory_state<ET>::value>::type* = nullptr)
  {
    llvm::errs() << "\ncalled restoreMemoryState/3 for EventType "
                 << describe(ET) << "\n";
    exit(EXIT_FAILURE);
  }

  template<EventType ET>
  void restoreMemoryState(
          EventLocation const &EvLoc,
          EventRecord<ET> const &Ev,
          MemoryArea const &InArea,
          MemoryState &Memory,
          typename std::enable_if<!is_memory_state<ET>::value>::type* = nullptr)
  {
    llvm::errs() << "\ncalled restoreMemoryState/4 for EventType "
                 << describe(ET) << "\n";
    exit(EXIT_FAILURE);
  }

  void restoreMemoryState(EventLocation const &Ev,
                          MemoryState &Memory);

  void restoreMemoryState(EventLocation const &Ev,
                          MemoryState &Memory,
                          MemoryArea const &InArea);

  /// @}

  /// \name Movement
  /// @{

  void addEvent(EventRecord<EventType::None> const &);
  void addEvent(EventRecord<EventType::TraceEnd> const &);
  void addEvent(EventRecord<EventType::FunctionStart> const &);
  void addEvent(EventRecord<EventType::FunctionEnd> const &);
  void addEvent(EventRecord<EventType::BasicBlockStart> const &);
  void addEvent(EventRecord<EventType::NewProcessTime> const &);
  void addEvent(EventRecord<EventType::NewThreadTime> const &);
  void addEvent(EventRecord<EventType::PreInstruction> const &);
  void addEvent(EventRecord<EventType::Instruction> const &);
  void addEvent(EventRecord<EventType::InstructionWithSmallValue> const &);
  void addEvent(EventRecord<EventType::InstructionWithValue> const &);
  void addEvent(EventRecord<EventType::InstructionWithLargeValue> const &);
  void addEvent(EventRecord<EventType::StackRestore> const &);
  void addEvent(EventRecord<EventType::Alloca> const &);
  void addEvent(EventRecord<EventType::Malloc> const &);
  void addEvent(EventRecord<EventType::Free> const &);
  void addEvent(EventRecord<EventType::StateTyped> const &);
  void addEvent(EventRecord<EventType::StateUntypedSmall> const &);
  void addEvent(EventRecord<EventType::StateUntyped> const &);
  void addEvent(EventRecord<EventType::StateMemmove> const &);
  void addEvent(EventRecord<EventType::StateClear> const &);
  void addEvent(EventRecord<EventType::KnownRegionAdd> const &);
  void addEvent(EventRecord<EventType::KnownRegionRemove> const &);
  void addEvent(EventRecord<EventType::ByValRegionAdd> const &);
  void addEvent(EventRecord<EventType::RuntimeError> const &);

  /// Swallows unmatched calls to addEvent. This allows us to restrict calls to
  /// addEvent using an if statement when switching over types that do not have
  /// a defined addEvent (i.e. types with the trait is_subservient). Calling
  /// this function at runtime is an error.
  void addEvent(...) { llvm_unreachable("addEvent(...) called!"); }

public:
  /// Add the event referenced by NextEvent to the state, and then increment
  /// NextEvent.
  void addNextEvent();

private:
  void makePreviousInstructionActive(EventReference PriorTo);
  void setPreviousViewOfProcessTime(EventReference PriorTo);

  void removeEvent(EventRecord<EventType::None> const &);
  void removeEvent(EventRecord<EventType::TraceEnd> const &);
  void removeEvent(EventRecord<EventType::FunctionStart> const &);
  void removeEvent(EventRecord<EventType::FunctionEnd> const &);
  void removeEvent(EventRecord<EventType::BasicBlockStart> const &);
  void removeEvent(EventRecord<EventType::NewProcessTime> const &);
  void removeEvent(EventRecord<EventType::NewThreadTime> const &);
  void removeEvent(EventRecord<EventType::PreInstruction> const &);
  void removeEvent(EventRecord<EventType::Instruction> const &);
  void removeEvent(EventRecord<EventType::InstructionWithSmallValue> const &);
  void removeEvent(EventRecord<EventType::InstructionWithValue> const &);
  void removeEvent(EventRecord<EventType::InstructionWithLargeValue> const &);
  void removeEvent(EventRecord<EventType::StackRestore> const &);
  void removeEvent(EventRecord<EventType::Alloca> const &);
  void removeEvent(EventRecord<EventType::Malloc> const &);
  void removeEvent(EventRecord<EventType::Free> const &);
  bool removeEventIfOverwrite(EventReference EvRef);
  void removeEvent(EventRecord<EventType::StateTyped> const &);
  void removeEvent(EventRecord<EventType::StateUntypedSmall> const &);
  void removeEvent(EventRecord<EventType::StateUntyped> const &);
  void removeEvent(EventRecord<EventType::StateMemmove> const &);
  void removeEvent(EventRecord<EventType::StateClear> const &);
  void removeEvent(EventRecord<EventType::StateOverwrite> const &);
  void removeEvent(EventRecord<EventType::StateOverwriteFragment> const &);
  void removeEvent(
    EventRecord<EventType::StateOverwriteFragmentTrimmedRight> const &);
  void removeEvent(
    EventRecord<EventType::StateOverwriteFragmentTrimmedLeft> const &);
  void removeEvent(EventRecord<EventType::StateOverwriteFragmentSplit> const &);
  void removeEvent(EventRecord<EventType::KnownRegionAdd> const &);
  void removeEvent(EventRecord<EventType::KnownRegionRemove> const &);
  void removeEvent(EventRecord<EventType::ByValRegionAdd> const &);
  void removeEvent(EventRecord<EventType::RuntimeError> const &);

  /// Swallows unmatched calls to removeEvent. This allows us to restrict calls
  /// to removeEvent using an if statement when switching over types that do
  /// not have a defined removeEvent (i.e. types with the trait is_subservient).
  /// Calling this function at runtime is an error.
  void removeEvent(...) { llvm_unreachable("removeEvent(...) called!"); }

public:
  /// Decrement NextEvent, and then remove the event it references from the
  /// state.
  void removePreviousEvent();

  /// @} (Movement)

  /// \name Accessors
  /// @{

  /// \brief Get the ProcessState that this ThreadState belongs to.
  ProcessState &getParent() { return Parent; }

  /// \brief Get the ProcessState that this ThreadState belongs to.
  ProcessState const &getParent() const { return Parent; }

  /// \brief Get the ThreadTrace for this thread.
  ThreadTrace const &getTrace() const { return Trace; }

  /// \brief Get the next event to process when moving forward through the
  /// trace.
  EventReference getNextEvent() const { return NextEvent; }

  /// \brief Get the synthetic thread time that this ThreadState represents.
  uint64_t getThreadTime() const { return ThreadTime; }

  /// \brief Get the current stack of FunctionStates.
  decltype(CallStack) const &getCallStack() const { return CallStack; }

  /// @} (Accessors)

  /// \name Queries.
  /// @{

  /// \brief Get a pointer to the active function's state, if there is one.
  ///
  FunctionState const *getActiveFunction() const {
    return CallStack.empty() ? nullptr : CallStack.back().get();
  }

  /// \brief Check if this thread is at the beginning of its trace.
  /// \return true iff this thread has not added any events.
  ///
  bool isAtStart() const { return NextEvent == Trace.events().begin(); }

  /// \brief Check if this thread is at the end of its trace.
  /// \return true iff this thread has no more events to add.
  ///
  bool isAtEnd() const { return NextEvent == Trace.events().end(); }

  /// @} (Queries.)

  /// \name Memory.
  /// @{

  /// \brief Find the allocated range that owns an address.
  ///
  /// This method will search:
  ///  - Functions' stack allocations.
  ///
  seec::Maybe<MemoryArea>
  getContainingMemoryArea(uintptr_t Address) const;

  /// @} (Memory.)

  /// \name Searching
  /// @{

  /// \brief Get the last event that modified the shared process state from this
  /// thread.
  seec::Maybe<EventReference> getLastProcessModifier() const;

  /// @}
};

/// Print a textual description of a ThreadState.
llvm::raw_ostream &operator<<(llvm::raw_ostream &Out,
                              ThreadState const &State);

} // namespace trace (in seec)

} // namespace seec

#endif // SEEC_TRACE_THREADSTATE_HPP
<|endoftext|>