<commit_before>/*
 * Copyright (C) 2009, 2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

#include <fstream>
#include <iterator>
#include <libport/cassert>
#include <libport/cerrno>
#include <libport/compiler.hh>
#include <libport/config.h>
#include <libport/cstdio>
#include <libport/cstring>
#include <libport/detect-win32.h>
#include <libport/exception.hh>
#include <libport/format.hh>
#include <libport/lexical-cast.hh>
#include <libport/read-stdin.hh>
#include <libport/sys/select.h>
#include <libport/sys/stat.h>

#if defined LIBPORT_WIN32 || defined WIN32
# include <libport/windows.hh>
# include <libport/lockable.hh>
# include <iostream>
#endif

#define FAIL_(Format, ...)						\
  do {                                                                  \
    LIBPORT_ECHO(libport::format(Format, ## __VA_ARGS__));              \
    throw libport::Exception(libport::format(Format, ## __VA_ARGS__));  \
  } while (false)

#define FAIL(Format, ...)                                       \
  FAIL_(Format ": %s", ## __VA_ARGS__, strerror(errno))

namespace libport
{

#if defined LIBPORT_WIN32 || defined WIN32

  /*----------.
  | Windows.  |
  `----------*/

  struct ConsumerData
  {
    ConsumerData()
      : fd(-1)
      , buffer()
      , lock()
      , exception(0)
    {}

    bool started()
    {
      return fd != -1;
    }

    void clear()
    {
      delete exception;
      exception = 0;
      fd = -1;
    }
    int fd;
    std::string buffer;
    Lockable lock;
    // If set, an exception to throw.
    libport::Exception *exception;
  };

  static DWORD WINAPI
  readThread(void* d)
  {
    ConsumerData& data = *reinterpret_cast<ConsumerData*>(d);
    try
    {
      while (true)
      {
	static char buf[BUFSIZ];
	int r = read(data.fd, buf, sizeof buf);
	if (r < 0)
	  FAIL("read error on fd = %s", data.fd);
	else if (r == 0) // EOF counts as an 'error'.
	  FAIL_("read error on fd = %s: EOF", data.fd);
	BlockLock bl(data.lock);
	data.buffer.append(buf, r);
      }
    }
    catch (const libport::Exception& e)
    {
      // Don't let exceptions get out of a thread.
      data.exception = new libport::Exception(e);
    }
    return 0;
  }

  std::string
  read_fd(int fd)
  {
    static ConsumerData data;

    BlockLock bl(data.lock);
    if (!data.started())
    {
      data.fd = fd;
      unsigned long id;
      CreateThread(NULL, 0, &readThread, &data, 0, &id);
    }

    if (data.exception && data.buffer.empty())
    {
      libport::Exception exception = *data.exception;
      data.clear();
      throw exception;
    }
    std::string res;
    swap(data.buffer, res);
    return res;
  }

#else

  /*-------.
  | Unix.  |
  `-------*/

  size_t
  read_fd(int fd, char* buf, size_t len)
  {
    // Select.
    {
      fd_set fds;
      FD_ZERO(&fds);
      FD_SET(fd, &fds);

      struct timeval tv;
      tv.tv_sec = tv.tv_usec = 0;

      int r = select(fd + 1, &fds, 0, 0, &tv);
      if (r < 0)
        FAIL("select error on fd=%d", fd);
      else if (r == 0)
        return 0;
    }

    // Read.
    {
      int r = read(fd, buf, len);
      if (r < 0)
        FAIL("read error on fd = %s", fd);
      else if (r == 0) // EOF counts as an 'error'.
        FAIL_("read error on fd = %s: EOF", fd);
      else
	return r;
    }
  }

  std::string
  read_fd(int fd)
  {
    char buf[BUFSIZ];
    size_t len = read_fd(fd, buf, sizeof buf);
    return std::string(buf, len);
  }

#endif

  std::string
  read_stdin()
  {
    return read_fd(STDIN_FILENO);
  }

  std::string
  read_file(const std::string& file)
  {
    if (file == "/dev/stdin")
      return read_stdin();
    else
    {
      // Or should we simply use tellg to get the size?
      struct stat st;
      if (stat(file.c_str(), &st) < 0)
        FAIL("cannot stat `%s'", file);

      std::string res;
      res.reserve(st.st_size);
      std::ifstream is(file.c_str(), std::ios::binary);
      if (is.fail())
        FAIL("cannot open `%s' for reading", file);
      std::copy(std::istreambuf_iterator<char>(is.rdbuf()),
                std::istreambuf_iterator<char>(),
                std::back_inserter(res));

      if (is.fail())
        FAIL("cannot read `%s'", file);
      // FIXME: We need to check for more error kinds.
      return res;
    }
  }

}
<commit_msg>read_fd: Handle EINTR.<commit_after>/*
 * Copyright (C) 2009, 2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

#include <fstream>
#include <iterator>
#include <libport/cassert>
#include <libport/cerrno>
#include <libport/compiler.hh>
#include <libport/config.h>
#include <libport/cstdio>
#include <libport/cstring>
#include <libport/detect-win32.h>
#include <libport/exception.hh>
#include <libport/format.hh>
#include <libport/lexical-cast.hh>
#include <libport/read-stdin.hh>
#include <libport/sys/select.h>
#include <libport/sys/stat.h>

#if defined LIBPORT_WIN32 || defined WIN32
# include <libport/windows.hh>
# include <libport/lockable.hh>
# include <iostream>
#endif

#define FAIL_(Format, ...)						\
  do {                                                                  \
    LIBPORT_ECHO(libport::format(Format, ## __VA_ARGS__));              \
    throw libport::Exception(libport::format(Format, ## __VA_ARGS__));  \
  } while (false)

#define FAIL(Format, ...)                                       \
  FAIL_(Format ": %s", ## __VA_ARGS__, strerror(errno))

namespace libport
{

#if defined LIBPORT_WIN32 || defined WIN32

  /*----------.
  | Windows.  |
  `----------*/

  struct ConsumerData
  {
    ConsumerData()
      : fd(-1)
      , buffer()
      , lock()
      , exception(0)
    {}

    bool started()
    {
      return fd != -1;
    }

    void clear()
    {
      delete exception;
      exception = 0;
      fd = -1;
    }
    int fd;
    std::string buffer;
    Lockable lock;
    // If set, an exception to throw.
    libport::Exception *exception;
  };

  static DWORD WINAPI
  readThread(void* d)
  {
    ConsumerData& data = *reinterpret_cast<ConsumerData*>(d);
    try
    {
      while (true)
      {
	static char buf[BUFSIZ];
	int r = read(data.fd, buf, sizeof buf);
	if (r < 0)
	  FAIL("read error on fd = %s", data.fd);
	else if (r == 0) // EOF counts as an 'error'.
	  FAIL_("read error on fd = %s: EOF", data.fd);
	BlockLock bl(data.lock);
	data.buffer.append(buf, r);
      }
    }
    catch (const libport::Exception& e)
    {
      // Don't let exceptions get out of a thread.
      data.exception = new libport::Exception(e);
    }
    return 0;
  }

  std::string
  read_fd(int fd)
  {
    static ConsumerData data;

    BlockLock bl(data.lock);
    if (!data.started())
    {
      data.fd = fd;
      unsigned long id;
      CreateThread(NULL, 0, &readThread, &data, 0, &id);
    }

    if (data.exception && data.buffer.empty())
    {
      libport::Exception exception = *data.exception;
      data.clear();
      throw exception;
    }
    std::string res;
    swap(data.buffer, res);
    return res;
  }

#else

  /*-------.
  | Unix.  |
  `-------*/

  size_t
  read_fd(int fd, char* buf, size_t len)
  {
    // Select.
    {
      fd_set fds;
      FD_ZERO(&fds);
      FD_SET(fd, &fds);

      struct timeval tv;
      tv.tv_sec = tv.tv_usec = 0;

      int r = select(fd + 1, &fds, 0, 0, &tv);
      if (r < 0)
       if (errno != EINTR)
          FAIL("select error on fd=%d", fd);
       else
         return 0;
      else if (r == 0)
        return 0;
    }

    // Read.
    {
      int r = read(fd, buf, len);
      if (r < 0)
       if (errno != EINTR)
          FAIL("read error on fd = %s", fd);
       else
         return 0;
      else if (r == 0) // EOF counts as an 'error'.
        FAIL_("read error on fd = %s: EOF", fd);
      else
	return r;
    }
  }

  std::string
  read_fd(int fd)
  {
    char buf[BUFSIZ];
    size_t len = read_fd(fd, buf, sizeof buf);
    return std::string(buf, len);
  }

#endif

  std::string
  read_stdin()
  {
    return read_fd(STDIN_FILENO);
  }

  std::string
  read_file(const std::string& file)
  {
    if (file == "/dev/stdin")
      return read_stdin();
    else
    {
      // Or should we simply use tellg to get the size?
      struct stat st;
      if (stat(file.c_str(), &st) < 0)
        FAIL("cannot stat `%s'", file);

      std::string res;
      res.reserve(st.st_size);
      std::ifstream is(file.c_str(), std::ios::binary);
      if (is.fail())
        FAIL("cannot open `%s' for reading", file);
      std::copy(std::istreambuf_iterator<char>(is.rdbuf()),
                std::istreambuf_iterator<char>(),
                std::back_inserter(res));

      if (is.fail())
        FAIL("cannot read `%s'", file);
      // FIXME: We need to check for more error kinds.
      return res;
    }
  }

}
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_FUNCTIONAL_L2_HH
#define DUNE_GDT_FUNCTIONAL_L2_HH

#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/la/container/interfaces.hh>

#include <dune/gdt/localfunctional/codim0.hh>
#include <dune/gdt/localfunctional/codim1.hh>
#include <dune/gdt/localevaluation/product.hh>

#include "base.hh"

namespace Dune {
namespace GDT {
namespace Functional {

template< class FunctionType, class VectorImp, class SpaceImp, class GridViewImp = typename SpaceImp::GridViewType >
class L2Volume;

template< class FunctionType, class VectorImp, class SpaceImp, class GridViewImp >
class L2VolumeTraits
{
  static_assert(std::is_base_of< Stuff::LocalizableFunctionInterface< typename FunctionType::EntityType
                                                                    , typename FunctionType::DomainFieldType
                                                                    , FunctionType::dimDomain
                                                                    , typename FunctionType::RangeFieldType
                                                                    , FunctionType::dimRange
                                                                    , FunctionType::dimRangeCols >
                               , FunctionType >::value,
                "FunctionType has to be derived from Stuff::LocalizableFunctionInterface!");
  static_assert(std::is_base_of< Stuff::LA::VectorInterface< typename VectorImp::Traits >, VectorImp >::value,
                "VectorImp has to be derived from Stuff::LA::VectorInterface!");
  static_assert(std::is_base_of< SpaceInterface< typename SpaceImp::Traits >, SpaceImp >::value,
                "SpaceImp has to be derived from SpaceInterface!");
public:
  typedef L2Volume< FunctionType, VectorImp, SpaceImp, GridViewImp > derived_type;
  typedef VectorImp   VectorType;
  typedef SpaceImp    SpaceType;
  typedef GridViewImp GridViewType;
  typedef typename VectorType::ScalarType ScalarType;

