<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/file_util.h"
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_unpacker.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"

namespace errors = extension_manifest_errors;
namespace keys = extension_manifest_keys;

class ExtensionUnpackerTest : public testing::Test {
public:
  void SetupUnpacker(const std::string& crx_name) {
    FilePath original_path;
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &original_path));
    original_path = original_path.AppendASCII("extensions")
        .AppendASCII("unpacker")
        .AppendASCII(crx_name);
    ASSERT_TRUE(file_util::PathExists(original_path)) << original_path.value();

    // Try bots won't let us write into DIR_TEST_DATA, so we have to create
    // a temp folder to play in.
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());

    FilePath crx_path = temp_dir_.path().AppendASCII(crx_name);
    ASSERT_TRUE(file_util::CopyFile(original_path, crx_path)) <<
        "Original path " << original_path.value() <<
        ", Crx path " << crx_path.value();

    unpacker_.reset(
        new ExtensionUnpacker(
            crx_path, Extension::INTERNAL, Extension::NO_FLAGS));
  }

 protected:
  ScopedTempDir temp_dir_;
  scoped_ptr<ExtensionUnpacker> unpacker_;
};

// Crashes intermittently on Windows, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_EmptyDefaultLocale DISABLED_EmptyDefaultLocale
#else
#define MAYBE_EmptyDefaultLocale EmptyDefaultLocale
#endif

TEST_F(ExtensionUnpackerTest, MAYBE_EmptyDefaultLocale) {
  SetupUnpacker("empty_default_locale.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kInvalidDefaultLocale),
            unpacker_->error_message());
}

// Crashes intermittently on Vista, see http://crbug.com/109385
#if defined(OS_WIN)
#define MAYBE_HasDefaultLocaleMissingLocalesFolder \
  DISABLED_HasDefaultLocaleMissingLocalesFolder
#else
#define MAYBE_HasDefaultLocaleMissingLocalesFolder \
  HasDefaultLocaleMissingLocalesFolder
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_HasDefaultLocaleMissingLocalesFolder) {
  SetupUnpacker("has_default_missing_locales.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kLocalesTreeMissing),
            unpacker_->error_message());
}

TEST_F(ExtensionUnpackerTest, InvalidDefaultLocale) {
  SetupUnpacker("invalid_default_locale.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kInvalidDefaultLocale),
            unpacker_->error_message());
}

TEST_F(ExtensionUnpackerTest, InvalidMessagesFile) {
  SetupUnpacker("invalid_messages_file.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_TRUE(MatchPattern(unpacker_->error_message(),
    ASCIIToUTF16("*_locales?en_US?messages.json: Line: 2, column: 3,"
                " Dictionary keys must be quoted.")));
}

TEST_F(ExtensionUnpackerTest, MissingDefaultData) {
  SetupUnpacker("missing_default_data.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kLocalesNoDefaultMessages),
            unpacker_->error_message());
}

TEST_F(ExtensionUnpackerTest, MissingDefaultLocaleHasLocalesFolder) {
  SetupUnpacker("missing_default_has_locales.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kLocalesNoDefaultLocaleSpecified),
            unpacker_->error_message());
}

TEST_F(ExtensionUnpackerTest, MissingMessagesFile) {
  SetupUnpacker("missing_messages_file.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_TRUE(MatchPattern(unpacker_->error_message(),
    ASCIIToUTF16(errors::kLocalesMessagesFileMissing) +
    ASCIIToUTF16("*_locales?en_US?messages.json")));
}

TEST_F(ExtensionUnpackerTest, NoLocaleData) {
  SetupUnpacker("no_locale_data.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kLocalesNoDefaultMessages),
            unpacker_->error_message());
}

TEST_F(ExtensionUnpackerTest, GoodL10n) {
  SetupUnpacker("good_l10n.crx");
  EXPECT_TRUE(unpacker_->Run());
  EXPECT_TRUE(unpacker_->error_message().empty());
  ASSERT_EQ(2U, unpacker_->parsed_catalogs()->size());
}

TEST_F(ExtensionUnpackerTest, NoL10n) {
  SetupUnpacker("no_l10n.crx");
  EXPECT_TRUE(unpacker_->Run());
  EXPECT_TRUE(unpacker_->error_message().empty());
  EXPECT_EQ(0U, unpacker_->parsed_catalogs()->size());
}
<commit_msg>Disable intermittently crashing ExtensionUnpackerTest.InvalidDefaultLocale on Win.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/file_util.h"
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_unpacker.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"

namespace errors = extension_manifest_errors;
namespace keys = extension_manifest_keys;

class ExtensionUnpackerTest : public testing::Test {
public:
  void SetupUnpacker(const std::string& crx_name) {
    FilePath original_path;
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &original_path));
    original_path = original_path.AppendASCII("extensions")
        .AppendASCII("unpacker")
        .AppendASCII(crx_name);
    ASSERT_TRUE(file_util::PathExists(original_path)) << original_path.value();

    // Try bots won't let us write into DIR_TEST_DATA, so we have to create
    // a temp folder to play in.
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());

    FilePath crx_path = temp_dir_.path().AppendASCII(crx_name);
    ASSERT_TRUE(file_util::CopyFile(original_path, crx_path)) <<
        "Original path " << original_path.value() <<
        ", Crx path " << crx_path.value();

    unpacker_.reset(
        new ExtensionUnpacker(
            crx_path, Extension::INTERNAL, Extension::NO_FLAGS));
  }

 protected:
  ScopedTempDir temp_dir_;
  scoped_ptr<ExtensionUnpacker> unpacker_;
};

// Crashes intermittently on Windows, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_EmptyDefaultLocale DISABLED_EmptyDefaultLocale
#else
#define MAYBE_EmptyDefaultLocale EmptyDefaultLocale
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_EmptyDefaultLocale) {
  SetupUnpacker("empty_default_locale.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kInvalidDefaultLocale),
            unpacker_->error_message());
}

// Crashes intermittently on Vista, see http://crbug.com/109385
#if defined(OS_WIN)
#define MAYBE_HasDefaultLocaleMissingLocalesFolder \
  DISABLED_HasDefaultLocaleMissingLocalesFolder
#else
#define MAYBE_HasDefaultLocaleMissingLocalesFolder \
  HasDefaultLocaleMissingLocalesFolder
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_HasDefaultLocaleMissingLocalesFolder) {
  SetupUnpacker("has_default_missing_locales.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kLocalesTreeMissing),
            unpacker_->error_message());
}

// Crashes intermittently on Windows, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_InvalidDefaultLocale DISABLED_InvalidDefaultLocale
#else
#define MAYBE_InvalidDefaultLocale InvalidDefaultLocale
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_InvalidDefaultLocale) {
  SetupUnpacker("invalid_default_locale.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kInvalidDefaultLocale),
            unpacker_->error_message());
}

TEST_F(ExtensionUnpackerTest, InvalidMessagesFile) {
  SetupUnpacker("invalid_messages_file.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_TRUE(MatchPattern(unpacker_->error_message(),
    ASCIIToUTF16("*_locales?en_US?messages.json: Line: 2, column: 3,"
                " Dictionary keys must be quoted.")));
}

TEST_F(ExtensionUnpackerTest, MissingDefaultData) {
  SetupUnpacker("missing_default_data.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kLocalesNoDefaultMessages),
            unpacker_->error_message());
}

TEST_F(ExtensionUnpackerTest, MissingDefaultLocaleHasLocalesFolder) {
  SetupUnpacker("missing_default_has_locales.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kLocalesNoDefaultLocaleSpecified),
            unpacker_->error_message());
}

TEST_F(ExtensionUnpackerTest, MissingMessagesFile) {
  SetupUnpacker("missing_messages_file.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_TRUE(MatchPattern(unpacker_->error_message(),
    ASCIIToUTF16(errors::kLocalesMessagesFileMissing) +
    ASCIIToUTF16("*_locales?en_US?messages.json")));
}

TEST_F(ExtensionUnpackerTest, NoLocaleData) {
  SetupUnpacker("no_locale_data.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kLocalesNoDefaultMessages),
            unpacker_->error_message());
}

TEST_F(ExtensionUnpackerTest, GoodL10n) {
  SetupUnpacker("good_l10n.crx");
  EXPECT_TRUE(unpacker_->Run());
  EXPECT_TRUE(unpacker_->error_message().empty());
  ASSERT_EQ(2U, unpacker_->parsed_catalogs()->size());
}

TEST_F(ExtensionUnpackerTest, NoL10n) {
  SetupUnpacker("no_l10n.crx");
  EXPECT_TRUE(unpacker_->Run());
  EXPECT_TRUE(unpacker_->error_message().empty());
  EXPECT_EQ(0U, unpacker_->parsed_catalogs()->size());
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <string.h>

#include <sampgdk/a_players.h>
#include <sampgdk/a_samp.h>
#include <sampgdk/core.h>
#include <sampgdk/sdk.h>

using sampgdk::logprintf;

extern void *pAMXFunctions;

AMX * a;

PLUGIN_EXPORT void PLUGIN_CALL ProcessTick() {
  sampgdk::ProcessTick();
}

PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports()
{
    return sampgdk::Supports() | SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES;
}

PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData)
{
    pAMXFunctions = ppData[PLUGIN_DATA_AMX_EXPORTS];
    return sampgdk::Load(ppData);
}