  typedef LocalFunctional::Codim0Integral< LocalEvaluation::Product< FunctionType > > LocalFunctionalType;
}; // class L2VolumeTraits

template< class FunctionType, class VectorImp, class SpaceImp, class GridViewImp >
class L2Volume
  : public Functional::AssemblableVolumeBase< L2VolumeTraits< FunctionType, VectorImp, SpaceImp, GridViewImp > >
{
  typedef L2VolumeTraits< FunctionType, VectorImp, SpaceImp, GridViewImp >  Traits;
  typedef Functional::AssemblableVolumeBase< Traits >                       BaseType;

public:
  typedef typename Traits::VectorType VectorType;
  typedef typename Traits::SpaceType  SpaceType;
  typedef typename Traits::GridViewType GridViewType;

private:
  typedef typename Traits::LocalFunctionalType LocalFunctionalType;

public:
  L2Volume(const FunctionType& function, VectorType& vector, const SpaceType& space, const GridViewType& grid_view)
    : BaseType(vector, space, grid_view)
    , local_functional_(function)
  {}

  L2Volume(const FunctionType& function, VectorType& vector, const SpaceType& space)
    : BaseType(vector, space)
    , local_functional_(function)
  {}

  virtual const LocalFunctionalType& local_functional() const DS_FINAL
  {
    return local_functional_;
  }

private:
  const LocalFunctionalType local_functional_;
}; // class L2Volume

template< class FunctionType, class VectorImp, class SpaceImp, class GridViewImp = typename SpaceImp::GridViewType >
class L2Face;

template< class FunctionType, class VectorImp, class SpaceImp, class GridViewImp >
class L2FaceTraits
{
  static_assert(std::is_base_of< Stuff::LocalizableFunctionInterface< typename FunctionType::EntityType
                                                                    , typename FunctionType::DomainFieldType
                                                                    , FunctionType::dimDomain
                                                                    , typename FunctionType::RangeFieldType
                                                                    , FunctionType::dimRange
                                                                    , FunctionType::dimRangeCols >
                               , FunctionType >::value,
                "FunctionType has to be derived from Stuff::LocalizableFunctionInterface!");
  static_assert(std::is_base_of< Stuff::LA::VectorInterface< typename VectorImp::Traits >, VectorImp >::value,
                "VectorImp has to be derived from Stuff::LA::VectorInterface!");
  static_assert(std::is_base_of< SpaceInterface< typename SpaceImp::Traits >, SpaceImp >::value,
                "SpaceImp has to be derived from SpaceInterface!");
public:
  typedef L2Face< FunctionType, VectorImp, SpaceImp, GridViewImp > derived_type;
  typedef VectorImp   VectorType;
  typedef SpaceImp    SpaceType;
  typedef GridViewImp GridViewType;
  typedef typename VectorType::ScalarType ScalarType;