PLUGIN_EXPORT void PLUGIN_CALL Unload()
{
    sampgdk::Unload();
}

PLUGIN_EXPORT int PLUGIN_CALL AmxLoad(AMX *amx)
{
    a = amx;
    return AMX_ERR_NONE;
}

PLUGIN_EXPORT int PLUGIN_CALL AmxUnload(AMX *amx)
{
    return AMX_ERR_NONE;
}

PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerConnect(int playerid) {
    int one = 10;
    int two = 20;
    int three = 30;
    int amxIndex = 0;

    logprintf("amx_FindPublic...TestCB3");
    if (!amx_FindPublic(a, "TestCB3", &amxIndex))
    {
        logprintf("amx_Push...");
        amx_Push(a, one);
        amx_Push(a, two);
        amx_Push(a, three);

        logprintf("amx_Exec...");
        amx_Exec(a, NULL, amxIndex);
    }
    else
    {
        logprintf("amx_FindPublic failed to find :(...");
    }
    return true;
}

PLUGIN_EXPORT bool PLUGIN_CALL OnPublicCall(AMX *amx, const char *name, cell *params, cell *retval) {
    if (!strcmp(name, "TestCB1")) {
        logprintf(">TestCB1(%d) %d", (params[0] / sizeof(cell)), params[1]);
    }
    if (!strcmp(name, "TestCB2")) {
        logprintf(">TestCB2(%d) %d %d", (params[0] / sizeof(cell)), params[1], params[2]);
    }
    if (!strcmp(name, "TestCB3")) {
        logprintf(">TestCB3(%d) %d %d %d", (params[0] / sizeof(cell)), params[1], params[2], params[3]);
    }
    if (!strcmp(name, "OnPlayerConnect")) {
        logprintf(">OnPlayerConnect(%d) %d", (params[0] / sizeof(cell)), params[1]);
    }
    return true;
}

<commit_msg>Remove test code from helloworld<commit_after>#include <stdio.h>
#include <string.h>

#include <sampgdk/a_players.h>
#include <sampgdk/a_samp.h>
#include <sampgdk/core.h>
#include <sampgdk/sdk.h>

using namespace sampgdk;

void SAMPGDK_CALL PrintTickCountTimer(int timerid, void *params) {
  logprintf("Tick count: %d", GetTickCount());
}

PLUGIN_EXPORT bool PLUGIN_CALL OnGameModeInit() {
  SetGameModeText("Hello, World!");
  AddPlayerClass(0, 1958.3783f, 1343.1572f, 15.3746f, 269.1425f,
                 0, 0, 0, 0, 0, 0);
  SetTimer(1000, true, PrintTickCountTimer, 0);
  return true;
}

PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerConnect(int playerid) {
  SendClientMessage(playerid, 0xFFFFFFFF, "Welcome to the HelloWorld server!");
  return true;
}

PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerRequestClass(int playerid,
                                                    int classid) {
  SetPlayerPos(playerid, 1958.3783f, 1343.1572f, 15.3746f);
  SetPlayerCameraPos(playerid, 1958.3783f, 1343.1572f, 15.3746f);
  SetPlayerCameraLookAt(playerid, 1958.3783f, 1343.1572f, 15.3746f, CAMERA_CUT);
  return true;
}

PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerCommandText(int playerid,
                                                   const char *cmdtext) {
  if (strcmp(cmdtext, "/hello") == 0) {
    char name[MAX_PLAYER_NAME];
    GetPlayerName(playerid, name, sizeof(name));
    char message[MAX_CLIENT_MESSAGE];
    sprintf(message, "Hello, %s!", name);
    SendClientMessage(playerid, 0x00FF00FF, message);
    return true;
  }
  return false;
}

PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports() {
  return sampgdk::Supports() | SUPPORTS_PROCESS_TICK;
}

PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData) {
  return sampgdk::Load(ppData);
}

PLUGIN_EXPORT void PLUGIN_CALL Unload() {
  sampgdk::Unload();
}

PLUGIN_EXPORT void PLUGIN_CALL ProcessTick() {
  sampgdk::ProcessTick();
}
<|endoftext|>


<commit_before>/*
    nlamarok.cpp

    Kopete Now Listening To plugin

    Copyright (c) 2002,2003,2004 by Will Stephenson <will@stevello.free-online.co.uk>
    Kopete
	Copyright (c) 2002,2003,2004 by the Kopete developers  <kopete-devel@kde.org>

	Purpose:
	This class abstracts the interface to amaroK by
	implementing NLMediaPlayer

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include <kdebug.h>

#include <QtDBus/QtDBus>

#include "nlmediaplayer.h"
#include "nlamarok.h"

NLamaroK::NLamaroK() : NLMediaPlayer()
{
	m_type = Audio;
	m_name = "amaroK";
	m_client = new QDBusInterface("org.kde.amaroK", "/player");
}

NLamaroK::~NLamaroK()
{
	delete m_client;
}

void NLamaroK::update()
{
	m_playing = false;
	m_newTrack = false;
	QString newTrack;
	QString result;

	// TODO: Port to amarok 2.0 D-BUS interface
	if( !m_client->isValid() )
		return;

	// See if amaroK is currently playing.
	QDBusReply<int> statusReply = m_client->call("status");
	if( statusReply.isValid() )
	{
		if( statusReply.value() )
		{
			m_playing = true;
		}
	}

	// Fetch title
	QDBusReply<QString> newTrackReply = m_client->call("title");
	if( newTrackReply.isValid() )
	{
		newTrack = newTrackReply.value();
	}

	if ( newTrack != m_track )
	{
		m_newTrack = true;
		m_track = newTrack;
	}

	// Fetch album
	QDBusReply<QString> albumReply = m_client->call("album");
	if( albumReply.isValid() )
	{
		m_album = albumReply.value();
	}

	// Fetch artist
	QDBusReply<QString> artistReply = m_client->call("artist");
	if( artistReply.isValid() )
	{
		m_artist = artistReply.value();
	}
}

<commit_msg>Change capitalization of the dbus interface to the one amarok is currently using. Fixes nowlistening support for Amarok 2.0. CCBUG: 155865<commit_after>/*
    nlamarok.cpp

    Kopete Now Listening To plugin

    Copyright (c) 2002,2003,2004 by Will Stephenson <will@stevello.free-online.co.uk>
    Kopete
	Copyright (c) 2002,2003,2004 by the Kopete developers  <kopete-devel@kde.org>

	Purpose:
	This class abstracts the interface to amaroK by
	implementing NLMediaPlayer

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include <kdebug.h>

#include <QtDBus/QtDBus>

#include "nlmediaplayer.h"
#include "nlamarok.h"

NLamaroK::NLamaroK() : NLMediaPlayer()
{
	m_type = Audio;
	m_name = "amaroK";
	m_client = new QDBusInterface("org.kde.amarok", "/Player");
}

NLamaroK::~NLamaroK()
{
	delete m_client;
}

void NLamaroK::update()
{
	m_playing = false;
	m_newTrack = false;
	QString newTrack;
	QString result;

	if( !m_client->isValid() )
		return;

	// See if amaroK is currently playing.
	QDBusReply<int> statusReply = m_client->call("status");
	if( statusReply.isValid() )
	{
		if( statusReply.value() )
		{
			m_playing = true;
		}
	}

	// Fetch title
	QDBusReply<QString> newTrackReply = m_client->call("title");
	if( newTrackReply.isValid() )
	{
		newTrack = newTrackReply.value();
	}

	if ( newTrack != m_track )
	{
		m_newTrack = true;
		m_track = newTrack;
	}

	// Fetch album
	QDBusReply<QString> albumReply = m_client->call("album");
	if( albumReply.isValid() )
	{
		m_album = albumReply.value();
	}

	// Fetch artist
	QDBusReply<QString> artistReply = m_client->call("artist");
	if( artistReply.isValid() )
	{
		m_artist = artistReply.value();
	}
}

<|endoftext|>


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

#ifndef DUNE_GDT_PRODUCTS_BASE_HH
#define DUNE_GDT_PRODUCTS_BASE_HH

#include <dune/gdt/assembler/system.hh>
#include <dune/gdt/assembler/tmp-storage.hh>
#include <dune/gdt/assembler/local/codim0.hh>

#include "interfaces.hh"

namespace Dune {
namespace GDT {
namespace Products {

template <class Traits>
class LocalizableBase : public LocalizableProductInterface<Traits>,
                        public Functor::Codim0<typename Traits::GridViewType>
{
  typedef LocalizableProductInterface<Traits> InterfaceType;

public:
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::RangeType RangeType;
  typedef typename Traits::SourceType SourceType;
  typedef typename Traits::FieldType FieldType;

private:
  typedef typename Traits::LocalOperatorType LocalOperatorType;
  typedef TmpStorageProvider::Matrices<FieldType> TmpMatricesProviderType;

public:
  using typename InterfaceType::EntityType;

public:
  LocalizableBase(const GridViewType& grd_vw, const RangeType& rng, const SourceType& src)
    : grid_view_(grd_vw)
    , range_(rng)
    , source_(src)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , finalized_(false)
    , result_(0)
  {
  }

  LocalizableBase(const GridViewType& grd_vw, const RangeType& rng)
    : grid_view_(grd_vw)
    , range_(rng)
    , source_(range_)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , finalized_(false)
    , result_(0)
  {
  }

  virtual ~LocalizableBase()
  {
  }

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  const RangeType& range() const
  {
    return range_;
  }

  const SourceType& source() const
  {
    return source_;
  }

private:
  virtual const LocalOperatorType& local_operator() const = 0;

public:
  virtual void prepare() DS_OVERRIDE
  {
    if (!prepared_) {
      tmp_storage_ = std::unique_ptr<TmpMatricesProviderType>(
          new TmpMatricesProviderType({1, local_operator().numTmpObjectsRequired()}, 1, 1));
      result_ *= 0.0;
      prepared_ = true;
    }
  } // ... prepare()

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE
  {
    assert(prepared_);
    assert(tmp_storage_);
    auto& tmp_storage = tmp_storage_->matrices();
    assert(tmp_storage.size() >= 2);
    assert(tmp_storage[0].size() >= 1);
    auto& local_operator_result = tmp_storage[0][0];
    auto& tmp_matrices          = tmp_storage[1];
    // get the local functions
    const auto local_source_ptr = this->source().local_function(entity);
    const auto local_range_ptr  = this->range().local_function(entity);
    // apply local operator
    local_operator().apply(*local_range_ptr, *local_source_ptr, local_operator_result, tmp_matrices);
    assert(local_operator_result.rows() == 1);
    assert(local_operator_result.cols() == 1);
    result_ += local_operator_result[0][0];
  } // ... apply_local(...)

  virtual void finalize() DS_OVERRIDE
  {
    finalized_ = true;
  }

  FieldType apply2()
  {
    if (!finalized_) {
      GridWalker<GridViewType> grid_walker(grid_view_);
      grid_walker.add(*this);
      grid_walker.walk();
    }
    return result_;
  }

private:
  const GridViewType& grid_view_;
  const RangeType& range_;
  const SourceType& source_;
  std::unique_ptr<TmpMatricesProviderType> tmp_storage_;
  bool prepared_;
  bool finalized_;
  FieldType result_;
}; // class LocalizableBase

template <class Traits>
class AssemblableBase : public AssemblableProductInterface<Traits>,
                        public Functor::Codim0<typename Traits::GridViewType>
{
  typedef AssemblableProductInterface<Traits> InterfaceType;

public:
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::RangeSpaceType RangeSpaceType;
  typedef typename Traits::SourceSpaceType SourceSpaceType;
  typedef typename Traits::MatrixType MatrixType;

  typedef typename MatrixType::ScalarType FieldType;

private:
  typedef TmpStorageProvider::Matrices<FieldType> TmpMatricesProviderType;
  typedef typename Traits::LocalOperatorType LocalOperatorType;
  typedef LocalAssembler::Codim0Matrix<LocalOperatorType> LocalAssemblerType;

public:
  using typename InterfaceType::EntityType;

  using InterfaceType::pattern;

  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc, const GridViewType& grd_vw,
                  const SourceSpaceType& src_spc)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(grd_vw)
    , source_space_(src_spc)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {
  }

  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc, const GridViewType& grd_vw)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(grd_vw)
    , source_space_(range_space_)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {
  }

  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(*(range_space_->grid_view()))
    , source_space_(range_space_)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {
  }

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  const RangeSpaceType& range_space() const
  {
    return range_space_;
  }

  const SourceSpaceType& source_space() const
  {
    return source_space_;
  }

  MatrixType& matrix()
  {
    return matrix_;
  }

  const MatrixType& matrix() const
  {
    return matrix_;
  }

private:
  virtual const LocalOperatorType& local_operator() const = 0;

public:
  virtual void prepare() DS_OVERRIDE
  {
    if (!assembled_ && !prepared_) {
      local_assembler_ = std::unique_ptr<LocalAssemblerType>(new LocalAssemblerType(local_operator()));
      tmp_storage_ = std::unique_ptr<TmpMatricesProviderType>(
          new TmpMatricesProviderType(local_assembler_->numTmpObjectsRequired(),
                                      range_space_.mapper().maxNumDofs(),
                                      source_space_.mapper().maxNumDofs()));
      prepared_ = true;
    }
  } // ... prepare()

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE
  {
    assert(prepared_);
    assert(local_assembler_);
    assert(tmp_storage_);
    local_assembler_->assembleLocal(
        range_space_, source_space_, entity, matrix_, tmp_storage_->matrices(), tmp_storage_->indices());
  } // ... apply_local(...)

  void assemble()
  {
    if (!assembled_) {
      GridWalker<GridViewType> grid_walker(grid_view_);
      grid_walker.add(*this);
      grid_walker.walk();
      assembled_ = true;
    }
  } // ... assemble()

  using InterfaceType::apply2;

private:
  MatrixType& matrix_;
  const RangeSpaceType& range_space_;
  const GridViewType& grid_view_;
  const SourceSpaceType& source_space_;
  std::unique_ptr<LocalAssemblerType> local_assembler_;
  std::unique_ptr<TmpMatricesProviderType> tmp_storage_;
  bool prepared_;
  bool assembled_;
}; // class AssemblableBase

} // namespace Products
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_PRODUCTS_BASE_HH
<commit_msg>[products.base] added notes<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_PRODUCTS_BASE_HH
#define DUNE_GDT_PRODUCTS_BASE_HH

#include <dune/gdt/assembler/system.hh>
#include <dune/gdt/assembler/tmp-storage.hh>
#include <dune/gdt/assembler/local/codim0.hh>

#include "interfaces.hh"

namespace Dune {
namespace GDT {
namespace Products {

/**
 *  \todo Derive from SystemAssembler, \see Operators::EllipticG
 */
template <class Traits>
class LocalizableBase : public LocalizableProductInterface<Traits>,
                        public Functor::Codim0<typename Traits::GridViewType>
{
  typedef LocalizableProductInterface<Traits> InterfaceType;

public:
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::RangeType RangeType;
  typedef typename Traits::SourceType SourceType;
  typedef typename Traits::FieldType FieldType;

private:
  typedef typename Traits::LocalOperatorType LocalOperatorType;
  typedef TmpStorageProvider::Matrices<FieldType> TmpMatricesProviderType;

public:
  using typename InterfaceType::EntityType;

public:
  LocalizableBase(const GridViewType& grd_vw, const RangeType& rng, const SourceType& src)
    : grid_view_(grd_vw)
    , range_(rng)
    , source_(src)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , finalized_(false)
    , result_(0)
  {
  }

  LocalizableBase(const GridViewType& grd_vw, const RangeType& rng)
    : grid_view_(grd_vw)
    , range_(rng)
    , source_(range_)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , finalized_(false)
    , result_(0)
  {
  }

  virtual ~LocalizableBase()
  {
  }

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  const RangeType& range() const
  {
    return range_;
  }

  const SourceType& source() const
  {
    return source_;
  }

private:
  virtual const LocalOperatorType& local_operator() const = 0;

public:
  virtual void prepare() DS_OVERRIDE
  {
    if (!prepared_) {
      tmp_storage_ = std::unique_ptr<TmpMatricesProviderType>(
          new TmpMatricesProviderType({1, local_operator().numTmpObjectsRequired()}, 1, 1));
      result_ *= 0.0;
      prepared_ = true;
    }
  } // ... prepare()

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE
  {
    assert(prepared_);
    assert(tmp_storage_);
    auto& tmp_storage = tmp_storage_->matrices();
    assert(tmp_storage.size() >= 2);
    assert(tmp_storage[0].size() >= 1);
    auto& local_operator_result = tmp_storage[0][0];
    auto& tmp_matrices          = tmp_storage[1];
    // get the local functions
    const auto local_source_ptr = this->source().local_function(entity);
    const auto local_range_ptr  = this->range().local_function(entity);
    // apply local operator
    local_operator().apply(*local_range_ptr, *local_source_ptr, local_operator_result, tmp_matrices);
    assert(local_operator_result.rows() == 1);
    assert(local_operator_result.cols() == 1);
    result_ += local_operator_result[0][0];
  } // ... apply_local(...)

  virtual void finalize() DS_OVERRIDE
  {
    finalized_ = true;
  }

  FieldType apply2()
  {
    if (!finalized_) {
      GridWalker<GridViewType> grid_walker(grid_view_);
      grid_walker.add(*this);
      grid_walker.walk();
    }
    return result_;
  }

private:
  const GridViewType& grid_view_;
  const RangeType& range_;
  const SourceType& source_;
  std::unique_ptr<TmpMatricesProviderType> tmp_storage_;
  bool prepared_;
  bool finalized_;
  FieldType result_;
}; // class LocalizableBase