  typedef LocalFunctional::Codim1Integral< LocalEvaluation::Product< FunctionType > > LocalFunctionalType;
}; // class L2FaceTraits

template< class FunctionType, class VectorImp, class SpaceImp, class GridViewImp >
class L2Face
  : public Functional::AssemblableFaceBase< L2FaceTraits< FunctionType, VectorImp, SpaceImp, GridViewImp > >
{
  typedef L2FaceTraits< FunctionType, VectorImp, SpaceImp, GridViewImp >  Traits;
  typedef Functional::AssemblableFaceBase< Traits >                       BaseType;

public:
  typedef typename Traits::VectorType VectorType;
  typedef typename Traits::SpaceType  SpaceType;
  typedef typename Traits::GridViewType GridViewType;

private:
  typedef typename Traits::LocalFunctionalType LocalFunctionalType;

public:
  L2Face(const FunctionType& function, VectorType& vector, const SpaceType& space, const GridViewType& grid_view)
    : BaseType(vector, space, grid_view)
    , local_functional_(function)
  {}

  L2Face(const FunctionType& function, VectorType& vector, const SpaceType& space)
    : BaseType(vector, space)
    , local_functional_(function)
  {}

  virtual const LocalFunctionalType& local_functional() const DS_FINAL
  {
    return local_functional_;
  }

private:
  const LocalFunctionalType local_functional_;
}; // class L2Face

} // namespace Functional
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_FUNCTIONAL_L2_HH
<commit_msg>[functional.l2] minor update<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_FUNCTIONAL_L2_HH
#define DUNE_GDT_FUNCTIONAL_L2_HH

#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/la/container/interfaces.hh>

#include <dune/gdt/localfunctional/codim0.hh>
#include <dune/gdt/localfunctional/codim1.hh>
#include <dune/gdt/localevaluation/product.hh>

#include "base.hh"

namespace Dune {
namespace GDT {
namespace Functional {

template< class FunctionType, class VectorImp, class SpaceImp, class GridViewImp = typename SpaceImp::GridViewType >
class L2Volume;

template< class FunctionType, class VectorImp, class SpaceImp, class GridViewImp >
class L2VolumeTraits
{
  static_assert(std::is_base_of< Stuff::LocalizableFunctionInterface< typename FunctionType::EntityType
                                                                    , typename FunctionType::DomainFieldType
                                                                    , FunctionType::dimDomain
                                                                    , typename FunctionType::RangeFieldType
                                                                    , FunctionType::dimRange
                                                                    , FunctionType::dimRangeCols >
                               , FunctionType >::value,
                "FunctionType has to be derived from Stuff::LocalizableFunctionInterface!");
  static_assert(std::is_base_of< SpaceInterface< typename SpaceImp::Traits >, SpaceImp >::value,
                "SpaceImp has to be derived from SpaceInterface!");
public:
  typedef L2Volume< FunctionType, VectorImp, SpaceImp, GridViewImp > derived_type;
  typedef VectorImp   VectorType;
  typedef SpaceImp    SpaceType;
  typedef GridViewImp GridViewType;
  typedef typename VectorType::ScalarType ScalarType;
  typedef LocalFunctional::Codim0Integral< LocalEvaluation::Product< FunctionType > > LocalFunctionalType;
}; // class L2VolumeTraits

template< class FunctionType, class VectorImp, class SpaceImp, class GridViewImp >
class L2Volume
  : public Functional::AssemblableVolumeBase< L2VolumeTraits< FunctionType, VectorImp, SpaceImp, GridViewImp > >
{
  typedef Functional::AssemblableVolumeBase< L2VolumeTraits< FunctionType, VectorImp, SpaceImp, GridViewImp > > BaseType;
public:
  typedef L2VolumeTraits< FunctionType, VectorImp, SpaceImp, GridViewImp > Traits;
  typedef typename Traits::VectorType VectorType;
  typedef typename Traits::SpaceType  SpaceType;
  typedef typename Traits::GridViewType GridViewType;

private:
  typedef typename Traits::LocalFunctionalType LocalFunctionalType;

public:
  L2Volume(const FunctionType& function, VectorType& vector, const SpaceType& space, const GridViewType& grid_view)
    : BaseType(vector, space, grid_view)
    , local_functional_(function)
  {}

  L2Volume(const FunctionType& function, VectorType& vector, const SpaceType& space)
    : BaseType(vector, space)
    , local_functional_(function)
  {}

  virtual const LocalFunctionalType& local_functional() const DS_OVERRIDE DS_FINAL
  {
    return local_functional_;
  }

private:
  const LocalFunctionalType local_functional_;
}; // class L2Volume

template< class FunctionType, class VectorImp, class SpaceImp, class GridViewImp = typename SpaceImp::GridViewType >
class L2Face;

template< class FunctionType, class VectorImp, class SpaceImp, class GridViewImp >
class L2FaceTraits
{
  static_assert(std::is_base_of< Stuff::LocalizableFunctionInterface< typename FunctionType::EntityType
                                                                    , typename FunctionType::DomainFieldType
                                                                    , FunctionType::dimDomain
                                                                    , typename FunctionType::RangeFieldType
                                                                    , FunctionType::dimRange
                                                                    , FunctionType::dimRangeCols >
                               , FunctionType >::value,
                "FunctionType has to be derived from Stuff::LocalizableFunctionInterface!");
  static_assert(std::is_base_of< SpaceInterface< typename SpaceImp::Traits >, SpaceImp >::value,
                "SpaceImp has to be derived from SpaceInterface!");
public:
  typedef L2Face< FunctionType, VectorImp, SpaceImp, GridViewImp > derived_type;
  typedef VectorImp   VectorType;
  typedef SpaceImp    SpaceType;
  typedef GridViewImp GridViewType;
  typedef typename VectorType::ScalarType ScalarType;
  typedef LocalFunctional::Codim1Integral< LocalEvaluation::Product< FunctionType > > LocalFunctionalType;
}; // class L2FaceTraits

template< class FunctionType, class VectorImp, class SpaceImp, class GridViewImp >
class L2Face
  : public Functional::AssemblableFaceBase< L2FaceTraits< FunctionType, VectorImp, SpaceImp, GridViewImp > >
{
  typedef Functional::AssemblableFaceBase< L2FaceTraits< FunctionType, VectorImp, SpaceImp, GridViewImp > > BaseType;
public:
  typedef L2FaceTraits< FunctionType, VectorImp, SpaceImp, GridViewImp > Traits;

  typedef typename Traits::VectorType VectorType;
  typedef typename Traits::SpaceType  SpaceType;
  typedef typename Traits::GridViewType GridViewType;

private:
  typedef typename Traits::LocalFunctionalType LocalFunctionalType;

public:
  L2Face(const FunctionType& function, VectorType& vector, const SpaceType& space, const GridViewType& grid_view)
    : BaseType(vector, space, grid_view)
    , local_functional_(function)
  {}

  L2Face(const FunctionType& function, VectorType& vector, const SpaceType& space)
    : BaseType(vector, space)
    , local_functional_(function)
  {}

  virtual const LocalFunctionalType& local_functional() const DS_OVERRIDE DS_FINAL
  {
    return local_functional_;
  }

private:
  const LocalFunctionalType local_functional_;
}; // class L2Face

} // namespace Functional
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_FUNCTIONAL_L2_HH
<|endoftext|>


<commit_before>// $Header$

#include "TPCLoaderEditor.h"
#include <Alieve/TPCLoader.h>
#include <Reve/RGTopFrame.h>
#include <Reve/RGValuators.h>

#include <TSystem.h>
#include <TVirtualPad.h>
#include <TColor.h>

#include <TGLabel.h>
#include <TGButton.h>
#include <TGTextEntry.h>
#include <TGNumberEntry.h>
#include <TGFileDialog.h>

using namespace Reve;
using namespace Alieve;

//______________________________________________________________________
// TPCLoaderEditor
//

ClassImp(TPCLoaderEditor)

TPCLoaderEditor::TPCLoaderEditor(const TGWindow *p, Int_t id, Int_t width, Int_t height,
				 UInt_t options, Pixel_t back) :
  TGedFrame(p, id, width, height, options | kVerticalFrame, back)
{
  fM = 0;
  MakeTitle("TPCLoader");

  Int_t labelW = 42;
  {
    TGHorizontalFrame* f = new TGHorizontalFrame(this);
    TGHorizontalFrame* g = new TGHorizontalFrame(f, labelW, 0, kFixedWidth);
    TGLabel* l = new TGLabel(g, "File: ");
    g->AddFrame(l, new TGLayoutHints(kLHintsLeft, 0,0,4,0));
    f->AddFrame(g);
    fFile = new TGTextEntry(f);
    fFile->SetWidth(140);
    f->AddFrame(fFile);
    fFile->Connect("DoubleClicked()",
		   "Alieve::TPCLoaderEditor", this, "FileSelect()");
    fFile->Connect("TextChanged(const char *)",
		   "Alieve::TPCLoaderEditor", this, "FileChanged()");
    fOpenFile = new TGTextButton(f, "Open");
    f->AddFrame(fOpenFile);
    fOpenFile->Connect("Clicked()",
		       "Alieve::TPCLoaderEditor", this, "DoOpen()");
    AddFrame(f);
  }

  fEvent = new RGValuator(this, "Event:", 110, 0);
  fEvent->SetShowSlider(kFALSE);
  fEvent->SetLabelWidth(labelW);
  fEvent->SetNELength(6);
  fEvent->Build();
  fEvent->SetLimits(0, 1000);
  fEvent->SetToolTip("Current event number");
  fEvent->Connect("ValueSet(Double_t)",
		  "Alieve::TPCLoaderEditor", this, "DoEvent()");
  // Reuse Event for DoubleSR button
  fDoubleSR = new TGCheckButton(fEvent, "Double SR");
  fDoubleSR->SetToolTipText("Double sampling rate");
  fEvent->AddFrame(fDoubleSR, new TGLayoutHints(kLHintsLeft, 12, 0, 1, 0));
  fDoubleSR->Connect("Toggled(Bool_t)","Alieve::TPCSectorVizEditor", this, "DoDoubleSR()");
  AddFrame(fEvent);

  fUpdateSectors = new TGTextButton(this, "Update Sectors");
  AddFrame(fUpdateSectors, new TGLayoutHints(kLHintsExpandX, 8,8,8,0));
  fUpdateSectors->Connect("Clicked()",
		     "Alieve::TPCLoaderEditor", this, "DoUpdateSectors()");
  {
    TGHorizontalFrame* f = new TGHorizontalFrame(this);
    fCreateSectors3D = new TGTextButton(f, "Create 3D");
    f->AddFrame(fCreateSectors3D, new TGLayoutHints(kLHintsExpandX, 0,4,0,0));
    fCreateSectors3D->Connect("Clicked()",
		     "Alieve::TPCLoaderEditor", this, "DoCreateSectors3D()");
    fDeleteSectors3D = new TGTextButton(f, "Delete 3D");
    f->AddFrame(fDeleteSectors3D, new TGLayoutHints(kLHintsExpandX, 4,0,0,0));
    fDeleteSectors3D->Connect("Clicked()",
		     "Alieve::TPCLoaderEditor", this, "DoDeleteSectors3D()");
    AddFrame(f, new TGLayoutHints(kLHintsExpandX, 8,8,8,0));
  }

  // Register the editor.
  TClass *cl = TPCLoader::Class();
  TGedElement *ge = new TGedElement;
  ge->fGedFrame = this;
  ge->fCanvas = 0;
  cl->GetEditorList()->Add(ge);
}

TPCLoaderEditor::~TPCLoaderEditor()
{}

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

void TPCLoaderEditor::SetModel(TVirtualPad* pad, TObject* obj, Int_t /*event*/)
{
  fModel = 0;
  fPad   = 0;

  if (!obj || !obj->InheritsFrom(TPCLoader::Class()) || obj->InheritsFrom(TVirtualPad::Class())) {
    SetActive(kFALSE);
    return;
  }

  fModel = obj;
  fPad   = pad;

  fM = dynamic_cast<TPCLoader*>(fModel);

  fFile->SetText(fM->fFile);
  fEvent->SetValue(fM->fEvent);
  fEvent->SetEnabled(fM->fEvent >= 0);
  fDoubleSR->SetState(fM->fDoubleSR  ? kButtonDown : kButtonUp);

  SetActive();
}

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

namespace {
const char *tpcfiletypes[] = {
   "Root files",  "*.root",
   "All files",   "*.*",
    0,               0
};
}

void TPCLoaderEditor::FileSelect()
{
  TGFileInfo fi;
  fi.fFileTypes = tpcfiletypes;
  new TGFileDialog(fClient->GetRoot(), gReve, kFDOpen, &fi);
  if (!fi.fFilename) return;
  fFile->SetText(gSystem->BaseName(fi.fFilename));
}

void TPCLoaderEditor::FileChanged()
{
  fM->fFile = fFile->GetText();
}

void TPCLoaderEditor::DoOpen()
{
  fM->OpenFile();
  SetModel(fPad, fModel, 0);
}

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

void TPCLoaderEditor::DoEvent()
{
  fM->GotoEvent((Int_t) fEvent->GetValue());
  SetModel(fPad, fModel, 0);
}

void TPCLoaderEditor::DoDoubleSR()
{
  fM->SetDoubleSR(fDoubleSR->IsOn());
  Update();
}

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

void TPCLoaderEditor::DoUpdateSectors()
{
  fM->UpdateSectors();
}

void TPCLoaderEditor::DoCreateSectors3D()
{
  fM->CreateSectors3D();
}

void TPCLoaderEditor::DoDeleteSectors3D()
{
  fM->DeleteSectors3D();
}

<commit_msg>Fixed target class for fDoubleSR signal connect.<commit_after>// $Header$

#include "TPCLoaderEditor.h"
#include <Alieve/TPCLoader.h>
#include <Reve/RGTopFrame.h>
#include <Reve/RGValuators.h>

#include <TSystem.h>
#include <TVirtualPad.h>
#include <TColor.h>

#include <TGLabel.h>
#include <TGButton.h>
#include <TGTextEntry.h>
#include <TGNumberEntry.h>
#include <TGFileDialog.h>

using namespace Reve;
using namespace Alieve;

//______________________________________________________________________
// TPCLoaderEditor
//

ClassImp(TPCLoaderEditor)

TPCLoaderEditor::TPCLoaderEditor(const TGWindow *p, Int_t id, Int_t width, Int_t height,
				 UInt_t options, Pixel_t back) :
  TGedFrame(p, id, width, height, options | kVerticalFrame, back)
{
  fM = 0;
  MakeTitle("TPCLoader");

  Int_t labelW = 42;
  {
    TGHorizontalFrame* f = new TGHorizontalFrame(this);
    TGHorizontalFrame* g = new TGHorizontalFrame(f, labelW, 0, kFixedWidth);
    TGLabel* l = new TGLabel(g, "File: ");
    g->AddFrame(l, new TGLayoutHints(kLHintsLeft, 0,0,4,0));
    f->AddFrame(g);
    fFile = new TGTextEntry(f);
    fFile->SetWidth(140);
    f->AddFrame(fFile);
    fFile->Connect("DoubleClicked()",
		   "Alieve::TPCLoaderEditor", this, "FileSelect()");
    fFile->Connect("TextChanged(const char *)",
		   "Alieve::TPCLoaderEditor", this, "FileChanged()");
    fOpenFile = new TGTextButton(f, "Open");
    f->AddFrame(fOpenFile);
    fOpenFile->Connect("Clicked()",
		       "Alieve::TPCLoaderEditor", this, "DoOpen()");
    AddFrame(f);
  }

  fEvent = new RGValuator(this, "Event:", 110, 0);
  fEvent->SetShowSlider(kFALSE);
  fEvent->SetLabelWidth(labelW);
  fEvent->SetNELength(6);
  fEvent->Build();
  fEvent->SetLimits(0, 1000);
  fEvent->SetToolTip("Current event number");
  fEvent->Connect("ValueSet(Double_t)",
		  "Alieve::TPCLoaderEditor", this, "DoEvent()");
  // Reuse Event for DoubleSR button
  fDoubleSR = new TGCheckButton(fEvent, "Double SR");
  fDoubleSR->SetToolTipText("Double sampling rate");
  fEvent->AddFrame(fDoubleSR, new TGLayoutHints(kLHintsLeft, 12, 0, 1, 0));
  fDoubleSR->Connect("Toggled(Bool_t)",
                     "Alieve::TPCLoaderEditor", this, "DoDoubleSR()");
  AddFrame(fEvent);

  fUpdateSectors = new TGTextButton(this, "Update Sectors");
  AddFrame(fUpdateSectors, new TGLayoutHints(kLHintsExpandX, 8,8,8,0));
  fUpdateSectors->Connect("Clicked()",
		     "Alieve::TPCLoaderEditor", this, "DoUpdateSectors()");
  {
    TGHorizontalFrame* f = new TGHorizontalFrame(this);
    fCreateSectors3D = new TGTextButton(f, "Create 3D");
    f->AddFrame(fCreateSectors3D, new TGLayoutHints(kLHintsExpandX, 0,4,0,0));
    fCreateSectors3D->Connect("Clicked()",
		     "Alieve::TPCLoaderEditor", this, "DoCreateSectors3D()");
    fDeleteSectors3D = new TGTextButton(f, "Delete 3D");
    f->AddFrame(fDeleteSectors3D, new TGLayoutHints(kLHintsExpandX, 4,0,0,0));
    fDeleteSectors3D->Connect("Clicked()",
		     "Alieve::TPCLoaderEditor", this, "DoDeleteSectors3D()");
    AddFrame(f, new TGLayoutHints(kLHintsExpandX, 8,8,8,0));
  }

  // Register the editor.
  TClass *cl = TPCLoader::Class();
  TGedElement *ge = new TGedElement;
  ge->fGedFrame = this;
  ge->fCanvas = 0;
  cl->GetEditorList()->Add(ge);
}

TPCLoaderEditor::~TPCLoaderEditor()
{}

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

void TPCLoaderEditor::SetModel(TVirtualPad* pad, TObject* obj, Int_t /*event*/)
{
  fModel = 0;
  fPad   = 0;

  if (!obj || !obj->InheritsFrom(TPCLoader::Class()) || obj->InheritsFrom(TVirtualPad::Class())) {
    SetActive(kFALSE);
    return;
  }

  fModel = obj;
  fPad   = pad;

  fM = dynamic_cast<TPCLoader*>(fModel);

  fFile->SetText(fM->fFile);
  fEvent->SetValue(fM->fEvent);
  fEvent->SetEnabled(fM->fEvent >= 0);
  fDoubleSR->SetState(fM->fDoubleSR  ? kButtonDown : kButtonUp);

  SetActive();
}

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

namespace {
const char *tpcfiletypes[] = {
   "Root files",  "*.root",
   "All files",   "*.*",
    0,               0
};
}

void TPCLoaderEditor::FileSelect()
{
  TGFileInfo fi;
  fi.fFileTypes = tpcfiletypes;
  new TGFileDialog(fClient->GetRoot(), gReve, kFDOpen, &fi);
  if (!fi.fFilename) return;
  fFile->SetText(gSystem->BaseName(fi.fFilename));
}

void TPCLoaderEditor::FileChanged()
{
  fM->fFile = fFile->GetText();
}

void TPCLoaderEditor::DoOpen()
{
  fM->OpenFile();
  SetModel(fPad, fModel, 0);
}

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

void TPCLoaderEditor::DoEvent()
{
  fM->GotoEvent((Int_t) fEvent->GetValue());
  SetModel(fPad, fModel, 0);
}

void TPCLoaderEditor::DoDoubleSR()
{
  fM->SetDoubleSR(fDoubleSR->IsOn());
  Update();
}

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

void TPCLoaderEditor::DoUpdateSectors()
{
  fM->UpdateSectors();
}

void TPCLoaderEditor::DoCreateSectors3D()
{
  fM->CreateSectors3D();
}

void TPCLoaderEditor::DoDeleteSectors3D()
{
  fM->DeleteSectors3D();
}

<|endoftext|>


<commit_before>extern "C" {
#include "q.h"
}

#include <gtest/gtest.h>
#include <queue>
#include <functional>
#include <algorithm>
#include <random>
#include <chrono>
#include <limits>
#include <iterator>

class Model : public ::testing::Test
{
    protected:
        virtual void SetUp()
        {
            InitQ(&q);
            auto seed = std::chrono::system_clock::now().time_since_epoch().count();
            rng.seed(seed);
        }

        virtual void TearDown()
        {
            FreeQ(&q);
        }

        Q q;
        std::queue<int> model;
        std::mt19937 rng;
};

TEST_F(Model, TheIDontHaveAllFuckingDaySoMakeTheComputerDoMyHomeworkTest)
{
    std::uniform_int_distribution<int> datum(
            std::numeric_limits<int>::min(),
            std::numeric_limits<int>::max());
    std::uniform_int_distribution<int> ntests(0, 1000);

    //Generate a random number of inserts
    auto const ninserts = ntests(rng);

    for(auto n = 0; n < ninserts; ++n)
    {
        auto r = ntests(rng);
        model.push(r);
        AddQ(&q, &r);
    }

    //Generate a random number of reads/pops
    auto const npops = ntests(rng);
    for(auto n = 0; n < npops; ++n)
    {
        model.pop();
        DelQ(&q);
    }

    //Generate a random number of more inserts to verify circular
    //dynamic functionality.  Verify we can write, read, write and read
    //again in any amount.
    auto const nreinserts = ntests(rng);
    for(auto n = 0; n < nreinserts; ++n)
    {
        auto r = datum(rng);
        model.push(r);
        AddQ(&q, &r);
    }

    //Verify from the model
    for(auto r = model.front(); r != model.back(); ++r)
    {
        if(r != *DelQ(&q))
        {
            std::cout << "Test Failed:\n"
                << "\tInserts: " << ninserts << '\n'
                << "\tDeletes: " << npops << '\n'
                << "\tReinserts: " << nreinserts << '\n';
            FAIL();
        }
    }
}

class Directed : public ::testing::Test
{
    protected:
        virtual void SetUp()
        {
            InitQ(&q);
        }

        virtual void TearDown()
        {
            FreeQ(&q);
        }

        Q q;
};

TEST_F(Directed, Add)
{
    for(int i = 1; i < 100; ++i)
    {
        AddQ(&q, &i);
        ASSERT_EQ(i, size_(&q));
    }
    ASSERT_EQ(99, size_(&q));
    for(int i = 1; i < 100; ++i)
    {
        ASSERT_EQ(i, *DelQ(&q));
    }
    ASSERT_EQ(0, size_(&q));
}

TEST_F(Directed, PutGet)
{
    int i = 8;
    AddQ(&q, &i);
    ASSERT_EQ(8, *DelQ(&q));
}

TEST_F(Directed, DeleteEmpty)
{
    Q q;
    InitQ(&q);

    DelQ(&q);
}

<commit_msg>Running through randomized test cases.<commit_after>extern "C" {
#include "q.h"
}

#include <gtest/gtest.h>
#include <deque>
#include <functional>
#include <algorithm>
#include <random>
#include <chrono>
#include <limits>
#include <iterator>

class Model : public ::testing::Test
{
    protected:
        virtual void SetUp()
        {
            auto seed = std::chrono::system_clock::now().time_since_epoch().count();
            rng.seed(seed);
        }

        virtual void TearDown()
        {
        }

        std::mt19937 rng;
};

bool run_isolated_test(int ninserts, int npops, int nreinserts)
{
    Q q;
    InitQ(&q);
    std::deque<int> model;
    auto result(true);

    for(auto n = 0; n < ninserts; ++n)
    {
        model.push_back(n);
        AddQ(&q, &n);
    }
    for(auto n = 0; n < npops; ++n)
    {
        model.pop_front();
        DelQ(&q);
    }
    for(auto n = 0; n < nreinserts; ++n)
    {
        model.push_back(n);
        AddQ(&q, &n);
    }
    for(auto r : model)
    {
        auto u = *DelQ(&q);

        if(r != u)
        {
            result = false;
        }
    }
    FreeQ(&q);
    return result;
}

TEST_F(Model, TheIDontHaveAllFuckingDaySoMakeTheComputerDoMyHomeworkTest)
{
    std::uniform_int_distribution<int> ntests(0, 1000);

    //Generate a random number of inserts
    auto ninserts = ntests(rng);

    //Generate a random number of reads/pops
    auto npops = ntests(rng);

    //Generate a random number of more inserts to verify circular
    //dynamic functionality.  Verify we can write, read, write and read
    //again in any amount.
    auto nreinserts = ntests(rng);

     std::cout << "Test:\n"
    << "\tInserts: " << ninserts << '\n'
    << "\tDeletes: " << npops << '\n'
    << "\tReinserts: " << nreinserts << '\n';
    //Verify from the model
    if(!run_isolated_test(ninserts, npops, nreinserts))
    {
        std::cout << "Test Failed, minimizing.\n";
        while(ninserts > 0 && run_isolated_test(ninserts, npops, nreinserts) == false)
        {
            --ninserts;
        }
        ++ninserts; //Make it fail again.
        while(npops > 0 && run_isolated_test(ninserts, npops, nreinserts) == false)
        {
            --npops;
        }
        ++npops; //Make it fail again.
        while(nreinserts > 0 && run_isolated_test(ninserts, npops, nreinserts) == false)
        {
            --nreinserts;
        }
        ++nreinserts; //Make it fail again.

        ADD_FAILURE();
        std::cout << "Test:\n"
            << "\tInserts: " << ninserts << '\n'
            << "\tDeletes: " << npops << '\n'
            << "\tReinserts: " << nreinserts << '\n';
    }
}

class Directed : public ::testing::Test
{
    protected:
        virtual void SetUp()
        {
            InitQ(&q);
        }

        virtual void TearDown()
        {
            FreeQ(&q);
        }

        Q q;
};

TEST_F(Directed, RandomMinimizedTest)
{
    ASSERT_TRUE(run_isolated_test(1, 0, 9)); //Random test generator found this test case
}
TEST_F(Directed, Weirdness)
{
    ASSERT_TRUE(run_isolated_test(10, 0, 0)); //10 straight inserts don't fail, but 1 and 9 do.
}
TEST_F(Directed, RandomMinimizedTest2)
{
    ASSERT_TRUE(run_isolated_test(1, 1, 8));
}

TEST_F(Directed, Add)
{
    for(int i = 1; i < 100; ++i)
    {
        AddQ(&q, &i);
        ASSERT_EQ(i, size_(&q));
    }
    ASSERT_EQ(99, size_(&q));
    for(int i = 1; i < 100; ++i)
    {
        ASSERT_EQ(i, *DelQ(&q));
    }
    ASSERT_EQ(0, size_(&q));
}

TEST_F(Directed, PutGet)
{
    int i = 8;
    AddQ(&q, &i);
    ASSERT_EQ(8, *DelQ(&q));
}

TEST_F(Directed, DeleteEmpty)
{
    Q q;
    InitQ(&q);

    DelQ(&q);
}

<|endoftext|>


<commit_before>#pragma once
/*
**  Copyright (C) 2013 Aldebaran Robotics
**  See COPYING for the license
*/

#ifndef _QITYPE_DETAILS_TYPETUPLE_HXX_
#define _QITYPE_DETAILS_TYPETUPLE_HXX_

#include <boost/type_traits.hpp>
#include <boost/utility/enable_if.hpp>
#include <qitype/details/accessor.hxx>
#include <qi/preproc.hpp>

namespace qi
{
  namespace detail {

    //keep only the class name. (remove :: and namespaces)
    QITYPE_API std::string normalizeClassName(const std::string &name);

    template<typename T> void setFromStorage(T& ref, void* storage)
    {
      ref = *(T*)typeOf<T>()->ptrFromStorage(&storage);
    }

    /* Helpers around accessors
     */
    template<typename A> TypeInterface* fieldType(A)
    {
      return qi::typeOf<typename detail::Accessor<A>::value_type>();
    }

    template<typename C, typename A> void* fieldStorage(C* inst, A accessor)
    {
      return fieldType(accessor)->initializeStorage(
        (void*)&detail::Accessor<A>::access(inst, accessor));
    }