/**
 *  \todo Derive from SystemAssembler, \see Operators::EllipticG
 */
template <class Traits>
class AssemblableBase : public AssemblableProductInterface<Traits>,
                        public Functor::Codim0<typename Traits::GridViewType>
{
  typedef AssemblableProductInterface<Traits> InterfaceType;

public:
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::RangeSpaceType RangeSpaceType;
  typedef typename Traits::SourceSpaceType SourceSpaceType;
  typedef typename Traits::MatrixType MatrixType;

  typedef typename MatrixType::ScalarType FieldType;

private:
  typedef TmpStorageProvider::Matrices<FieldType> TmpMatricesProviderType;
  typedef typename Traits::LocalOperatorType LocalOperatorType;
  typedef LocalAssembler::Codim0Matrix<LocalOperatorType> LocalAssemblerType;

public:
  using typename InterfaceType::EntityType;

  using InterfaceType::pattern;

  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc, const GridViewType& grd_vw,
                  const SourceSpaceType& src_spc)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(grd_vw)
    , source_space_(src_spc)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {
  }

  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc, const GridViewType& grd_vw)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(grd_vw)
    , source_space_(range_space_)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {
  }

  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(*(range_space_->grid_view()))
    , source_space_(range_space_)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {
  }

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  const RangeSpaceType& range_space() const
  {
    return range_space_;
  }

  const SourceSpaceType& source_space() const
  {
    return source_space_;
  }

  MatrixType& matrix()
  {
    return matrix_;
  }

  const MatrixType& matrix() const
  {
    return matrix_;
  }

private:
  virtual const LocalOperatorType& local_operator() const = 0;

public:
  virtual void prepare() DS_OVERRIDE
  {
    if (!assembled_ && !prepared_) {
      local_assembler_ = std::unique_ptr<LocalAssemblerType>(new LocalAssemblerType(local_operator()));
      tmp_storage_ = std::unique_ptr<TmpMatricesProviderType>(
          new TmpMatricesProviderType(local_assembler_->numTmpObjectsRequired(),
                                      range_space_.mapper().maxNumDofs(),
                                      source_space_.mapper().maxNumDofs()));
      prepared_ = true;
    }
  } // ... prepare()

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE
  {
    assert(prepared_);
    assert(local_assembler_);
    assert(tmp_storage_);
    local_assembler_->assembleLocal(
        range_space_, source_space_, entity, matrix_, tmp_storage_->matrices(), tmp_storage_->indices());
  } // ... apply_local(...)

  void assemble()
  {
    if (!assembled_) {
      GridWalker<GridViewType> grid_walker(grid_view_);
      grid_walker.add(*this);
      grid_walker.walk();
      assembled_ = true;
    }
  } // ... assemble()

  using InterfaceType::apply2;

private:
  MatrixType& matrix_;
  const RangeSpaceType& range_space_;
  const GridViewType& grid_view_;
  const SourceSpaceType& source_space_;
  std::unique_ptr<LocalAssemblerType> local_assembler_;
  std::unique_ptr<TmpMatricesProviderType> tmp_storage_;
  bool prepared_;
  bool assembled_;
}; // class AssemblableBase

} // namespace Products
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_PRODUCTS_BASE_HH
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   https://github.com/dune-community/dune-gdt
// Copyright 2010-2018 dune-gdt developers and contributors. All rights reserved.
// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
//          with "runtime exception" (http://www.dune-project.org/license.html)
// Authors:
//   Felix Schindler (2013 - 2017)
//   Rene Milk       (2014, 2016 - 2017)
//   Tobias Leibner  (2014, 2016)

#ifndef DUNE_GDT_PROLONGATIONS_HH
#define DUNE_GDT_PROLONGATIONS_HH

#include <dune/xt/functions/reinterpret.hh>
#include <dune/xt/la/container/vector-interface.hh>

#include <dune/gdt/discretefunction/default.hh>
#include <dune/gdt/discretefunction/reinterpret.hh>
#include <dune/gdt/interpolations.hh>
#include <dune/gdt/spaces/interface.hh>