    template<typename C, typename A>
    typename detail::Accessor<A>::value_type&
    fieldValue(C* instance, A accessor, void** data)
    {
      typedef typename detail::Accessor<A>::value_type T;
      return *(T*)fieldType(accessor)->ptrFromStorage(data);
    }
  }
}

#define __QI_TYPE_STRUCT_DECLARE(name, extra)                             \
namespace qi {                                                            \
  template<> struct TypeImpl<name>: public ::qi::StructTypeInterface                \
  {                                                                       \
  public:                                                                 \
    typedef name ClassType;                                               \
    virtual std::vector< ::qi::TypeInterface*> memberTypes();                      \
    virtual std::vector<std::string> elementsName();                      \
    virtual std::string className();                                      \
    virtual void* get(void* storage, unsigned int index);                 \
    virtual void set(void** storage, unsigned int index, void* valStorage); \
    extra                                                                   \
    _QI_BOUNCE_TYPE_METHODS(::qi::DefaultTypeImplMethods<name>);            \
 }; }

#define __QI_TUPLE_TYPE(_, what, field) res.push_back(::qi::typeOf(ptr->field));
#define __QI_TUPLE_GET(_, what, field) if (i == index) return ::qi::typeOf(ptr->field)->initializeStorage(&ptr->field); i++;
#define __QI_TUPLE_SET(_, what, field) if (i == index) ::qi::detail::setFromStorage(ptr->field, valueStorage); i++;
#define __QI_TUPLE_FIELD_NAME(_, what, field) res.push_back(BOOST_PP_STRINGIZE(QI_DELAY(field)));
#define __QI_TYPE_STRUCT_IMPLEMENT(name, inl, onSet, ...)                                    \
namespace qi {                                                                        \
  inl std::vector< ::qi::TypeInterface*> TypeImpl<name>::memberTypes()                                \
  {                                                                                \
    name* ptr = 0;                                                                    \
    std::vector< ::qi::TypeInterface*> res;                                                           \
    QI_VAARGS_APPLY(__QI_TUPLE_TYPE, _, __VA_ARGS__);                                 \
    return res;                                                                       \
  }                                                                                \
  inl void* TypeImpl<name>::get(void* storage, unsigned int index)                    \
  {                                                                                \
    unsigned int i = 0;                                                                        \
    name* ptr = (name*)ptrFromStorage(&storage);                                      \
    QI_VAARGS_APPLY(__QI_TUPLE_GET, _, __VA_ARGS__);                                  \
    return 0;                                                                         \
  }                                                                                \
  inl void TypeImpl<name>::set(void** storage, unsigned int index, void* valueStorage)\
  {                                                                                \
    unsigned int i=0;                                                                 \
    name* ptr = (name*)ptrFromStorage(storage);                                       \
    QI_VAARGS_APPLY(__QI_TUPLE_SET, _, __VA_ARGS__);                                  \
    onSet                                                                      \
  }\
  inl std::vector<std::string> TypeImpl<name>::elementsName() \
  {  \
    std::vector<std::string> res; \
    QI_VAARGS_APPLY(__QI_TUPLE_FIELD_NAME, _, __VA_ARGS__); \
    return res; \
  }\
  inl std::string TypeImpl<name>::className() \
  {\
    return ::qi::detail::normalizeClassName(BOOST_PP_STRINGIZE(name));\
  }\
}

/// Declare a struct field using an helper function
#define QI_STRUCT_HELPER(name, func) (name, func, FUNC)
/// Declare a struct feld that is a member (member value or member accessor function)
#define QI_STRUCT_FIELD(name, field) (name, field, FIELD)

// construct pointer-to accessor from free-function
#define __QI_STRUCT_ACCESS_FUNC(fname, field) &field
// construct pointer-to-accessor from member function/field
#define __QI_STRUCT_ACCESS_FIELD(fname, field) &ClassType::field

// invoke the correct __QI_STRUCT_ACCESS_ macro using type
#define __QI_STRUCT_ACCESS_BOUNCE2(name, accessor, type) \
  QI_CAT(__QI_STRUCT_ACCESS_, type)(name, accessor)

// bounce with default value FIELD for argument 3
#define __QI_STRUCT_ACCESS_BOUNCE1(x, y) \
  __QI_STRUCT_ACCESS_BOUNCE2(x, y, FIELD)

// arg-count overload, bounce to __QI_STRUCT_ACCESS_BOUNCE<N>
#define __QI_STRUCT_ACCESS_BOUNCE(...) \
 QI_CAT(__QI_STRUCT_ACCESS_BOUNCE, QI_LIST_VASIZE((__VA_ARGS__)))(__VA_ARGS__)

// accept (name, accessor, type) and (name, accessor) defaulting type to field
#define __QI_STRUCT_ACCESS(tuple) QI_DELAY(__QI_STRUCT_ACCESS_BOUNCE)tuple

#define __QI_ATUPLE_TYPE(_, what, field) res.push_back(::qi::detail::fieldType(__QI_STRUCT_ACCESS(field)));
#define __QI_ATUPLE_GET(_, what, field) if (i == index) return ::qi::detail::fieldStorage(ptr, __QI_STRUCT_ACCESS(field)); i++;
#define __QI_ATUPLE_FIELD_NAME(_, what, field) res.push_back(QI_PAIR_FIRST(field));
#define __QI_ATUPLE_FROMDATA(idx, what, field) ::qi::detail::fieldValue(ptr, __QI_STRUCT_ACCESS(field), const_cast<void**>(&data[idx]))
#define __QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR_IMPLEMENT(name, inl, onSet, ...)\
  namespace qi {                                                                        \
  inl std::vector< ::qi::TypeInterface*> TypeImpl<name>::memberTypes()                                \
  {                                                                                \
    std::vector< ::qi::TypeInterface*> res;                                                           \
    QI_VAARGS_APPLY(__QI_ATUPLE_TYPE, name, __VA_ARGS__);                                 \
    return res;                                                                       \
  }                                                                                \
  \
  inl void* TypeImpl<name>::get(void* storage, unsigned int index)                    \
  {                                                                                \
    unsigned int i = 0;                                                                        \
    name* ptr = (name*)ptrFromStorage(&storage);                                      \
    QI_VAARGS_APPLY(__QI_ATUPLE_GET, name, __VA_ARGS__);                                  \
    return 0;                                                                         \
  }                                                                                \
  \
  inl void TypeImpl<name>::set(void** storage, unsigned int index, void* valueStorage)\
  {\
    throw std::runtime_error("single-field set not implemented");\
  }\
  \
  inl void TypeImpl<name>::set(void** storage, const std::vector<void*>& data) \
  {\
    name* ptr = (name*)ptrFromStorage(storage);         \
    *ptr = name(QI_VAARGS_MAP(__QI_ATUPLE_FROMDATA, name, __VA_ARGS__)); \
  }\
  \
  inl std::vector<std::string> TypeImpl<name>::elementsName() \
  {  \
    std::vector<std::string> res; \
    QI_VAARGS_APPLY(__QI_ATUPLE_FIELD_NAME, _, __VA_ARGS__); \
    return res; \
  }\
  inl std::string TypeImpl<name>::className() \
  \
  { \
    return ::qi::detail::normalizeClassName(BOOST_PP_STRINGIZE(name));\
  } \
  }

/// Allow the QI_TYPE_STRUCT macro and variants to access private members
#define QI_TYPE_STRUCT_PRIVATE_ACCESS(name) \
friend class qi::TypeImpl<name>;

/** Declare a simple struct to the type system.
 * First argument is the structure name. Remaining arguments are the structure
 * fields.
 * This macro must be called outside any namespace.
 * This macro should be called in the header file defining the structure 'name',
 * or in a header included by all source files using the structure.
 * See QI_TYPE_STRUCT_REGISTER for a similar macro that can be called from a
 * single source file.
 */
#define QI_TYPE_STRUCT(name, ...) \
  QI_TYPE_STRUCT_DECLARE(name) \
  __QI_TYPE_STRUCT_IMPLEMENT(name, inline, /**/, __VA_ARGS__)

/** Similar to QI_TYPE_STRUCT, but evaluates 'onSet' after writting to an instance.
 * The instance is accessible through the variable 'ptr'.
 */
#define QI_TYPE_STRUCT_EX(name, onSet, ...) \
  QI_TYPE_STRUCT_DECLARE(name) \
  __QI_TYPE_STRUCT_IMPLEMENT(name, inline, onSet, __VA_ARGS__)

#define QI_TYPE_STRUCT_IMPLEMENT(name, ...) \
  __QI_TYPE_STRUCT_IMPLEMENT(name, /**/, /**/, __VA_ARGS__)

/** Register a struct with member field/function getters, and constructor setter
 *
 * Call like that:
 *    QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR(Point,
 *       ("x", getX),
 *       ("y", y))
 *
 * The first macro argument is the class full name including namespace.
 * Remaining arguments can be:
 *  - (fieldName, accessor): accessor must be:
 *        - a member function returning a const T& with no argument
 *        - a member field
 *  - QI_STRUCT_FIELD(fieldName, accessor): Same thing as above, provided for
 *      consistency.
 *  - QI_STRUCT_HELPER(fieldName, function). Function must be a free function
 *       taking a class pointer, and returning a const T&
 *
 * The class must provide a constructor that accepts all fields as argument, in
 * the order in which they are declared in the macro.
 *
 * Must be called outside any namespace.
 */
#define QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR(name, ...)     \
  __QI_TYPE_STRUCT_DECLARE(name,                             \
    virtual void set(void** storage, const std::vector<void*>&);) \
    __QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR_IMPLEMENT(name, inline, /**/, __VA_ARGS__)

/** Similar to QI_TYPE_STRUCT, but using the runtime factory instead of the
 * compile-time template.
 *
 */
#define QI_TYPE_STRUCT_REGISTER(name, ...) \
namespace _qi_ {                           \
    QI_TYPE_STRUCT(name, __VA_ARGS__);     \
}                                          \
QI_TYPE_REGISTER_CUSTOM(name, _qi_::qi::TypeImpl<name>)

/** Similar to QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR,
 * but using the runtime factory instead of the
 * compile-time template.
 *
 */
#define QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR_REGISTER(name, ...) \
namespace _qi_ {                           \
    QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR(name, __VA_ARGS__);     \
}                                          \
QI_TYPE_REGISTER_CUSTOM(name, _qi_::qi::TypeImpl<name>)

/** Declares that name is equivalent to type bounceTo, and that instances
 * can be converted using the conversion function with signature 'bounceTo* (name*)'.
 * This macro should be called in a header included by all code using the 'name'
 * class.
 * See QI_TYPE_STRUCT_BOUNCE_REGISTER for a similar macro that can be called from a
 * single source file.
 */
#define QI_TYPE_STRUCT_BOUNCE(name, bounceTo, conversion)                 \
namespace qi {                                                            \
template<> class TypeImpl<name>: public ::qi::StructTypeInterfaceBouncer<name, bounceTo>  \
{                                                                         \
public:                                                                   \
  void adaptStorage(void** storage, void** adapted)                       \
  {                                                                       \
    name* ptr = (name*)ptrFromStorage(storage);                           \
    bounceTo * tptr = conversion(ptr);                                    \
    *adapted = bounceType()->initializeStorage(tptr);                     \
  }                                                                       \
};}

/** Similar to QI_TYPE_STRUCT_BOUNCE, but using the runtime factory instead of the
 * compile-time template.
 */
#define QI_TYPE_STRUCT_BOUNCE_REGISTER(name, bounceTo, conversion)        \
namespace _qi_ {                                                          \
    QI_TYPE_STRUCT_BOUNCE(name, bounceTo, conversion);                    \
}                                                                         \
QI_TYPE_REGISTER_CUSTOM(name, _qi_::qi::TypeImpl<name>)

namespace qi {
  //TODO
  template<typename T, typename TO>
  class StructTypeInterfaceBouncer: public StructTypeInterface
  {
  public:
    StructTypeInterface* bounceType()
    {
      static TypeInterface* result = 0;
      if (!result)
        result = typeOf<TO>();
      return static_cast<StructTypeInterface*>(result);
    }