namespace Dune {
namespace GDT {

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [most general
 *        variant].
 *
 * \note This does not clear target.dofs().vector(). Thus, if prolongation_grid_view only covers a part of the domain of
 *       target.space().grid_view(), other contributions in target remain (which is on purpose).
 */
template <class SV, class SGV, size_t r, size_t rC, class SR, class TV, class TGV, class TR, class PGV>
std::enable_if_t<std::is_same<XT::Grid::extract_entity_t<TGV>, typename PGV::Grid::template Codim<0>::Entity>::value,
                 void>
prolong(const DiscreteFunction<SV, SGV, r, rC, SR>& source,
        DiscreteFunction<TV, TGV, r, rC, TR>& target,
        const GridView<PGV>& prolongation_grid_view)
{
  interpolate(reinterpret(source, prolongation_grid_view), target, prolongation_grid_view);
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [uses
 *        target.space().grid_view() as prolongation_grid_view].
 */
template <class SV, class SGV, size_t r, size_t rC, class SR, class TV, class TGV, class TR>
void prolong(const DiscreteFunction<SV, SGV, r, rC, SR>& source, DiscreteFunction<TV, TGV, r, rC, TR>& target)
{
  prolong(source, target, target.space().grid_view());
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [creates
 *        suitable target_function, TargetVectorType has to be provided].
 *
 * Use as in
\code
auto target_function = prolong<TargetVectorType>(source, target_space, prolongation_grid_view);
\endcode
 */
template <class TargetVectorType, class SV, class SGV, size_t r, size_t rC, class SR, class TGV, class TR, class PGV>
std::enable_if_t<std::is_same<XT::Grid::extract_entity_t<TGV>, typename PGV::Grid::template Codim<0>::Entity>::value,
                 DiscreteFunction<TargetVectorType, TGV, r, rC, TR>>
prolong(const DiscreteFunction<SV, SGV, r, rC, SR>& source,
        const SpaceInterface<TGV, r, rC, TR>& target_space,
        const GridView<PGV>& prolongation_grid_view)
{
  auto target_function = make_discrete_function<TargetVectorType>(target_space);
  prolong(source, target_function, prolongation_grid_view);
  return target_function;
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [creates
 *        suitable target_function, TargetVectorType has to be provided, uses target.space().grid_view() as
 *        prolongation_grid_view].
 *
 * Use as in
\code
auto target_function = prolong<TargetVectorType>(source, target_space);
\endcode
 */
template <class TargetVectorType, class SV, class SGV, size_t r, size_t rC, class SR, class TGV, class TR>
DiscreteFunction<TargetVectorType, TGV, r, rC, TR> prolong(const DiscreteFunction<SV, SGV, r, rC, SR>& source,
                                                           const SpaceInterface<TGV, r, rC, TR>& target_space)
{
  auto target_function = make_discrete_function<TargetVectorType>(target_space);
  prolong(source, target_function);
  return target_function;
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [creates
 *        suitable target_function with same VectorType as source].
 */
template <class V, class SGV, size_t r, size_t rC, class SR, class TGV, class TR, class PGV>
std::enable_if_t<std::is_same<XT::Grid::extract_entity_t<TGV>, typename PGV::Grid::template Codim<0>::Entity>::value,
                 DiscreteFunction<V, TGV, r, rC, TR>>
prolong(const DiscreteFunction<V, SGV, r, rC, SR>& source,
        const SpaceInterface<TGV, r, rC, TR>& target_space,
        const GridView<PGV>& prolongation_grid_view)
{
  auto target_function = make_discrete_function<V>(target_space);
  prolong(source, target_function, prolongation_grid_view);
  return target_function;
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [creates
 *        suitable target_function with same VectorType as source, uses target.space().grid_view() as
 *        prolongation_grid_view].
 */
template <class V, class SGV, size_t r, size_t rC, class SR, class TGV, class TR>
DiscreteFunction<V, TGV, r, rC, TR> prolong(const DiscreteFunction<V, SGV, r, rC, SR>& source,
                                            const SpaceInterface<TGV, r, rC, TR>& target_space)
{
  auto target_function = make_discrete_function<V>(target_space);
  prolong(source, target_function);
  return target_function;
}

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_PROLONGATIONS_HH
<commit_msg>[prolongations] update doc<commit_after>// This file is part of the dune-gdt project:
//   https://github.com/dune-community/dune-gdt
// Copyright 2010-2018 dune-gdt developers and contributors. All rights reserved.
// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
//          with "runtime exception" (http://www.dune-project.org/license.html)
// Authors:
//   Felix Schindler (2013 - 2017)
//   Rene Milk       (2014, 2016 - 2017)
//   Tobias Leibner  (2014, 2016)

#ifndef DUNE_GDT_PROLONGATIONS_HH
#define DUNE_GDT_PROLONGATIONS_HH

#include <dune/xt/functions/reinterpret.hh>
#include <dune/xt/la/container/vector-interface.hh>

#include <dune/gdt/discretefunction/default.hh>
#include <dune/gdt/discretefunction/reinterpret.hh>
#include <dune/gdt/interpolations.hh>
#include <dune/gdt/spaces/interface.hh>

namespace Dune {
namespace GDT {

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [most general
 *        variant].
 *
 * \note This does not clear target.dofs().vector(). Thus, if prolongation_grid_view only covers a part of the domain of
 *       target.space().grid_view(), other contributions in target remain (which is on purpose).
 *
 * \sa interpolate
 * \sa reinterpret
 */
template <class SV, class SGV, size_t r, size_t rC, class SR, class TV, class TGV, class TR, class PGV>
std::enable_if_t<std::is_same<XT::Grid::extract_entity_t<TGV>, typename PGV::Grid::template Codim<0>::Entity>::value,
                 void>
prolong(const DiscreteFunction<SV, SGV, r, rC, SR>& source,
        DiscreteFunction<TV, TGV, r, rC, TR>& target,
        const GridView<PGV>& prolongation_grid_view)
{
  interpolate(reinterpret(source, prolongation_grid_view), target, prolongation_grid_view);
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [uses
 *        target.space().grid_view() as prolongation_grid_view].
 */
template <class SV, class SGV, size_t r, size_t rC, class SR, class TV, class TGV, class TR>
void prolong(const DiscreteFunction<SV, SGV, r, rC, SR>& source, DiscreteFunction<TV, TGV, r, rC, TR>& target)
{
  prolong(source, target, target.space().grid_view());
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [creates
 *        suitable target_function, TargetVectorType has to be provided].
 *
 * Use as in
\code
auto target_function = prolong<TargetVectorType>(source, target_space, prolongation_grid_view);
\endcode
 */
template <class TargetVectorType, class SV, class SGV, size_t r, size_t rC, class SR, class TGV, class TR, class PGV>
std::enable_if_t<std::is_same<XT::Grid::extract_entity_t<TGV>, typename PGV::Grid::template Codim<0>::Entity>::value,
                 DiscreteFunction<TargetVectorType, TGV, r, rC, TR>>
prolong(const DiscreteFunction<SV, SGV, r, rC, SR>& source,
        const SpaceInterface<TGV, r, rC, TR>& target_space,
        const GridView<PGV>& prolongation_grid_view)
{
  auto target_function = make_discrete_function<TargetVectorType>(target_space);
  prolong(source, target_function, prolongation_grid_view);
  return target_function;
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [creates
 *        suitable target_function, TargetVectorType has to be provided, uses target.space().grid_view() as
 *        prolongation_grid_view].
 *
 * Use as in
\code
auto target_function = prolong<TargetVectorType>(source, target_space);
\endcode
 */
template <class TargetVectorType, class SV, class SGV, size_t r, size_t rC, class SR, class TGV, class TR>
DiscreteFunction<TargetVectorType, TGV, r, rC, TR> prolong(const DiscreteFunction<SV, SGV, r, rC, SR>& source,
                                                           const SpaceInterface<TGV, r, rC, TR>& target_space)
{
  auto target_function = make_discrete_function<TargetVectorType>(target_space);
  prolong(source, target_function);
  return target_function;
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [creates
 *        suitable target_function with same VectorType as source].
 */
template <class V, class SGV, size_t r, size_t rC, class SR, class TGV, class TR, class PGV>
std::enable_if_t<std::is_same<XT::Grid::extract_entity_t<TGV>, typename PGV::Grid::template Codim<0>::Entity>::value,
                 DiscreteFunction<V, TGV, r, rC, TR>>
prolong(const DiscreteFunction<V, SGV, r, rC, SR>& source,
        const SpaceInterface<TGV, r, rC, TR>& target_space,
        const GridView<PGV>& prolongation_grid_view)
{
  auto target_function = make_discrete_function<V>(target_space);
  prolong(source, target_function, prolongation_grid_view);
  return target_function;
}

/**
 * \brief Prolongs a DiscreteFunction from one (usually coarser) GridView onto another (usually finer) one [creates
 *        suitable target_function with same VectorType as source, uses target.space().grid_view() as
 *        prolongation_grid_view].
 */
template <class V, class SGV, size_t r, size_t rC, class SR, class TGV, class TR>
DiscreteFunction<V, TGV, r, rC, TR> prolong(const DiscreteFunction<V, SGV, r, rC, SR>& source,
                                            const SpaceInterface<TGV, r, rC, TR>& target_space)
{
  auto target_function = make_discrete_function<V>(target_space);
  prolong(source, target_function);
  return target_function;
}

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_PROLONGATIONS_HH
<|endoftext|>


<commit_before>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_GRID_ENTITY_HH
#define DUNE_STUFF_GRID_ENTITY_HH

#include <dune/geometry/referenceelements.hh>

#if HAVE_DUNE_GRID
# include <dune/grid/common/entity.hh>
# include <dune/grid/common/gridview.hh>
#endif

#include <dune/stuff/common/string.hh>
#include <dune/stuff/common/print.hh>
#include <dune/stuff/common/ranges.hh>
#include <dune/stuff/aliases.hh>

namespace Dune {
namespace Stuff {
namespace Grid {

#if HAVE_DUNE_GRID

template< class GridPartOrViewType >
class Entity
{
  template< class GridViewType, bool is_view >
  struct Choose
  {
    typedef typename GridViewType::template Codim< 0 >::Entity Type;
  };

  template< class GridPartType >
  struct Choose< GridPartType, false >
  {
    typedef typename GridPartType::template Codim< 0 >::EntityType Type;
  };

  static const bool this_is_a_grid_view =
      std::is_base_of< GridView< typename GridPartOrViewType::Traits >, GridPartOrViewType >::value;

public:
  typedef typename Choose< GridPartOrViewType, this_is_a_grid_view >::Type Type;
}; // class Entity

#endif // HAVE_DUNE_GRID

template< class EntityType >
void printEntity(const EntityType& entity,
                 const std::string name = Common::Typename< EntityType >::value(),
                 std::ostream& out = std::cout, const std::string prefix = "")
{
  if (!name.empty())
    out << prefix << name << ":\n";
  const auto& geometry = entity.geometry();
  for (auto ii : DSC::valueRange(geometry.corners()))
    Common::print(geometry.corner(ii), "corner " + Common::toString(ii), out, prefix + "  ");
} // ... printEntity(...)

#if HAVE_DUNE_GRID

template< int codim, int worlddim, class GridImp, template< int, int, class > class EntityImp >
double entity_diameter(const Dune::Entity< codim, worlddim, GridImp, EntityImp >& entity) {
  auto max_dist = std::numeric_limits<typename GridImp::ctype>::min();
  const auto& geometry = entity.geometry();
  for (auto i : DSC::valueRange(geometry.corners()))
  {
    const auto xi = geometry.corner(i);
    for (auto j : DSC::valueRange(i + 1, geometry.corners()))
    {
      auto xj = geometry.corner(j);
      xj -= xi;
      max_dist = std::max(max_dist, xj.two_norm());
    }
  }
  return max_dist;
} // entity_diameter

template< size_t codim, size_t worlddim, class GridImp, template< int, int, class > class EntityImp >
double DUNE_DEPRECATED_MSG("use entity_diameter instead, but: changed meaning from min conerdistance to max corner distance")
entityDiameter(const Dune::Entity< codim, worlddim, GridImp, EntityImp >& entity) {
  return entity_diameter(entity);
} //entityDiameter

#if DUNE_VERSION_NEWER(DUNE_GEOMETRY, 2, 3)
# define REFERENCE_ELEMENTS ReferenceElements
#else
# define REFERENCE_ELEMENTS GenericReferenceElements
#endif

template< int codim, int worlddim, class GridImp, template< int, int, class > class EntityImp >
auto reference_element(const Dune::Entity< codim, worlddim, GridImp, EntityImp >& entity)
-> decltype(REFERENCE_ELEMENTS< typename GridImp::ctype, worlddim >::general(entity.geometry().type()))
{
  return REFERENCE_ELEMENTS< typename GridImp::ctype, worlddim >::general(entity.geometry().type());
}

template <int mydim, int cdim, class GridImp, template< int, int, class > class GeometryImp>
auto reference_element(const Dune::Geometry< mydim, cdim, GridImp, GeometryImp>& geometry)
-> decltype(REFERENCE_ELEMENTS< typename GridImp::ctype, mydim >::general(geometry.type()))
{
  return REFERENCE_ELEMENTS< typename GridImp::ctype, mydim >::general(geometry.type());
}

#undef REFERENCE_ELEMENTS

#endif // HAVE_DUNE_GRID

} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_GRID_ENTITY_HH
<commit_msg>[grid.entity] whitespace<commit_after>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_GRID_ENTITY_HH
#define DUNE_STUFF_GRID_ENTITY_HH

#include <dune/geometry/referenceelements.hh>

#if HAVE_DUNE_GRID
# include <dune/grid/common/entity.hh>
# include <dune/grid/common/gridview.hh>
#endif

#include <dune/stuff/common/string.hh>
#include <dune/stuff/common/print.hh>
#include <dune/stuff/common/ranges.hh>
#include <dune/stuff/aliases.hh>

namespace Dune {
namespace Stuff {
namespace Grid {

#if HAVE_DUNE_GRID

template< class GridPartOrViewType >
class Entity
{
  template< class GridViewType, bool is_view >
  struct Choose
  {
    typedef typename GridViewType::template Codim< 0 >::Entity Type;
  };

  template< class GridPartType >
  struct Choose< GridPartType, false >
  {
    typedef typename GridPartType::template Codim< 0 >::EntityType Type;
  };

  static const bool this_is_a_grid_view =
      std::is_base_of< GridView< typename GridPartOrViewType::Traits >, GridPartOrViewType >::value;

public:
  typedef typename Choose< GridPartOrViewType, this_is_a_grid_view >::Type Type;
}; // class Entity

#endif // HAVE_DUNE_GRID

template< class EntityType >
void printEntity(const EntityType& entity,
                 const std::string name = Common::Typename< EntityType >::value(),
                 std::ostream& out = std::cout,
                 const std::string prefix = "")
{
  if (!name.empty())
    out << prefix << name << ":\n";
  const auto& geometry = entity.geometry();
  for (auto ii : DSC::valueRange(geometry.corners()))
    Common::print(geometry.corner(ii), "corner " + Common::toString(ii), out, prefix + "  ");
} // ... printEntity(...)

#if HAVE_DUNE_GRID

template< int codim, int worlddim, class GridImp, template< int, int, class > class EntityImp >
double entity_diameter(const Dune::Entity< codim, worlddim, GridImp, EntityImp >& entity) {
  auto max_dist = std::numeric_limits<typename GridImp::ctype>::min();
  const auto& geometry = entity.geometry();
  for (auto i : DSC::valueRange(geometry.corners()))
  {
    const auto xi = geometry.corner(i);
    for (auto j : DSC::valueRange(i + 1, geometry.corners()))
    {
      auto xj = geometry.corner(j);
      xj -= xi;
      max_dist = std::max(max_dist, xj.two_norm());
    }
  }
  return max_dist;
} // entity_diameter

template< size_t codim, size_t worlddim, class GridImp, template< int, int, class > class EntityImp >
double DUNE_DEPRECATED_MSG("use entity_diameter instead, but: changed meaning from min conerdistance to max corner distance")
entityDiameter(const Dune::Entity< codim, worlddim, GridImp, EntityImp >& entity) {
  return entity_diameter(entity);
} //entityDiameter

#if DUNE_VERSION_NEWER(DUNE_GEOMETRY, 2, 3)
# define REFERENCE_ELEMENTS ReferenceElements
#else
# define REFERENCE_ELEMENTS GenericReferenceElements
#endif

template< int codim, int worlddim, class GridImp, template< int, int, class > class EntityImp >
auto reference_element(const Dune::Entity< codim, worlddim, GridImp, EntityImp >& entity)
-> decltype(REFERENCE_ELEMENTS< typename GridImp::ctype, worlddim >::general(entity.geometry().type()))
{
  return REFERENCE_ELEMENTS< typename GridImp::ctype, worlddim >::general(entity.geometry().type());
}

template <int mydim, int cdim, class GridImp, template< int, int, class > class GeometryImp>
auto reference_element(const Dune::Geometry< mydim, cdim, GridImp, GeometryImp>& geometry)
-> decltype(REFERENCE_ELEMENTS< typename GridImp::ctype, mydim >::general(geometry.type()))
{
  return REFERENCE_ELEMENTS< typename GridImp::ctype, mydim >::general(geometry.type());
}

#undef REFERENCE_ELEMENTS

#endif // HAVE_DUNE_GRID

} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_GRID_ENTITY_HH
<|endoftext|>


<commit_before>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright (C) 2011 - 2016                                                  *
 * Dominik Charousset <dominik.charousset (at) haw-hamburg.de>                *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#ifndef CAF_DETAIL_LOGGING_HPP
#define CAF_DETAIL_LOGGING_HPP

#include <thread>
#include <cstring>
#include <sstream>
#include <iostream>
#include <typeinfo>
#include <type_traits>
#include <unordered_map>

#include "caf/fwd.hpp"
#include "caf/config.hpp"
#include "caf/unifyn.hpp"
#include "caf/abstract_actor.hpp"
#include "caf/deep_to_string.hpp"

#include "caf/type_nr.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/shared_spinlock.hpp"
#include "caf/detail/single_reader_queue.hpp"

/*
 * To enable logging, you have to define CAF_DEBUG. This enables
 * CAF_LOG_ERROR messages. To enable more debugging output, you can
 * define CAF_LOG_LEVEL to:
 * 1: + warning
 * 2: + info
 * 3: + debug
 * 4: + trace (prints for each logged method entry and exit message)
 *
 * Note: this logger emits log4j style output; logs are best viewed
 *       using a log4j viewer, e.g., http://code.google.com/p/otroslogviewer/
 *
 */
namespace caf {

/// Centrally logs events from all actors in an actor system. To enable
/// logging in your application, you need to define `CAF_LOG_LEVEL`. Per
/// default, the logger generates log4j compatible output.
class logger {
public:
  friend class actor_system;

  struct event {
    event* next;
    event* prev;
    int level;
    std::string prefix;
    std::string msg;
    explicit event(int l = 0, std::string p = "", std::string m = "");
  };

  template <class T>
  struct arg_wrapper {
    const char* name;
    const T& value;
    arg_wrapper(const char* x, const T& y) : name(x), value(y) {
      // nop
    }
  };

  template <class T>
  static arg_wrapper<T> make_arg_wrapper(const char* name, const T& value) {
    return {name, value};
  }

  static std::string render_type_name(const std::type_info& ti);

  class line_builder {
  public:
    line_builder();

    template <class T>
    line_builder& operator<<(const T& x) {
      if (!str_.empty())
        str_ += " ";
      std::stringstream ss;
      ss << x;
      str_ += ss.str();
      behind_arg_ = false;
      return *this;
    }

    template <class T>
    line_builder& operator<<(const arg_wrapper<T>& x) {
      if (behind_arg_)
        str_ += ", ";
      else if (!str_.empty())
        str_ += " ";
      str_ += x.name;
      str_ += " = ";
      str_ += deep_to_string(x.value);
      behind_arg_ = true;
      return *this;
    }

    line_builder& operator<<(const std::string& str);

    line_builder& operator<<(const char* str);

    std::string get() const;

  private:
    std::string str_;
    bool behind_arg_;
  };

  static std::string extract_class_name(const char* prettyfun, size_t strsize);

  template <size_t N>
  static std::string extract_class_name(const char (&prettyfun)[N]) {
    return extract_class_name(prettyfun, N);
  }

  /// Returns the ID of the actor currently associated to the calling thread.
  actor_id thread_local_aid();

  /// Associates an actor ID to the calling thread and returns the last value.
  actor_id thread_local_aid(actor_id aid);

  /// Writes an entry to the log file.
  void log(int level, const char* component, const std::string& class_name,
           const char* function_name, const char* file_name,
           int line_num, const std::string& msg);

  ~logger();

  /** @cond PRIVATE */

  static void set_current_actor_system(actor_system*);

  static logger* current_logger();

  static void log_static(int level, const char* component,
                         const std::string& class_name,
                         const char* function_name,
                         const char* file_name, int line_num,
                         const std::string& msg);

  /** @endcond */

private:
  logger(actor_system& sys);

  void run();

  void start();

  void stop();

  actor_system& system_;
  int level_;
  detail::shared_spinlock aids_lock_;
  std::unordered_map<std::thread::id, actor_id> aids_;
  std::thread thread_;
  std::mutex queue_mtx_;
  std::condition_variable queue_cv_;
  detail::single_reader_queue<event> queue_;
};

} // namespace caf

#define CAF_VOID_STMT static_cast<void>(0)

#define CAF_CAT(a, b) a##b

#define CAF_LOG_LEVEL_ERROR 0
#define CAF_LOG_LEVEL_WARNING 1
#define CAF_LOG_LEVEL_INFO 2
#define CAF_LOG_LEVEL_DEBUG 3
#define CAF_LOG_LEVEL_TRACE 4

#define CAF_PRINT_ERROR_IMPL(nclass, nfun, message)                            \
  do {                                                                         \
    caf::logger::line_builder lb;                                              \
    lb << message;                                                             \
    if (nclass.empty())                                                        \
      printf("[ERROR] in %s:%d %s::%s: %s\n", __FILE__, __LINE__,              \
             nclass.c_str(), nfun, lb.get().c_str());                          \
    else                                                                       \
      printf("[ERROR] in %s:%d %s: %s\n", __FILE__, __LINE__,                  \
             nfun, lb.get().c_str());                      \
  } while (false)

#define CAF_ARG(argument) caf::logger::make_arg_wrapper(#argument, argument)

#ifdef CAF_MSVC
#define CAF_GET_CLASS_NAME caf::logger::extract_class_name(__FUNCSIG__)
#else // CAF_MSVC
#define CAF_GET_CLASS_NAME caf::logger::extract_class_name(__PRETTY_FUNCTION__)
#endif // CAF_MSVC

#ifndef CAF_LOG_LEVEL

#define CAF_LOG_IMPL(unused1, unused2)

// placeholder macros when compiling without logging
inline caf::actor_id caf_set_aid_dummy() { return 0; }

#define CAF_PUSH_AID(unused) CAF_VOID_STMT

#define CAF_PUSH_AID_FROM_PTR(unused) CAF_VOID_STMT

#define CAF_SET_AID(unused) caf_set_aid_dummy()

#define CAF_SET_LOGGER_SYS(unused) CAF_VOID_STMT

#define CAF_LOG_TRACE(unused)

#else // CAF_LOG_LEVEL

#ifndef CAF_LOG_COMPONENT
#define CAF_LOG_COMPONENT "caf"
#endif

#define CAF_LOG_IMPL(loglvl, message)                                          \
  caf::logger::log_static(loglvl, CAF_LOG_COMPONENT, CAF_GET_CLASS_NAME,       \
                          __func__, __FILE__, __LINE__,                        \
                          (caf::logger::line_builder{} << message).get())

#define CAF_PUSH_AID(aarg)                                                     \
  auto CAF_UNIFYN(caf_tmp_ptr) = caf::logger::current_logger();                \
  caf::actor_id CAF_UNIFYN(caf_aid_tmp) = 0;                                   \
  if (CAF_UNIFYN(caf_tmp_ptr))                                                 \
    CAF_UNIFYN(caf_aid_tmp) = CAF_UNIFYN(caf_tmp_ptr)->thread_local_aid(aarg); \
  auto CAF_UNIFYN(aid_aid_tmp_guard) = caf::detail::make_scope_guard([=] {     \
    auto CAF_UNIFYN(caf_tmp2_ptr) = caf::logger::current_logger();             \
    if (CAF_UNIFYN(caf_tmp2_ptr))                                              \
      CAF_UNIFYN(caf_tmp2_ptr)->thread_local_aid(CAF_UNIFYN(caf_aid_tmp));     \
  })

#define CAF_PUSH_AID_FROM_PTR(some_ptr)                                        \
  auto CAF_UNIFYN(caf_aid_ptr) = some_ptr;                                     \
  CAF_PUSH_AID(CAF_UNIFYN(caf_aid_ptr) ? CAF_UNIFYN(caf_aid_ptr)->id() : 0)

#define CAF_SET_AID(aid_arg)                                                   \
  (caf::logger::current_logger()                                               \
     ? caf::logger::current_logger()->thread_local_aid(aid_arg)                \
     : 0)

#define CAF_SET_LOGGER_SYS(ptr) caf::logger::set_current_actor_system(ptr)

#if CAF_LOG_LEVEL < CAF_LOG_LEVEL_TRACE

#define CAF_LOG_TRACE(unused) CAF_VOID_STMT

#else // CAF_LOG_LEVEL < CAF_LOG_LEVEL_TRACE

#define CAF_LOG_TRACE(entry_message)                                           \
  const char* CAF_UNIFYN(func_name_) = __func__;                               \
  CAF_LOG_IMPL(CAF_LOG_LEVEL_TRACE, "ENTRY" << entry_message);                 \
  auto CAF_UNIFYN(caf_log_trace_guard_) = ::caf::detail::make_scope_guard([=] {\
    caf::logger::log_static(CAF_LOG_LEVEL_TRACE, CAF_LOG_COMPONENT,            \
                            CAF_GET_CLASS_NAME, CAF_UNIFYN(func_name_),        \
                            __FILE__, __LINE__, "EXIT");                       \
  })

#endif // CAF_LOG_LEVEL < CAF_LOG_LEVEL_TRACE

#if CAF_LOG_LEVEL >= CAF_LOG_LEVEL_DEBUG
#  define CAF_LOG_DEBUG(output) CAF_LOG_IMPL(CAF_LOG_LEVEL_DEBUG, output)
#endif

#if CAF_LOG_LEVEL >= CAF_LOG_LEVEL_INFO
#  define CAF_LOG_INFO(output) CAF_LOG_IMPL(CAF_LOG_LEVEL_INFO, output)
#endif

#if CAF_LOG_LEVEL >= CAF_LOG_LEVEL_WARNING
#  define CAF_LOG_WARNING(output) CAF_LOG_IMPL(CAF_LOG_LEVEL_WARNING, output)
#endif

#endif // CAF_LOG_LEVEL

#ifndef CAF_LOG_INFO
#  define CAF_LOG_INFO(output) CAF_VOID_STMT
#endif

#ifndef CAF_LOG_DEBUG
#  define CAF_LOG_DEBUG(output) CAF_VOID_STMT
#endif

#ifndef CAF_LOG_WARNING
#  define CAF_LOG_WARNING(output) CAF_VOID_STMT
#endif

#define CAF_LOG_ERROR(output)                                                  \
  do {                                                                         \
    CAF_PRINT_ERROR_IMPL(CAF_GET_CLASS_NAME, __func__, output);                \
    CAF_LOG_IMPL(CAF_LOG_LEVEL_ERROR, output);                                 \
  } while (false)

#ifdef CAF_LOG_LEVEL

#define CAF_LOG_DEBUG_IF(cond, output)                                         \
  if (cond) { CAF_LOG_IMPL(CAF_LOG_LEVEL_DEBUG, output); } CAF_VOID_STMT

#define CAF_LOG_INFO_IF(cond, output)                                          \
  if (cond) { CAF_LOG_IMPL(CAF_LOG_LEVEL_INFO, output); } CAF_VOID_STMT

#define CAF_LOG_WARNING_IF(cond, output)                                       \
  if (cond) { CAF_LOG_IMPL(CAF_LOG_LEVEL_WARNING, output); } CAF_VOID_STMT

#define CAF_LOG_ERROR_IF(cond, output)                                         \
  if (cond) { CAF_LOG_IMPL(CAF_LOG_LEVEL_ERROR, output); } CAF_VOID_STMT

#else // CAF_LOG_LEVEL

#define CAF_LOG_DEBUG_IF(unused1, unused2)
#define CAF_LOG_INFO_IF(unused1, unused2)
#define CAF_LOG_WARNING_IF(unused1, unused2)
#define CAF_LOG_ERROR_IF(unused1, unused2)

#endif // CAF_LOG_LEVEL

#endif // CAF_DETAIL_LOGGING_HPP
<commit_msg>Demote errors to normal log events<commit_after>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright (C) 2011 - 2016                                                  *
 * Dominik Charousset <dominik.charousset (at) haw-hamburg.de>                *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#ifndef CAF_DETAIL_LOGGING_HPP
#define CAF_DETAIL_LOGGING_HPP

#include <thread>
#include <cstring>
#include <sstream>
#include <iostream>
#include <typeinfo>
#include <type_traits>
#include <unordered_map>

#include "caf/fwd.hpp"
#include "caf/config.hpp"
#include "caf/unifyn.hpp"
#include "caf/abstract_actor.hpp"
#include "caf/deep_to_string.hpp"

#include "caf/type_nr.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/shared_spinlock.hpp"
#include "caf/detail/single_reader_queue.hpp"

/*
 * To enable logging, you have to define CAF_DEBUG. This enables
 * CAF_LOG_ERROR messages. To enable more debugging output, you can
 * define CAF_LOG_LEVEL to:
 * 1: + warning
 * 2: + info
 * 3: + debug
 * 4: + trace (prints for each logged method entry and exit message)
 *
 * Note: this logger emits log4j style output; logs are best viewed
 *       using a log4j viewer, e.g., http://code.google.com/p/otroslogviewer/
 *
 */
namespace caf {

/// Centrally logs events from all actors in an actor system. To enable
/// logging in your application, you need to define `CAF_LOG_LEVEL`. Per
/// default, the logger generates log4j compatible output.
class logger {
public:
  friend class actor_system;

  struct event {
    event* next;
    event* prev;
    int level;
    std::string prefix;
    std::string msg;
    explicit event(int l = 0, std::string p = "", std::string m = "");
  };

  template <class T>
  struct arg_wrapper {
    const char* name;
    const T& value;
    arg_wrapper(const char* x, const T& y) : name(x), value(y) {
      // nop
    }
  };

  template <class T>
  static arg_wrapper<T> make_arg_wrapper(const char* name, const T& value) {
    return {name, value};
  }

  static std::string render_type_name(const std::type_info& ti);

  class line_builder {
  public:
    line_builder();

    template <class T>
    line_builder& operator<<(const T& x) {
      if (!str_.empty())
        str_ += " ";
      std::stringstream ss;
      ss << x;
      str_ += ss.str();
      behind_arg_ = false;
      return *this;
    }

    template <class T>
    line_builder& operator<<(const arg_wrapper<T>& x) {
      if (behind_arg_)
        str_ += ", ";
      else if (!str_.empty())
        str_ += " ";
      str_ += x.name;
      str_ += " = ";
      str_ += deep_to_string(x.value);
      behind_arg_ = true;
      return *this;
    }

    line_builder& operator<<(const std::string& str);

    line_builder& operator<<(const char* str);

    std::string get() const;

  private:
    std::string str_;
    bool behind_arg_;
  };

  static std::string extract_class_name(const char* prettyfun, size_t strsize);

  template <size_t N>
  static std::string extract_class_name(const char (&prettyfun)[N]) {
    return extract_class_name(prettyfun, N);
  }

  /// Returns the ID of the actor currently associated to the calling thread.
  actor_id thread_local_aid();

  /// Associates an actor ID to the calling thread and returns the last value.
  actor_id thread_local_aid(actor_id aid);

  /// Writes an entry to the log file.
  void log(int level, const char* component, const std::string& class_name,
           const char* function_name, const char* file_name,
           int line_num, const std::string& msg);

  ~logger();

  /** @cond PRIVATE */

  static void set_current_actor_system(actor_system*);

  static logger* current_logger();

  static void log_static(int level, const char* component,
                         const std::string& class_name,
                         const char* function_name,
                         const char* file_name, int line_num,
                         const std::string& msg);

  /** @endcond */

private:
  logger(actor_system& sys);

  void run();

  void start();

  void stop();

  actor_system& system_;
  int level_;
  detail::shared_spinlock aids_lock_;
  std::unordered_map<std::thread::id, actor_id> aids_;
  std::thread thread_;
  std::mutex queue_mtx_;
  std::condition_variable queue_cv_;
  detail::single_reader_queue<event> queue_;
};

} // namespace caf

#define CAF_VOID_STMT static_cast<void>(0)

#define CAF_CAT(a, b) a##b

#define CAF_LOG_LEVEL_ERROR 0
#define CAF_LOG_LEVEL_WARNING 1
#define CAF_LOG_LEVEL_INFO 2
#define CAF_LOG_LEVEL_DEBUG 3
#define CAF_LOG_LEVEL_TRACE 4

#define CAF_ARG(argument) caf::logger::make_arg_wrapper(#argument, argument)

#ifdef CAF_MSVC
#define CAF_GET_CLASS_NAME caf::logger::extract_class_name(__FUNCSIG__)
#else // CAF_MSVC
#define CAF_GET_CLASS_NAME caf::logger::extract_class_name(__PRETTY_FUNCTION__)
#endif // CAF_MSVC

#ifndef CAF_LOG_LEVEL

#define CAF_LOG_IMPL(unused1, unused2)

// placeholder macros when compiling without logging
inline caf::actor_id caf_set_aid_dummy() { return 0; }

#define CAF_PUSH_AID(unused) CAF_VOID_STMT

#define CAF_PUSH_AID_FROM_PTR(unused) CAF_VOID_STMT

#define CAF_SET_AID(unused) caf_set_aid_dummy()

#define CAF_SET_LOGGER_SYS(unused) CAF_VOID_STMT

#define CAF_LOG_TRACE(unused)

#else // CAF_LOG_LEVEL

#ifndef CAF_LOG_COMPONENT
#define CAF_LOG_COMPONENT "caf"
#endif

#define CAF_LOG_IMPL(loglvl, message)                                          \
  caf::logger::log_static(loglvl, CAF_LOG_COMPONENT, CAF_GET_CLASS_NAME,       \
                          __func__, __FILE__, __LINE__,                        \
                          (caf::logger::line_builder{} << message).get())

#define CAF_PUSH_AID(aarg)                                                     \
  auto CAF_UNIFYN(caf_tmp_ptr) = caf::logger::current_logger();                \
  caf::actor_id CAF_UNIFYN(caf_aid_tmp) = 0;                                   \
  if (CAF_UNIFYN(caf_tmp_ptr))                                                 \
    CAF_UNIFYN(caf_aid_tmp) = CAF_UNIFYN(caf_tmp_ptr)->thread_local_aid(aarg); \
  auto CAF_UNIFYN(aid_aid_tmp_guard) = caf::detail::make_scope_guard([=] {     \
    auto CAF_UNIFYN(caf_tmp2_ptr) = caf::logger::current_logger();             \
    if (CAF_UNIFYN(caf_tmp2_ptr))                                              \
      CAF_UNIFYN(caf_tmp2_ptr)->thread_local_aid(CAF_UNIFYN(caf_aid_tmp));     \
  })

#define CAF_PUSH_AID_FROM_PTR(some_ptr)                                        \
  auto CAF_UNIFYN(caf_aid_ptr) = some_ptr;                                     \
  CAF_PUSH_AID(CAF_UNIFYN(caf_aid_ptr) ? CAF_UNIFYN(caf_aid_ptr)->id() : 0)

#define CAF_SET_AID(aid_arg)                                                   \
  (caf::logger::current_logger()                                               \
     ? caf::logger::current_logger()->thread_local_aid(aid_arg)                \
     : 0)

#define CAF_SET_LOGGER_SYS(ptr) caf::logger::set_current_actor_system(ptr)

#if CAF_LOG_LEVEL < CAF_LOG_LEVEL_TRACE

#define CAF_LOG_TRACE(unused) CAF_VOID_STMT

#else // CAF_LOG_LEVEL < CAF_LOG_LEVEL_TRACE

#define CAF_LOG_TRACE(entry_message)                                           \
  const char* CAF_UNIFYN(func_name_) = __func__;                               \
  CAF_LOG_IMPL(CAF_LOG_LEVEL_TRACE, "ENTRY" << entry_message);                 \
  auto CAF_UNIFYN(caf_log_trace_guard_) = ::caf::detail::make_scope_guard([=] {\
    caf::logger::log_static(CAF_LOG_LEVEL_TRACE, CAF_LOG_COMPONENT,            \
                            CAF_GET_CLASS_NAME, CAF_UNIFYN(func_name_),        \
                            __FILE__, __LINE__, "EXIT");                       \
  })

#endif // CAF_LOG_LEVEL < CAF_LOG_LEVEL_TRACE

#if CAF_LOG_LEVEL >= CAF_LOG_LEVEL_DEBUG
#  define CAF_LOG_DEBUG(output) CAF_LOG_IMPL(CAF_LOG_LEVEL_DEBUG, output)
#endif

#if CAF_LOG_LEVEL >= CAF_LOG_LEVEL_INFO
#  define CAF_LOG_INFO(output) CAF_LOG_IMPL(CAF_LOG_LEVEL_INFO, output)
#endif

#if CAF_LOG_LEVEL >= CAF_LOG_LEVEL_WARNING
#  define CAF_LOG_WARNING(output) CAF_LOG_IMPL(CAF_LOG_LEVEL_WARNING, output)
#endif

#define CAF_LOG_ERROR(output) CAF_LOG_IMPL(CAF_LOG_LEVEL_ERROR, output)

#endif // CAF_LOG_LEVEL

#ifndef CAF_LOG_INFO
#  define CAF_LOG_INFO(output) CAF_VOID_STMT
#endif

#ifndef CAF_LOG_DEBUG
#  define CAF_LOG_DEBUG(output) CAF_VOID_STMT
#endif

#ifndef CAF_LOG_WARNING
#  define CAF_LOG_WARNING(output) CAF_VOID_STMT
#endif

#ifndef CAF_LOG_ERROR
#  define CAF_LOG_ERROR(output) CAF_VOID_STMT
#endif

#ifdef CAF_LOG_LEVEL

#define CAF_LOG_DEBUG_IF(cond, output)                                         \
  if (cond) { CAF_LOG_IMPL(CAF_LOG_LEVEL_DEBUG, output); } CAF_VOID_STMT

#define CAF_LOG_INFO_IF(cond, output)                                          \
  if (cond) { CAF_LOG_IMPL(CAF_LOG_LEVEL_INFO, output); } CAF_VOID_STMT

#define CAF_LOG_WARNING_IF(cond, output)                                       \
  if (cond) { CAF_LOG_IMPL(CAF_LOG_LEVEL_WARNING, output); } CAF_VOID_STMT

#define CAF_LOG_ERROR_IF(cond, output)                                         \
  if (cond) { CAF_LOG_IMPL(CAF_LOG_LEVEL_ERROR, output); } CAF_VOID_STMT

#else // CAF_LOG_LEVEL

#define CAF_LOG_DEBUG_IF(unused1, unused2)
#define CAF_LOG_INFO_IF(unused1, unused2)
#define CAF_LOG_WARNING_IF(unused1, unused2)
#define CAF_LOG_ERROR_IF(unused1, unused2)

#endif // CAF_LOG_LEVEL

#endif // CAF_DETAIL_LOGGING_HPP
<|endoftext|>