    virtual void adaptStorage(void** storage, void** adapted) = 0;

    typedef DefaultTypeImplMethods<T> Methods;
    virtual std::vector<TypeInterface*> memberTypes()
    {
      return bounceType()->memberTypes();
    }

    virtual void* get(void* storage, unsigned int index)
    {
      void* astorage;
      adaptStorage(&storage, &astorage);
      return bounceType()->get(astorage, index);
    }

    virtual void set(void** storage, unsigned int index, void* valStorage)
    {
      void* astorage;
      adaptStorage(storage, &astorage);
      bounceType()->set(&astorage, index, valStorage);
    }

    _QI_BOUNCE_TYPE_METHODS(Methods);
  };

  template<typename F, typename S>
  class TypeImpl<std::pair<F, S> >: public StructTypeInterface
  {
  public:
    typedef DefaultTypeImplMethods<std::pair<F, S> > Methods;
    typedef typename std::pair<F, S> BackendType;
    std::vector<TypeInterface*> memberTypes()
    {
      static std::vector<TypeInterface*>* result=0;
      if (!result)
      {
        result = new std::vector<TypeInterface*>();
        result->push_back(typeOf<F>());
        result->push_back(typeOf<S>());
      }
      return *result;
    }
    void* get(void* storage, unsigned int index)
    {
      BackendType* ptr = (BackendType*)ptrFromStorage(&storage);
      // Will work if F or S are references
      if (!index)
        return typeOf<F>()->initializeStorage(const_cast<void*>((void*)&ptr->first));
      else
        return typeOf<S>()->initializeStorage(const_cast<void*>((void*)&ptr->second));
    }
    void set(void** storage, unsigned int index, void* valStorage)
    {
      BackendType* ptr = (BackendType*)ptrFromStorage(storage);
      if (!index)
        detail::TypeManagerDefault<F>::copy(const_cast<void*>((void*)&ptr->first), typeOf<F>()->ptrFromStorage(&valStorage));
      else
        detail::TypeManagerDefault<S>::copy(const_cast<void*>((void*)&ptr->second), typeOf<S>()->ptrFromStorage(&valStorage));
    }
    _QI_BOUNCE_TYPE_METHODS(Methods);
  };

}
#endif  // _QITYPE_DETAILS_TYPETUPLE_HXX_
<commit_msg>Add struct bounce for elementsName()<commit_after>#pragma once
/*
**  Copyright (C) 2013 Aldebaran Robotics
**  See COPYING for the license
*/

#ifndef _QITYPE_DETAILS_TYPETUPLE_HXX_
#define _QITYPE_DETAILS_TYPETUPLE_HXX_

#include <boost/type_traits.hpp>
#include <boost/utility/enable_if.hpp>
#include <qitype/details/accessor.hxx>
#include <qi/preproc.hpp>

namespace qi
{
  namespace detail {

    //keep only the class name. (remove :: and namespaces)
    QITYPE_API std::string normalizeClassName(const std::string &name);

    template<typename T> void setFromStorage(T& ref, void* storage)
    {
      ref = *(T*)typeOf<T>()->ptrFromStorage(&storage);
    }

    /* Helpers around accessors
     */
    template<typename A> TypeInterface* fieldType(A)
    {
      return qi::typeOf<typename detail::Accessor<A>::value_type>();
    }

    template<typename C, typename A> void* fieldStorage(C* inst, A accessor)
    {
      return fieldType(accessor)->initializeStorage(
        (void*)&detail::Accessor<A>::access(inst, accessor));
    }

    template<typename C, typename A>
    typename detail::Accessor<A>::value_type&
    fieldValue(C* instance, A accessor, void** data)
    {
      typedef typename detail::Accessor<A>::value_type T;
      return *(T*)fieldType(accessor)->ptrFromStorage(data);
    }
  }
}

#define __QI_TYPE_STRUCT_DECLARE(name, extra)                             \
namespace qi {                                                            \
  template<> struct TypeImpl<name>: public ::qi::StructTypeInterface                \
  {                                                                       \
  public:                                                                 \
    typedef name ClassType;                                               \
    virtual std::vector< ::qi::TypeInterface*> memberTypes();                      \
    virtual std::vector<std::string> elementsName();                      \
    virtual std::string className();                                      \
    virtual void* get(void* storage, unsigned int index);                 \
    virtual void set(void** storage, unsigned int index, void* valStorage); \
    extra                                                                   \
    _QI_BOUNCE_TYPE_METHODS(::qi::DefaultTypeImplMethods<name>);            \
 }; }

#define __QI_TUPLE_TYPE(_, what, field) res.push_back(::qi::typeOf(ptr->field));
#define __QI_TUPLE_GET(_, what, field) if (i == index) return ::qi::typeOf(ptr->field)->initializeStorage(&ptr->field); i++;
#define __QI_TUPLE_SET(_, what, field) if (i == index) ::qi::detail::setFromStorage(ptr->field, valueStorage); i++;
#define __QI_TUPLE_FIELD_NAME(_, what, field) res.push_back(BOOST_PP_STRINGIZE(QI_DELAY(field)));
#define __QI_TYPE_STRUCT_IMPLEMENT(name, inl, onSet, ...)                                    \
namespace qi {                                                                        \
  inl std::vector< ::qi::TypeInterface*> TypeImpl<name>::memberTypes()                                \
  {                                                                                \
    name* ptr = 0;                                                                    \
    std::vector< ::qi::TypeInterface*> res;                                                           \
    QI_VAARGS_APPLY(__QI_TUPLE_TYPE, _, __VA_ARGS__);                                 \
    return res;                                                                       \
  }                                                                                \
  inl void* TypeImpl<name>::get(void* storage, unsigned int index)                    \
  {                                                                                \
    unsigned int i = 0;                                                                        \
    name* ptr = (name*)ptrFromStorage(&storage);                                      \
    QI_VAARGS_APPLY(__QI_TUPLE_GET, _, __VA_ARGS__);                                  \
    return 0;                                                                         \
  }                                                                                \
  inl void TypeImpl<name>::set(void** storage, unsigned int index, void* valueStorage)\
  {                                                                                \
    unsigned int i=0;                                                                 \
    name* ptr = (name*)ptrFromStorage(storage);                                       \
    QI_VAARGS_APPLY(__QI_TUPLE_SET, _, __VA_ARGS__);                                  \
    onSet                                                                      \
  }\
  inl std::vector<std::string> TypeImpl<name>::elementsName() \
  {  \
    std::vector<std::string> res; \
    QI_VAARGS_APPLY(__QI_TUPLE_FIELD_NAME, _, __VA_ARGS__); \
    return res; \
  }\
  inl std::string TypeImpl<name>::className() \
  {\
    return ::qi::detail::normalizeClassName(BOOST_PP_STRINGIZE(name));\
  }\
}

/// Declare a struct field using an helper function
#define QI_STRUCT_HELPER(name, func) (name, func, FUNC)
/// Declare a struct feld that is a member (member value or member accessor function)
#define QI_STRUCT_FIELD(name, field) (name, field, FIELD)

// construct pointer-to accessor from free-function
#define __QI_STRUCT_ACCESS_FUNC(fname, field) &field
// construct pointer-to-accessor from member function/field
#define __QI_STRUCT_ACCESS_FIELD(fname, field) &ClassType::field

// invoke the correct __QI_STRUCT_ACCESS_ macro using type
#define __QI_STRUCT_ACCESS_BOUNCE2(name, accessor, type) \
  QI_CAT(__QI_STRUCT_ACCESS_, type)(name, accessor)

// bounce with default value FIELD for argument 3
#define __QI_STRUCT_ACCESS_BOUNCE1(x, y) \
  __QI_STRUCT_ACCESS_BOUNCE2(x, y, FIELD)

// arg-count overload, bounce to __QI_STRUCT_ACCESS_BOUNCE<N>
#define __QI_STRUCT_ACCESS_BOUNCE(...) \
 QI_CAT(__QI_STRUCT_ACCESS_BOUNCE, QI_LIST_VASIZE((__VA_ARGS__)))(__VA_ARGS__)

// accept (name, accessor, type) and (name, accessor) defaulting type to field
#define __QI_STRUCT_ACCESS(tuple) QI_DELAY(__QI_STRUCT_ACCESS_BOUNCE)tuple

#define __QI_ATUPLE_TYPE(_, what, field) res.push_back(::qi::detail::fieldType(__QI_STRUCT_ACCESS(field)));
#define __QI_ATUPLE_GET(_, what, field) if (i == index) return ::qi::detail::fieldStorage(ptr, __QI_STRUCT_ACCESS(field)); i++;
#define __QI_ATUPLE_FIELD_NAME(_, what, field) res.push_back(QI_PAIR_FIRST(field));
#define __QI_ATUPLE_FROMDATA(idx, what, field) ::qi::detail::fieldValue(ptr, __QI_STRUCT_ACCESS(field), const_cast<void**>(&data[idx]))
#define __QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR_IMPLEMENT(name, inl, onSet, ...)\
  namespace qi {                                                                        \
  inl std::vector< ::qi::TypeInterface*> TypeImpl<name>::memberTypes()                                \
  {                                                                                \
    std::vector< ::qi::TypeInterface*> res;                                                           \
    QI_VAARGS_APPLY(__QI_ATUPLE_TYPE, name, __VA_ARGS__);                                 \
    return res;                                                                       \
  }                                                                                \
  \
  inl void* TypeImpl<name>::get(void* storage, unsigned int index)                    \
  {                                                                                \
    unsigned int i = 0;                                                                        \
    name* ptr = (name*)ptrFromStorage(&storage);                                      \
    QI_VAARGS_APPLY(__QI_ATUPLE_GET, name, __VA_ARGS__);                                  \
    return 0;                                                                         \
  }                                                                                \
  \
  inl void TypeImpl<name>::set(void** storage, unsigned int index, void* valueStorage)\
  {\
    throw std::runtime_error("single-field set not implemented");\
  }\
  \
  inl void TypeImpl<name>::set(void** storage, const std::vector<void*>& data) \
  {\
    name* ptr = (name*)ptrFromStorage(storage);         \
    *ptr = name(QI_VAARGS_MAP(__QI_ATUPLE_FROMDATA, name, __VA_ARGS__)); \
  }\
  \
  inl std::vector<std::string> TypeImpl<name>::elementsName() \
  {  \
    std::vector<std::string> res; \
    QI_VAARGS_APPLY(__QI_ATUPLE_FIELD_NAME, _, __VA_ARGS__); \
    return res; \
  }\
  inl std::string TypeImpl<name>::className() \
  \
  { \
    return ::qi::detail::normalizeClassName(BOOST_PP_STRINGIZE(name));\
  } \
  }

/// Allow the QI_TYPE_STRUCT macro and variants to access private members
#define QI_TYPE_STRUCT_PRIVATE_ACCESS(name) \
friend class qi::TypeImpl<name>;

/** Declare a simple struct to the type system.
 * First argument is the structure name. Remaining arguments are the structure
 * fields.
 * This macro must be called outside any namespace.
 * This macro should be called in the header file defining the structure 'name',
 * or in a header included by all source files using the structure.
 * See QI_TYPE_STRUCT_REGISTER for a similar macro that can be called from a
 * single source file.
 */
#define QI_TYPE_STRUCT(name, ...) \
  QI_TYPE_STRUCT_DECLARE(name) \
  __QI_TYPE_STRUCT_IMPLEMENT(name, inline, /**/, __VA_ARGS__)

/** Similar to QI_TYPE_STRUCT, but evaluates 'onSet' after writting to an instance.
 * The instance is accessible through the variable 'ptr'.
 */
#define QI_TYPE_STRUCT_EX(name, onSet, ...) \
  QI_TYPE_STRUCT_DECLARE(name) \
  __QI_TYPE_STRUCT_IMPLEMENT(name, inline, onSet, __VA_ARGS__)

#define QI_TYPE_STRUCT_IMPLEMENT(name, ...) \
  __QI_TYPE_STRUCT_IMPLEMENT(name, /**/, /**/, __VA_ARGS__)

/** Register a struct with member field/function getters, and constructor setter
 *
 * Call like that:
 *    QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR(Point,
 *       ("x", getX),
 *       ("y", y))
 *
 * The first macro argument is the class full name including namespace.
 * Remaining arguments can be:
 *  - (fieldName, accessor): accessor must be:
 *        - a member function returning a const T& with no argument
 *        - a member field
 *  - QI_STRUCT_FIELD(fieldName, accessor): Same thing as above, provided for
 *      consistency.
 *  - QI_STRUCT_HELPER(fieldName, function). Function must be a free function
 *       taking a class pointer, and returning a const T&
 *
 * The class must provide a constructor that accepts all fields as argument, in
 * the order in which they are declared in the macro.
 *
 * Must be called outside any namespace.
 */
#define QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR(name, ...)     \
  __QI_TYPE_STRUCT_DECLARE(name,                             \
    virtual void set(void** storage, const std::vector<void*>&);) \
    __QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR_IMPLEMENT(name, inline, /**/, __VA_ARGS__)

/** Similar to QI_TYPE_STRUCT, but using the runtime factory instead of the
 * compile-time template.
 *
 */
#define QI_TYPE_STRUCT_REGISTER(name, ...) \
namespace _qi_ {                           \
    QI_TYPE_STRUCT(name, __VA_ARGS__);     \
}                                          \
QI_TYPE_REGISTER_CUSTOM(name, _qi_::qi::TypeImpl<name>)

/** Similar to QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR,
 * but using the runtime factory instead of the
 * compile-time template.
 *
 */
#define QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR_REGISTER(name, ...) \
namespace _qi_ {                           \
    QI_TYPE_STRUCT_AGREGATE_CONSTRUCTOR(name, __VA_ARGS__);     \
}                                          \
QI_TYPE_REGISTER_CUSTOM(name, _qi_::qi::TypeImpl<name>)

/** Declares that name is equivalent to type bounceTo, and that instances
 * can be converted using the conversion function with signature 'bounceTo* (name*)'.
 * This macro should be called in a header included by all code using the 'name'
 * class.
 * See QI_TYPE_STRUCT_BOUNCE_REGISTER for a similar macro that can be called from a
 * single source file.
 */
#define QI_TYPE_STRUCT_BOUNCE(name, bounceTo, conversion)                 \
namespace qi {                                                            \
template<> class TypeImpl<name>: public ::qi::StructTypeInterfaceBouncer<name, bounceTo>  \
{                                                                         \
public:                                                                   \
  void adaptStorage(void** storage, void** adapted)                       \
  {                                                                       \
    name* ptr = (name*)ptrFromStorage(storage);                           \
    bounceTo * tptr = conversion(ptr);                                    \
    *adapted = bounceType()->initializeStorage(tptr);                     \
  }                                                                       \
};}

/** Similar to QI_TYPE_STRUCT_BOUNCE, but using the runtime factory instead of the
 * compile-time template.
 */
#define QI_TYPE_STRUCT_BOUNCE_REGISTER(name, bounceTo, conversion)        \
namespace _qi_ {                                                          \
    QI_TYPE_STRUCT_BOUNCE(name, bounceTo, conversion);                    \
}                                                                         \
QI_TYPE_REGISTER_CUSTOM(name, _qi_::qi::TypeImpl<name>)

namespace qi {
  //TODO
  template<typename T, typename TO>
  class StructTypeInterfaceBouncer: public StructTypeInterface
  {
  public:
    StructTypeInterface* bounceType()
    {
      static TypeInterface* result = 0;
      if (!result)
        result = typeOf<TO>();
      return static_cast<StructTypeInterface*>(result);
    }

    virtual void adaptStorage(void** storage, void** adapted) = 0;

    typedef DefaultTypeImplMethods<T> Methods;
    virtual std::vector<TypeInterface*> memberTypes()
    {
      return bounceType()->memberTypes();
    }

    virtual void* get(void* storage, unsigned int index)
    {
      void* astorage;
      adaptStorage(&storage, &astorage);
      return bounceType()->get(astorage, index);
    }

    virtual void set(void** storage, unsigned int index, void* valStorage)
    {
      void* astorage;
      adaptStorage(storage, &astorage);
      bounceType()->set(&astorage, index, valStorage);
    }

    virtual std::vector<std::string> elementsName()
    {
      return bounceType()->elementsName();
    }

    _QI_BOUNCE_TYPE_METHODS(Methods);
  };

  template<typename F, typename S>
  class TypeImpl<std::pair<F, S> >: public StructTypeInterface
  {
  public:
    typedef DefaultTypeImplMethods<std::pair<F, S> > Methods;
    typedef typename std::pair<F, S> BackendType;
    std::vector<TypeInterface*> memberTypes()
    {
      static std::vector<TypeInterface*>* result=0;
      if (!result)
      {
        result = new std::vector<TypeInterface*>();
        result->push_back(typeOf<F>());
        result->push_back(typeOf<S>());
      }
      return *result;
    }
    void* get(void* storage, unsigned int index)
    {
      BackendType* ptr = (BackendType*)ptrFromStorage(&storage);
      // Will work if F or S are references
      if (!index)
        return typeOf<F>()->initializeStorage(const_cast<void*>((void*)&ptr->first));
      else
        return typeOf<S>()->initializeStorage(const_cast<void*>((void*)&ptr->second));
    }
    void set(void** storage, unsigned int index, void* valStorage)
    {
      BackendType* ptr = (BackendType*)ptrFromStorage(storage);
      if (!index)
        detail::TypeManagerDefault<F>::copy(const_cast<void*>((void*)&ptr->first), typeOf<F>()->ptrFromStorage(&valStorage));
      else
        detail::TypeManagerDefault<S>::copy(const_cast<void*>((void*)&ptr->second), typeOf<S>()->ptrFromStorage(&valStorage));
    }
    _QI_BOUNCE_TYPE_METHODS(Methods);
  };

}
#endif  // _QITYPE_DETAILS_TYPETUPLE_HXX_
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2015 Kläralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company.  For licensing terms and
** conditions see http://www.qt.io/terms-conditions.  For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "valgrindruncontrolfactory.h"
#include "valgrindsettings.h"
#include "valgrindplugin.h"

#include <analyzerbase/ianalyzertool.h>
#include <analyzerbase/analyzermanager.h>
#include <analyzerbase/analyzerstartparameters.h>
#include <analyzerbase/analyzerruncontrol.h>
#include <analyzerbase/analyzerrunconfigwidget.h>

#include <remotelinux/abstractremotelinuxrunconfiguration.h>

#include <debugger/debuggerrunconfigurationaspect.h>
#include <projectexplorer/environmentaspect.h>
#include <projectexplorer/localapplicationrunconfiguration.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/target.h>

#include <utils/qtcassert.h>

#include <QTcpServer>

using namespace Analyzer;
using namespace ProjectExplorer;

namespace Valgrind {
namespace Internal {

ValgrindRunControlFactory::ValgrindRunControlFactory(QObject *parent) :
    IRunControlFactory(parent)
{
}

bool ValgrindRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const
{
    Q_UNUSED(runConfiguration);
    return mode == CallgrindRunMode || mode == MemcheckRunMode || mode == MemcheckWithGdbRunMode;
}

RunControl *ValgrindRunControlFactory::create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage)
{
    Q_UNUSED(errorMessage);

    AnalyzerStartParameters sp;
    sp.displayName = runConfiguration->displayName();
    sp.runMode = mode;
    if (LocalApplicationRunConfiguration *rc1 =
            qobject_cast<LocalApplicationRunConfiguration *>(runConfiguration)) {
        EnvironmentAspect *aspect = runConfiguration->extraAspect<EnvironmentAspect>();
        if (aspect)
            sp.environment = aspect->environment();
        sp.workingDirectory = rc1->workingDirectory();
        sp.debuggee = rc1->executable();
        sp.debuggeeArgs = rc1->commandLineArguments();
        const IDevice::ConstPtr device =
                DeviceKitInformation::device(runConfiguration->target()->kit());
        QTC_ASSERT(device, return 0);
        QTC_ASSERT(device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE, return 0);
        QTcpServer server;
        if (!server.listen(QHostAddress::LocalHost) && !server.listen(QHostAddress::LocalHostIPv6)) {
            qWarning() << "Cannot open port on host for profiling.";
            return 0;
        }
        sp.connParams.host = server.serverAddress().toString();
        sp.connParams.port = server.serverPort();
        sp.localRunMode = static_cast<ApplicationLauncher::Mode>(rc1->runMode());
    } else if (RemoteLinux::AbstractRemoteLinuxRunConfiguration *rc2 =
               qobject_cast<RemoteLinux::AbstractRemoteLinuxRunConfiguration *>(runConfiguration)) {
        sp.useStartupProject = false; // FIXME: This is wrong.
        sp.debuggee = rc2->remoteExecutableFilePath();
        sp.connParams = DeviceKitInformation::device(rc2->target()->kit())->sshParameters();
        sp.debuggeeArgs = rc2->arguments().join(QLatin1Char(' '));
    } else {
        QTC_ASSERT(false, return 0);
    }

    return AnalyzerManager::createRunControl(sp, runConfiguration);
}

class ValgrindRunConfigurationAspect : public IRunConfigurationAspect
{
public:
    ValgrindRunConfigurationAspect(RunConfiguration *parent)
        : IRunConfigurationAspect(parent)
    {
        setProjectSettings(new ValgrindProjectSettings());
        setGlobalSettings(ValgrindPlugin::globalSettings());
        setId(ANALYZER_VALGRIND_SETTINGS);
        setDisplayName(QCoreApplication::translate("Valgrind::Internal::ValgrindRunConfigurationAspect", "Valgrind Settings"));
        setUsingGlobalSettings(true);
        resetProjectToGlobalSettings();
    }

    ValgrindRunConfigurationAspect *create(RunConfiguration *parent) const override
    {
        return new ValgrindRunConfigurationAspect(parent);
    }

    RunConfigWidget *createConfigurationWidget() override
    {
        return new AnalyzerRunConfigWidget(this);
    }
};

IRunConfigurationAspect *ValgrindRunControlFactory::createRunConfigurationAspect(RunConfiguration *rc)
{
    return new ValgrindRunConfigurationAspect(rc);
}

} // namespace Internal
} // namespace Valgrind
<commit_msg>Valgrind: Remove one use of AnalyzerStartParameters::useStartupProject<commit_after>/****************************************************************************
**
** Copyright (C) 2015 Kläralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company.  For licensing terms and
** conditions see http://www.qt.io/terms-conditions.  For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "valgrindruncontrolfactory.h"
#include "valgrindsettings.h"
#include "valgrindplugin.h"

#include <analyzerbase/ianalyzertool.h>
#include <analyzerbase/analyzermanager.h>
#include <analyzerbase/analyzerstartparameters.h>
#include <analyzerbase/analyzerruncontrol.h>
#include <analyzerbase/analyzerrunconfigwidget.h>

#include <remotelinux/abstractremotelinuxrunconfiguration.h>

#include <debugger/debuggerrunconfigurationaspect.h>
#include <projectexplorer/environmentaspect.h>
#include <projectexplorer/localapplicationrunconfiguration.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/target.h>

#include <utils/qtcassert.h>

#include <QTcpServer>

using namespace Analyzer;
using namespace ProjectExplorer;

namespace Valgrind {
namespace Internal {

ValgrindRunControlFactory::ValgrindRunControlFactory(QObject *parent) :
    IRunControlFactory(parent)
{
}

bool ValgrindRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const
{
    Q_UNUSED(runConfiguration);
    return mode == CallgrindRunMode || mode == MemcheckRunMode || mode == MemcheckWithGdbRunMode;
}

RunControl *ValgrindRunControlFactory::create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage)
{
    Q_UNUSED(errorMessage);

    AnalyzerStartParameters sp;
    sp.displayName = runConfiguration->displayName();
    sp.runMode = mode;
    if (LocalApplicationRunConfiguration *rc1 =
            qobject_cast<LocalApplicationRunConfiguration *>(runConfiguration)) {
        EnvironmentAspect *aspect = runConfiguration->extraAspect<EnvironmentAspect>();
        if (aspect)
            sp.environment = aspect->environment();
        sp.workingDirectory = rc1->workingDirectory();
        sp.debuggee = rc1->executable();
        sp.debuggeeArgs = rc1->commandLineArguments();
        const IDevice::ConstPtr device =
                DeviceKitInformation::device(runConfiguration->target()->kit());
        QTC_ASSERT(device, return 0);
        QTC_ASSERT(device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE, return 0);
        QTcpServer server;
        if (!server.listen(QHostAddress::LocalHost) && !server.listen(QHostAddress::LocalHostIPv6)) {
            qWarning() << "Cannot open port on host for profiling.";
            return 0;
        }
        sp.connParams.host = server.serverAddress().toString();
        sp.connParams.port = server.serverPort();
        sp.localRunMode = static_cast<ApplicationLauncher::Mode>(rc1->runMode());
    } else if (RemoteLinux::AbstractRemoteLinuxRunConfiguration *rc2 =
               qobject_cast<RemoteLinux::AbstractRemoteLinuxRunConfiguration *>(runConfiguration)) {
        sp.debuggee = rc2->remoteExecutableFilePath();
        sp.connParams = DeviceKitInformation::device(rc2->target()->kit())->sshParameters();
        sp.debuggeeArgs = rc2->arguments().join(QLatin1Char(' '));
    } else {
        QTC_ASSERT(false, return 0);
    }

    return AnalyzerManager::createRunControl(sp, runConfiguration);
}

class ValgrindRunConfigurationAspect : public IRunConfigurationAspect
{
public:
    ValgrindRunConfigurationAspect(RunConfiguration *parent)
        : IRunConfigurationAspect(parent)
    {
        setProjectSettings(new ValgrindProjectSettings());
        setGlobalSettings(ValgrindPlugin::globalSettings());
        setId(ANALYZER_VALGRIND_SETTINGS);
        setDisplayName(QCoreApplication::translate("Valgrind::Internal::ValgrindRunConfigurationAspect", "Valgrind Settings"));
        setUsingGlobalSettings(true);
        resetProjectToGlobalSettings();
    }

    ValgrindRunConfigurationAspect *create(RunConfiguration *parent) const override
    {
        return new ValgrindRunConfigurationAspect(parent);
    }

    RunConfigWidget *createConfigurationWidget() override
    {
        return new AnalyzerRunConfigWidget(this);
    }
};

IRunConfigurationAspect *ValgrindRunControlFactory::createRunConfigurationAspect(RunConfiguration *rc)
{
    return new ValgrindRunConfigurationAspect(rc);
}

} // namespace Internal
} // namespace Valgrind
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "product.h"

void test_product_large()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( product(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_2( product(MatrixXd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_3( product(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_4( product(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );
    CALL_SUBTEST_5( product(Matrix<float,Dynamic,Dynamic,RowMajor>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
  }

#if defined EIGEN_TEST_PART_6
  {
    // test a specific issue in DiagonalProduct
    int N = 1000000;
    VectorXf v = VectorXf::Ones(N);
    MatrixXf m = MatrixXf::Ones(N,3);
    m = (v+v).asDiagonal() * m;
    VERIFY_IS_APPROX(m, MatrixXf::Constant(N,3,2));
  }

  {
    // test deferred resizing in Matrix::operator=
    MatrixXf a = MatrixXf::Random(10,4), b = MatrixXf::Random(4,10), c = a;
    VERIFY_IS_APPROX((a = a * b), (c * b).eval());
  }

  {
    // check the functions to setup blocking sizes compile and do not segfault
    // FIXME check they do what they are supposed to do !!
    std::ptrdiff_t l1 = internal::random<int>(10000,20000);
    std::ptrdiff_t l2 = internal::random<int>(1000000,2000000);
    setCpuCacheSizes(l1,l2);
    VERIFY(l1==l1CacheSize());
    VERIFY(l2==l2CacheSize());
    std::ptrdiff_t k1 = internal::random<int>(10,100)*16;
    std::ptrdiff_t m1 = internal::random<int>(10,100)*16;
    std::ptrdiff_t n1 = internal::random<int>(10,100)*16;
    // only makes sure it compiles fine
    internal::computeProductBlockingSizes<float,float>(k1,m1,n1);
  }

  {
    // test regression in row-vector by matrix (bad Map type)
    MatrixXf mat1(10,32); mat1.setRandom();
    MatrixXf mat2(32,32); mat2.setRandom();
    MatrixXf r1 = mat1.row(2)*mat2.transpose();
    VERIFY_IS_APPROX(r1, (mat1.row(2)*mat2.transpose()).eval());

    MatrixXf r2 = mat1.row(2)*mat2;
    VERIFY_IS_APPROX(r2, (mat1.row(2)*mat2).eval());
  }
#endif
}
<commit_msg>Regression test for bug 714. Note that the bug only occurs on some compilers and is not fixed yet<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "product.h"

void test_product_large()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( product(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_2( product(MatrixXd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_3( product(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_4( product(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );
    CALL_SUBTEST_5( product(Matrix<float,Dynamic,Dynamic,RowMajor>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
  }

#if defined EIGEN_TEST_PART_6
  {
    // test a specific issue in DiagonalProduct
    int N = 1000000;
    VectorXf v = VectorXf::Ones(N);
    MatrixXf m = MatrixXf::Ones(N,3);
    m = (v+v).asDiagonal() * m;
    VERIFY_IS_APPROX(m, MatrixXf::Constant(N,3,2));
  }

  {
    // test deferred resizing in Matrix::operator=
    MatrixXf a = MatrixXf::Random(10,4), b = MatrixXf::Random(4,10), c = a;
    VERIFY_IS_APPROX((a = a * b), (c * b).eval());
  }

  {
    // check the functions to setup blocking sizes compile and do not segfault
    // FIXME check they do what they are supposed to do !!
    std::ptrdiff_t l1 = internal::random<int>(10000,20000);
    std::ptrdiff_t l2 = internal::random<int>(1000000,2000000);
    setCpuCacheSizes(l1,l2);
    VERIFY(l1==l1CacheSize());
    VERIFY(l2==l2CacheSize());
    std::ptrdiff_t k1 = internal::random<int>(10,100)*16;
    std::ptrdiff_t m1 = internal::random<int>(10,100)*16;
    std::ptrdiff_t n1 = internal::random<int>(10,100)*16;
    // only makes sure it compiles fine
    internal::computeProductBlockingSizes<float,float>(k1,m1,n1);
  }

  {
    // test regression in row-vector by matrix (bad Map type)
    MatrixXf mat1(10,32); mat1.setRandom();
    MatrixXf mat2(32,32); mat2.setRandom();
    MatrixXf r1 = mat1.row(2)*mat2.transpose();
    VERIFY_IS_APPROX(r1, (mat1.row(2)*mat2.transpose()).eval());

    MatrixXf r2 = mat1.row(2)*mat2;
    VERIFY_IS_APPROX(r2, (mat1.row(2)*mat2).eval());
  }
#endif

  // Regression test for bug 714:
#ifdef EIGEN_HAS_OPENMP
  std::cout << "Testing omp_set_dynamic(1)\n";
  omp_set_dynamic(1);
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_6( product(Matrix<float,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
  }
#endif
}
<|endoftext|>