<commit_before>// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/api/atom_api_app.h"

#include <string>
#include <vector>

#include "atom/browser/api/atom_api_menu.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/browser.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "base/command_line.h"
#include "base/environment.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "brightray/browser/brightray_paths.h"
#include "native_mate/callback.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "net/base/load_flags.h"
#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"

#include "atom/common/node_includes.h"

using atom::Browser;

namespace mate {

#if defined(OS_WIN)
template<>
struct Converter<Browser::UserTask> {
  static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
                     Browser::UserTask* out) {
    mate::Dictionary dict;
    if (!ConvertFromV8(isolate, val, &dict))
      return false;
    if (!dict.Get("program", &(out->program)) ||
        !dict.Get("title", &(out->title)))
      return false;
    if (dict.Get("iconPath", &(out->icon_path)) &&
        !dict.Get("iconIndex", &(out->icon_index)))
      return false;
    dict.Get("arguments", &(out->arguments));
    dict.Get("description", &(out->description));
    return true;
  }
};
#endif

}  // namespace mate

namespace atom {

namespace api {

namespace {

// Return the path constant from string.
int GetPathConstant(const std::string& name) {
  if (name == "appData")
    return brightray::DIR_APP_DATA;
  else if (name == "userData")
    return brightray::DIR_USER_DATA;
  else if (name == "cache")
    return brightray::DIR_CACHE;
  else if (name == "userCache")
    return brightray::DIR_USER_CACHE;
  else if (name == "home")
    return base::DIR_HOME;
  else if (name == "temp")
    return base::DIR_TEMP;
  else if (name == "userDesktop")
    return base::DIR_USER_DESKTOP;
  else if (name == "exe")
    return base::FILE_EXE;
  else if (name == "module")
    return base::FILE_MODULE;
  else
    return -1;
}

class ResolveProxyHelper {
 public:
  ResolveProxyHelper(const GURL& url, App::ResolveProxyCallback callback)
      : callback_(callback) {
    net::ProxyService* proxy_service = AtomBrowserContext::Get()->
        url_request_context_getter()->GetURLRequestContext()->proxy_service();

    // Start the request.
    int result = proxy_service->ResolveProxy(
        url, net::LOAD_NORMAL, &proxy_info_,
        base::Bind(&ResolveProxyHelper::OnResolveProxyCompleted,
                   base::Unretained(this)),
        &pac_req_, nullptr, net::BoundNetLog());

    // Completed synchronously.
    if (result != net::ERR_IO_PENDING)
      OnResolveProxyCompleted(result);
  }

  void OnResolveProxyCompleted(int result) {
    std::string proxy;
    if (result == net::OK)
      proxy = proxy_info_.ToPacString();
    callback_.Run(proxy);

    delete this;
  }

 private:
  App::ResolveProxyCallback callback_;
  net::ProxyInfo proxy_info_;
  net::ProxyService::PacRequest* pac_req_;

  DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper);
};

}  // namespace

App::App() {
  Browser::Get()->AddObserver(this);
}

App::~App() {
  Browser::Get()->RemoveObserver(this);
}

void App::OnBeforeQuit(bool* prevent_default) {
  *prevent_default = Emit("before-quit");
}

void App::OnWillQuit(bool* prevent_default) {
  *prevent_default = Emit("will-quit");
}

void App::OnWindowAllClosed() {
  Emit("window-all-closed");
}

void App::OnQuit() {
  Emit("quit");
}

void App::OnOpenFile(bool* prevent_default, const std::string& file_path) {
  *prevent_default = Emit("open-file", file_path);
}

void App::OnOpenURL(const std::string& url) {
  Emit("open-url", url);
}

void App::OnActivateWithNoOpenWindows() {
  Emit("activate-with-no-open-windows");
}

void App::OnWillFinishLaunching() {
  Emit("will-finish-launching");
}

void App::OnFinishLaunching() {
  Emit("ready");
}

base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
  bool succeed = false;
  base::FilePath path;
  int key = GetPathConstant(name);
  if (key >= 0)
    succeed = PathService::Get(key, &path);
  if (!succeed)
    args->ThrowError("Failed to get path");
  return path;
}

void App::SetPath(mate::Arguments* args,
                  const std::string& name,
                  const base::FilePath& path) {
  bool succeed = false;
  int key = GetPathConstant(name);
  if (key >= 0)
    succeed = PathService::Override(key, path);
  if (!succeed)
    args->ThrowError("Failed to set path");
}

void App::ResolveProxy(const GURL& url, ResolveProxyCallback callback) {
  new ResolveProxyHelper(url, callback);
}

void App::SetDesktopName(const std::string& desktop_name) {
#if defined(OS_LINUX)
  scoped_ptr<base::Environment> env(base::Environment::Create());
  env->SetVar("CHROME_DESKTOP", desktop_name);
#endif
}

void App::SetAppUserModelId(const std::string& app_id) {
#if defined(OS_WIN)
  base::string16 app_id_utf16 = base::UTF8ToUTF16(app_id);
  SetCurrentProcessExplicitAppUserModelID(app_id_utf16.c_str());
#endif
}

mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
    v8::Isolate* isolate) {
  auto browser = base::Unretained(Browser::Get());
  return mate::ObjectTemplateBuilder(isolate)
      .SetMethod("quit", base::Bind(&Browser::Quit, browser))
      .SetMethod("focus", base::Bind(&Browser::Focus, browser))
      .SetMethod("getVersion", base::Bind(&Browser::GetVersion, browser))
      .SetMethod("setVersion", base::Bind(&Browser::SetVersion, browser))
      .SetMethod("getName", base::Bind(&Browser::GetName, browser))
      .SetMethod("setName", base::Bind(&Browser::SetName, browser))
      .SetMethod("isReady", base::Bind(&Browser::is_ready, browser))
      .SetMethod("addRecentDocument",
                 base::Bind(&Browser::AddRecentDocument, browser))
      .SetMethod("clearRecentDocuments",
                 base::Bind(&Browser::ClearRecentDocuments, browser))
#if defined(OS_WIN)
      .SetMethod("setUserTasks",
                 base::Bind(&Browser::SetUserTasks, browser))
#endif
      .SetMethod("setPath", &App::SetPath)
      .SetMethod("getPath", &App::GetPath)
      .SetMethod("resolveProxy", &App::ResolveProxy)
      .SetMethod("setDesktopName", &App::SetDesktopName)
      .SetMethod("setAppUserModelId", &App::SetAppUserModelId);
}

// static
mate::Handle<App> App::Create(v8::Isolate* isolate) {
  return CreateHandle(isolate, new App);
}

}  // namespace api

}  // namespace atom

namespace {

void AppendSwitch(const std::string& switch_string, mate::Arguments* args) {
  auto command_line = base::CommandLine::ForCurrentProcess();
  std::string value;
  if (args->GetNext(&value))
    command_line->AppendSwitchASCII(switch_string, value);
  else
    command_line->AppendSwitch(switch_string);
}

#if defined(OS_MACOSX)
int DockBounce(const std::string& type) {
  int request_id = -1;
  if (type == "critical")
    request_id = Browser::Get()->DockBounce(Browser::BOUNCE_CRITICAL);
  else if (type == "informational")
    request_id = Browser::Get()->DockBounce(Browser::BOUNCE_INFORMATIONAL);
  return request_id;
}

void DockSetMenu(atom::api::Menu* menu) {
  Browser::Get()->DockSetMenu(menu->model());
}
#endif

void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
                v8::Handle<v8::Context> context, void* priv) {
  v8::Isolate* isolate = context->GetIsolate();
  auto command_line = base::CommandLine::ForCurrentProcess();

  mate::Dictionary dict(isolate, exports);
  dict.Set("app", atom::api::App::Create(isolate));
  dict.SetMethod("appendSwitch", &AppendSwitch);
  dict.SetMethod("appendArgument",
                 base::Bind(&base::CommandLine::AppendArg,
                            base::Unretained(command_line)));
#if defined(OS_MACOSX)
  auto browser = base::Unretained(Browser::Get());
  dict.SetMethod("dockBounce", &DockBounce);
  dict.SetMethod("dockCancelBounce",
                 base::Bind(&Browser::DockCancelBounce, browser));
  dict.SetMethod("dockSetBadgeText",
                 base::Bind(&Browser::DockSetBadgeText, browser));
  dict.SetMethod("dockGetBadgeText",
                 base::Bind(&Browser::DockGetBadgeText, browser));
  dict.SetMethod("dockHide", base::Bind(&Browser::DockHide, browser));
  dict.SetMethod("dockShow", base::Bind(&Browser::DockShow, browser));
  dict.SetMethod("dockSetMenu", &DockSetMenu);
#endif
}

}  // namespace

NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_app, Initialize)
<commit_msg>win: Fix compilation error<commit_after>// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/api/atom_api_app.h"

#include <string>
#include <vector>

#if defined(OS_WIN)
#include <shlobj.h>
#endif

#include "atom/browser/api/atom_api_menu.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/browser.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "base/command_line.h"
#include "base/environment.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "brightray/browser/brightray_paths.h"
#include "native_mate/callback.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "net/base/load_flags.h"
#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"

#if defined(OS_WIN)
#include "base/strings/utf_string_conversions.h"
#endif

#include "atom/common/node_includes.h"

using atom::Browser;

namespace mate {

#if defined(OS_WIN)
template<>
struct Converter<Browser::UserTask> {
  static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
                     Browser::UserTask* out) {
    mate::Dictionary dict;
    if (!ConvertFromV8(isolate, val, &dict))
      return false;
    if (!dict.Get("program", &(out->program)) ||
        !dict.Get("title", &(out->title)))
      return false;
    if (dict.Get("iconPath", &(out->icon_path)) &&
        !dict.Get("iconIndex", &(out->icon_index)))
      return false;
    dict.Get("arguments", &(out->arguments));
    dict.Get("description", &(out->description));
    return true;
  }
};
#endif

}  // namespace mate

namespace atom {

namespace api {

namespace {

// Return the path constant from string.
int GetPathConstant(const std::string& name) {
  if (name == "appData")
    return brightray::DIR_APP_DATA;
  else if (name == "userData")
    return brightray::DIR_USER_DATA;
  else if (name == "cache")
    return brightray::DIR_CACHE;
  else if (name == "userCache")
    return brightray::DIR_USER_CACHE;
  else if (name == "home")
    return base::DIR_HOME;
  else if (name == "temp")
    return base::DIR_TEMP;
  else if (name == "userDesktop")
    return base::DIR_USER_DESKTOP;
  else if (name == "exe")
    return base::FILE_EXE;
  else if (name == "module")
    return base::FILE_MODULE;
  else
    return -1;
}

class ResolveProxyHelper {
 public:
  ResolveProxyHelper(const GURL& url, App::ResolveProxyCallback callback)
      : callback_(callback) {
    net::ProxyService* proxy_service = AtomBrowserContext::Get()->
        url_request_context_getter()->GetURLRequestContext()->proxy_service();

    // Start the request.
    int result = proxy_service->ResolveProxy(
        url, net::LOAD_NORMAL, &proxy_info_,
        base::Bind(&ResolveProxyHelper::OnResolveProxyCompleted,
                   base::Unretained(this)),
        &pac_req_, nullptr, net::BoundNetLog());

    // Completed synchronously.
    if (result != net::ERR_IO_PENDING)
      OnResolveProxyCompleted(result);
  }

  void OnResolveProxyCompleted(int result) {
    std::string proxy;
    if (result == net::OK)
      proxy = proxy_info_.ToPacString();
    callback_.Run(proxy);

    delete this;
  }

 private:
  App::ResolveProxyCallback callback_;
  net::ProxyInfo proxy_info_;
  net::ProxyService::PacRequest* pac_req_;

  DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper);
};

}  // namespace

App::App() {
  Browser::Get()->AddObserver(this);
}

App::~App() {
  Browser::Get()->RemoveObserver(this);
}

void App::OnBeforeQuit(bool* prevent_default) {
  *prevent_default = Emit("before-quit");
}

void App::OnWillQuit(bool* prevent_default) {
  *prevent_default = Emit("will-quit");
}

void App::OnWindowAllClosed() {
  Emit("window-all-closed");
}

void App::OnQuit() {
  Emit("quit");
}

void App::OnOpenFile(bool* prevent_default, const std::string& file_path) {
  *prevent_default = Emit("open-file", file_path);
}

void App::OnOpenURL(const std::string& url) {
  Emit("open-url", url);
}

void App::OnActivateWithNoOpenWindows() {
  Emit("activate-with-no-open-windows");
}

void App::OnWillFinishLaunching() {
  Emit("will-finish-launching");
}

void App::OnFinishLaunching() {
  Emit("ready");
}

base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
  bool succeed = false;
  base::FilePath path;
  int key = GetPathConstant(name);
  if (key >= 0)
    succeed = PathService::Get(key, &path);
  if (!succeed)
    args->ThrowError("Failed to get path");
  return path;
}

void App::SetPath(mate::Arguments* args,
                  const std::string& name,
                  const base::FilePath& path) {
  bool succeed = false;
  int key = GetPathConstant(name);
  if (key >= 0)
    succeed = PathService::Override(key, path);
  if (!succeed)
    args->ThrowError("Failed to set path");
}

void App::ResolveProxy(const GURL& url, ResolveProxyCallback callback) {
  new ResolveProxyHelper(url, callback);
}

void App::SetDesktopName(const std::string& desktop_name) {
#if defined(OS_LINUX)
  scoped_ptr<base::Environment> env(base::Environment::Create());
  env->SetVar("CHROME_DESKTOP", desktop_name);
#endif
}

void App::SetAppUserModelId(const std::string& app_id) {
#if defined(OS_WIN)
  base::string16 app_id_utf16 = base::UTF8ToUTF16(app_id);
  SetCurrentProcessExplicitAppUserModelID(app_id_utf16.c_str());
#endif
}

mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
    v8::Isolate* isolate) {
  auto browser = base::Unretained(Browser::Get());
  return mate::ObjectTemplateBuilder(isolate)
      .SetMethod("quit", base::Bind(&Browser::Quit, browser))
      .SetMethod("focus", base::Bind(&Browser::Focus, browser))
      .SetMethod("getVersion", base::Bind(&Browser::GetVersion, browser))
      .SetMethod("setVersion", base::Bind(&Browser::SetVersion, browser))
      .SetMethod("getName", base::Bind(&Browser::GetName, browser))
      .SetMethod("setName", base::Bind(&Browser::SetName, browser))
      .SetMethod("isReady", base::Bind(&Browser::is_ready, browser))
      .SetMethod("addRecentDocument",
                 base::Bind(&Browser::AddRecentDocument, browser))
      .SetMethod("clearRecentDocuments",
                 base::Bind(&Browser::ClearRecentDocuments, browser))
#if defined(OS_WIN)
      .SetMethod("setUserTasks",
                 base::Bind(&Browser::SetUserTasks, browser))
#endif
      .SetMethod("setPath", &App::SetPath)
      .SetMethod("getPath", &App::GetPath)
      .SetMethod("resolveProxy", &App::ResolveProxy)
      .SetMethod("setDesktopName", &App::SetDesktopName)
      .SetMethod("setAppUserModelId", &App::SetAppUserModelId);
}

// static
mate::Handle<App> App::Create(v8::Isolate* isolate) {
  return CreateHandle(isolate, new App);
}

}  // namespace api

}  // namespace atom

namespace {

void AppendSwitch(const std::string& switch_string, mate::Arguments* args) {
  auto command_line = base::CommandLine::ForCurrentProcess();
  std::string value;
  if (args->GetNext(&value))
    command_line->AppendSwitchASCII(switch_string, value);
  else
    command_line->AppendSwitch(switch_string);
}

#if defined(OS_MACOSX)
int DockBounce(const std::string& type) {
  int request_id = -1;
  if (type == "critical")
    request_id = Browser::Get()->DockBounce(Browser::BOUNCE_CRITICAL);
  else if (type == "informational")
    request_id = Browser::Get()->DockBounce(Browser::BOUNCE_INFORMATIONAL);
  return request_id;
}

void DockSetMenu(atom::api::Menu* menu) {
  Browser::Get()->DockSetMenu(menu->model());
}
#endif

void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
                v8::Handle<v8::Context> context, void* priv) {
  v8::Isolate* isolate = context->GetIsolate();
  auto command_line = base::CommandLine::ForCurrentProcess();

  mate::Dictionary dict(isolate, exports);
  dict.Set("app", atom::api::App::Create(isolate));
  dict.SetMethod("appendSwitch", &AppendSwitch);
  dict.SetMethod("appendArgument",
                 base::Bind(&base::CommandLine::AppendArg,
                            base::Unretained(command_line)));
#if defined(OS_MACOSX)
  auto browser = base::Unretained(Browser::Get());
  dict.SetMethod("dockBounce", &DockBounce);
  dict.SetMethod("dockCancelBounce",
                 base::Bind(&Browser::DockCancelBounce, browser));
  dict.SetMethod("dockSetBadgeText",
                 base::Bind(&Browser::DockSetBadgeText, browser));
  dict.SetMethod("dockGetBadgeText",
                 base::Bind(&Browser::DockGetBadgeText, browser));
  dict.SetMethod("dockHide", base::Bind(&Browser::DockHide, browser));
  dict.SetMethod("dockShow", base::Bind(&Browser::DockShow, browser));
  dict.SetMethod("dockSetMenu", &DockSetMenu);
#endif
}

}  // namespace

NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_app, Initialize)
<|endoftext|>


<commit_before>#include <stingray/toolkit/Factory.h>

#include <stingray/toolkit/any.h>

#include <stingray/app/activation_manager/ActivationIntent.h>
#include <stingray/app/application_context/AppChannel.h>
#include <stingray/app/application_context/ChannelList.h>
#include <stingray/app/scheduler/ScheduledEvents.h>
#include <stingray/app/tests/AutoFilter.h>
#include <stingray/ca/BasicSubscription.h>
#include <stingray/ca/BissConditionalAccess.h>
#include <stingray/ca/DreSubscription.h>
#include <stingray/crypto/PlainCipherKey.h>
#include <stingray/details/IReceiverTrait.h>
#include <stingray/hdmi/IHDMI.h>
#include <stingray/media/ImageFileMediaData.h>
#include <stingray/media/MediaInfoBase.h>
#include <stingray/media/Mp3MediaInfo.h>
#include <stingray/media/formats/flv/MediaInfo.h>
#include <stingray/media/formats/mp4/MediaInfo.h>
#include <stingray/media/formats/mp4/Stream.h>
#include <stingray/media/formats/mp4/SubstreamDescriptors.h>
#include <stingray/mpeg/Stream.h>
#include <stingray/net/DHCPInterfaceConfiguration.h>
#include <stingray/net/IgnoredInterfaceConfiguration.h>
#include <stingray/net/LinkLocalInterfaceConfiguration.h>
#include <stingray/net/ManualInterfaceConfiguration.h>
#include <stingray/parentalcontrol/AgeRating.h>
#ifdef PLATFORM_EMU
#	include <stingray/platform/emu/scanner/Channel.h>
#endif
#ifdef PLATFORM_MSTAR
#	include <stingray/platform/mstar/crypto/HardwareCipherKey.h>
#endif
#ifdef PLATFORM_OPENSSL
#	include <stingray/platform/openssl/crypto/Certificate.h>
#endif
#ifdef PLATFORM_OPENSSL
#	include <stingray/platform/openssl/crypto/EvpKey.h>
#endif
#ifdef PLATFORM_STAPI
#	include <stingray/platform/stapi/crypto/HardwareCipherKey.h>
#endif
#include <stingray/records/FileSystemRecord.h>
#include <stingray/rpc/UrlObjectId.h>
#include <stingray/scanner/DVBServiceId.h>
#include <stingray/scanner/DefaultDVBTBandInfo.h>
#include <stingray/scanner/DefaultMpegService.h>
#include <stingray/scanner/DefaultMpegSubstreamDescriptor.h>
#include <stingray/scanner/DefaultScanParams.h>
#include <stingray/scanner/DreCasGeographicRegion.h>
#include <stingray/scanner/LybidScanParams.h>
#include <stingray/scanner/TerrestrialScanParams.h>
#include <stingray/scanner/TricolorGeographicRegion.h>
#include <stingray/scanner/TricolorScanParams.h>
#include <stingray/scanner/lybid/LybidServiceMetaInfo.h>
#include <stingray/scanner/terrestrial/TerrestrialServiceMetaInfo.h>
#include <stingray/scanner/tricolor/TricolorServiceMetaInfo.h>
#include <stingray/stats/StatisticChannelInfo.h>
#include <stingray/streams/PlaybackStreamContent.h>
#include <stingray/streams/RecordStreamContent.h>
#include <stingray/streams/RecordStreamMetaInfo.h>
#include <stingray/tuners/TunerState.h>
#include <stingray/tuners/dvbs/Antenna.h>
#include <stingray/tuners/dvbs/DefaultDVBSTransport.h>
#include <stingray/tuners/dvbs/Satellite.h>
#include <stingray/tuners/dvbt/DVBTTransport.h>
#include <stingray/tuners/ip/TsOverIpTransport.h>
#include <stingray/update/VersionRequirement.h>
#include <stingray/update/system/CopyFile.h>
#include <stingray/update/system/EraseFlashPartition.h>
#include <stingray/update/system/MountFilesystem.h>
#include <stingray/update/system/MoveFile.h>
#include <stingray/update/system/RemoveFile.h>
#include <stingray/update/system/UnmountFilesystem.h>
#include <stingray/update/system/WriteFlashPartition.h>

/* WARNING! This is autogenerated file, DO NOT EDIT! */

namespace stingray { namespace Detail
{
	void Factory::RegisterTypes()
	{
#ifdef BUILD_SHARED_LIB
		/*nothing*/
#else
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ActivationKeyIntent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::PersonalCodeIntent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::PlatformNameIntent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ReceiverTraitIntent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::AppChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ChannelList);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::CinemaHallScheduledViewing);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ContinuousScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::DeferredStandby);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::InfiniteScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledRecord);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledViewing);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::AutoFilter);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(BasicSubscription);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(BasicSubscriptionProvider);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(BissSubscriptionClass);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Dre4SubscriptionClass);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(PlainCipherKey);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBCReceiverTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBSReceiverTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBTReceiverTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(HouseholdClientTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(HouseholdServerTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LybidOperatorTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorOperatorTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(HDMIConfig);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(ImageFileMediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(ImageFileMediaPreview);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(InMemoryImageMediaPreview);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MediaInfoBase);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Mp3MediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(flv::MediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mp4::MediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mp4::Stream);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mp4::Mp4MediaAudioSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mp4::Mp4MediaVideoSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mpeg::Stream);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DHCPInterfaceConfiguration);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(IgnoredInterfaceConfiguration);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LinkLocalInterfaceConfiguration);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(ManualInterfaceConfiguration);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(AgeRating);
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::EmuServiceId);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::RadioChannel);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::SubstreamDescriptor);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::TVChannel);
#endif
#ifdef PLATFORM_MSTAR
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mstar::HardwareCipherKey);
#endif
#ifdef PLATFORM_OPENSSL
		TOOLKIT_REGISTER_CLASS_EXPLICIT(openssl::Certificate);
#endif
#ifdef PLATFORM_OPENSSL
		TOOLKIT_REGISTER_CLASS_EXPLICIT(openssl::EvpKey);
#endif
#ifdef PLATFORM_STAPI
		TOOLKIT_REGISTER_CLASS_EXPLICIT(stapi::HardwareCipherKey);
#endif
		TOOLKIT_REGISTER_CLASS_EXPLICIT(FileSystemRecord);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(rpc::UrlObjectId);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBServiceId);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultDVBTBandInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegRadioChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegService);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegTVChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegAudioSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegDataCarouselSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegPcrSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegSubtitlesSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegTeletextBasedSubtitlesSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegTeletextSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegVideoSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DreCasGeographicRegion);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LybidScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TerrestrialScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorGeographicRegion);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LybidServiceMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TerrestrialServiceMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorServiceMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Detail::any::ObjectHolder<stingray::StatisticChannelInfo>);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(PlaybackStreamContent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(RecordStreamContent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(RecordStreamMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(CircuitedTunerState);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LockedTunerState);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(UnlockedTunerState);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Antenna);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultDVBSTransport);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Satellite);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBTTransport);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TsOverIpTransport);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(VersionRequirement);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(CopyFile);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(EraseFlashPartition);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MountFilesystem);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MoveFile);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(RemoveFile);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(UnmountFilesystem);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(WriteFlashPartition);
#endif
	}
}}
<commit_msg>update factory classes<commit_after>#include <stingray/toolkit/Factory.h>

#include <stingray/toolkit/any.h>

#include <stingray/app/activation_manager/ActivationIntent.h>
#include <stingray/app/application_context/AppChannel.h>
#include <stingray/app/application_context/ChannelList.h>
#include <stingray/app/scheduler/ScheduledEvents.h>
#include <stingray/app/tests/AutoFilter.h>
#include <stingray/ca/BasicSubscription.h>
#include <stingray/ca/BissConditionalAccess.h>
#include <stingray/ca/DreSubscription.h>
#include <stingray/crypto/PlainCipherKey.h>
#include <stingray/details/IReceiverTrait.h>
#include <stingray/hdmi/IHDMI.h>
#include <stingray/media/ImageFileMediaData.h>
#include <stingray/media/MediaInfoBase.h>
#include <stingray/media/Mp3MediaInfo.h>
#include <stingray/media/formats/flv/MediaInfo.h>
#include <stingray/media/formats/mp4/MediaInfo.h>
#include <stingray/media/formats/mp4/Stream.h>
#include <stingray/media/formats/mp4/SubstreamDescriptors.h>
#include <stingray/mpeg/Stream.h>
#include <stingray/net/DHCPInterfaceConfiguration.h>
#include <stingray/net/IgnoredInterfaceConfiguration.h>
#include <stingray/net/LinkLocalInterfaceConfiguration.h>
#include <stingray/net/ManualInterfaceConfiguration.h>
#include <stingray/parentalcontrol/AgeRating.h>
#ifdef PLATFORM_EMU
#	include <stingray/platform/emu/scanner/Channel.h>
#endif
#ifdef PLATFORM_MSTAR
#	include <stingray/platform/mstar/crypto/HardwareCipherKey.h>
#endif
#ifdef PLATFORM_OPENSSL
#	include <stingray/platform/openssl/crypto/Certificate.h>
#endif
#ifdef PLATFORM_OPENSSL
#	include <stingray/platform/openssl/crypto/CertificateRevocationList.h>
#endif
#ifdef PLATFORM_OPENSSL
#	include <stingray/platform/openssl/crypto/EvpKey.h>
#endif
#ifdef PLATFORM_STAPI
#	include <stingray/platform/stapi/crypto/HardwareCipherKey.h>
#endif
#include <stingray/records/FileSystemRecord.h>
#include <stingray/rpc/UrlObjectId.h>
#include <stingray/scanner/DVBServiceId.h>
#include <stingray/scanner/DefaultDVBTBandInfo.h>
#include <stingray/scanner/DefaultMpegService.h>
#include <stingray/scanner/DefaultMpegSubstreamDescriptor.h>
#include <stingray/scanner/DefaultScanParams.h>
#include <stingray/scanner/DreCasGeographicRegion.h>
#include <stingray/scanner/LybidScanParams.h>
#include <stingray/scanner/TerrestrialScanParams.h>
#include <stingray/scanner/TricolorGeographicRegion.h>
#include <stingray/scanner/TricolorScanParams.h>
#include <stingray/scanner/lybid/LybidServiceMetaInfo.h>
#include <stingray/scanner/terrestrial/TerrestrialServiceMetaInfo.h>
#include <stingray/scanner/tricolor/TricolorServiceMetaInfo.h>
#include <stingray/stats/StatisticChannelInfo.h>
#include <stingray/streams/PlaybackStreamContent.h>
#include <stingray/streams/RecordStreamContent.h>
#include <stingray/streams/RecordStreamMetaInfo.h>
#include <stingray/tuners/TunerState.h>
#include <stingray/tuners/dvbs/Antenna.h>
#include <stingray/tuners/dvbs/DefaultDVBSTransport.h>
#include <stingray/tuners/dvbs/Satellite.h>
#include <stingray/tuners/dvbt/DVBTTransport.h>
#include <stingray/tuners/ip/TsOverIpTransport.h>
#include <stingray/update/VersionRequirement.h>
#include <stingray/update/system/CopyFile.h>
#include <stingray/update/system/EraseFlashPartition.h>
#include <stingray/update/system/MountFilesystem.h>
#include <stingray/update/system/MoveFile.h>
#include <stingray/update/system/RemoveFile.h>
#include <stingray/update/system/UnmountFilesystem.h>
#include <stingray/update/system/WriteFlashPartition.h>

/* WARNING! This is autogenerated file, DO NOT EDIT! */

namespace stingray { namespace Detail
{
	void Factory::RegisterTypes()
	{
#ifdef BUILD_SHARED_LIB
		/*nothing*/
#else
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ActivationKeyIntent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::PersonalCodeIntent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::PlatformNameIntent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ReceiverTraitIntent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::AppChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ChannelList);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::CinemaHallScheduledViewing);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ContinuousScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::DeferredStandby);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::InfiniteScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledRecord);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledViewing);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::AutoFilter);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(BasicSubscription);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(BasicSubscriptionProvider);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(BissSubscriptionClass);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Dre4SubscriptionClass);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(PlainCipherKey);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBCReceiverTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBSReceiverTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBTReceiverTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(HouseholdClientTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(HouseholdServerTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LybidOperatorTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorOperatorTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(HDMIConfig);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(ImageFileMediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(ImageFileMediaPreview);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(InMemoryImageMediaPreview);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MediaInfoBase);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Mp3MediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(flv::MediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mp4::MediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mp4::Stream);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mp4::Mp4MediaAudioSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mp4::Mp4MediaVideoSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mpeg::Stream);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DHCPInterfaceConfiguration);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(IgnoredInterfaceConfiguration);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LinkLocalInterfaceConfiguration);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(ManualInterfaceConfiguration);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(AgeRating);
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::EmuServiceId);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::RadioChannel);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::SubstreamDescriptor);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::TVChannel);
#endif
#ifdef PLATFORM_MSTAR
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mstar::HardwareCipherKey);
#endif
#ifdef PLATFORM_OPENSSL
		TOOLKIT_REGISTER_CLASS_EXPLICIT(openssl::Certificate);
#endif
#ifdef PLATFORM_OPENSSL
		TOOLKIT_REGISTER_CLASS_EXPLICIT(openssl::CertificateRevocationList);
#endif
#ifdef PLATFORM_OPENSSL
		TOOLKIT_REGISTER_CLASS_EXPLICIT(openssl::EvpKey);
#endif
#ifdef PLATFORM_STAPI
		TOOLKIT_REGISTER_CLASS_EXPLICIT(stapi::HardwareCipherKey);
#endif
		TOOLKIT_REGISTER_CLASS_EXPLICIT(FileSystemRecord);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(rpc::UrlObjectId);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBServiceId);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultDVBTBandInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegRadioChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegService);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegTVChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegAudioSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegDataCarouselSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegPcrSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegSubtitlesSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegTeletextBasedSubtitlesSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegTeletextSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegVideoSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DreCasGeographicRegion);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LybidScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TerrestrialScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorGeographicRegion);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LybidServiceMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TerrestrialServiceMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorServiceMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Detail::any::ObjectHolder<stingray::StatisticChannelInfo>);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(PlaybackStreamContent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(RecordStreamContent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(RecordStreamMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(CircuitedTunerState);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LockedTunerState);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(UnlockedTunerState);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Antenna);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultDVBSTransport);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Satellite);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBTTransport);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TsOverIpTransport);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(VersionRequirement);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(CopyFile);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(EraseFlashPartition);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MountFilesystem);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MoveFile);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(RemoveFile);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(UnmountFilesystem);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(WriteFlashPartition);
#endif
	}
}}
<|endoftext|>


<commit_before>/*------------------------------------------------------------------------------
| This file is distributed under the BSD 2-Clause License.
| See LICENSE for details.
*-----------------------------------------------------------------------------*/
#include <cstdio>
#include <vector>
#include <utility> /* std::pair */

#include <cuddObj.hh>
extern "C" {
#include "aig/gia/gia.h"
#include "cudd.h"
}

namespace lsy {

/* Black magic */
static inline int test(DdManager *dd, DdNode *l)
{
	if (l == NULL)
		return 0;
	DdNode *lb = l;
	::Cudd_Ref(lb);
	while (lb != ::Cudd_ReadLogicZero(dd)) {
		DdNode *implicant = ::Cudd_LargestCube(dd, lb, NULL);
		if (implicant == NULL) {
			::Cudd_RecursiveDeref(dd, lb);
			return 0;
		}
		::Cudd_Ref(implicant);

		DdNode *prime = ::Cudd_bddMakePrime(dd, implicant, l);
		if (prime == NULL) {
			::Cudd_RecursiveDeref(dd, lb);
			::Cudd_RecursiveDeref(dd, implicant);
			return 0;
		}
		::Cudd_Ref(prime);
		::Cudd_RecursiveDeref(dd, implicant);

		DdNode *tmp = ::Cudd_bddAnd(dd, lb, Cudd_Not(prime));
		if (tmp == NULL) {
			::Cudd_RecursiveDeref(dd, lb);
			::Cudd_RecursiveDeref(dd, prime);
			return 0;
		}
		::Cudd_Ref(tmp);
		::Cudd_RecursiveDeref(dd, lb);
		::Cudd_RecursiveDeref(dd, prime);
		lb = tmp;
	}
	::Cudd_RecursiveDeref(dd, lb);
	return 1;
}

std::pair<Cudd, std::vector<BDD>> aig_to_bdd(Gia_Man_t *aig, bool reorder, int verbose)
{
	uint32_t i, id;
	Gia_Obj_t* obj;
	Cudd bdd_mngr;
	std::vector<BDD> nodes(Gia_ManObjNum(aig));

	if (reorder) {
		bdd_mngr.AutodynEnable();
	}
	//bdd_mngr.AutodynEnable(CUDD_REORDER_EXACT);
	printf("[i] Converting AIG to BDD\n");
	Gia_ManForEachCiId(aig, id, i) {
		nodes[id] = bdd_mngr.bddVar(i);
	}
	Gia_ManForEachAnd(aig, obj, i) {
		const auto b1 = nodes[Gia_ObjFaninId0(obj, i)];
		const auto c1 = Gia_ObjFaninC0(obj);
		const auto b2 = nodes[Gia_ObjFaninId1(obj, i)];
		const auto c2 = Gia_ObjFaninC1(obj);
		nodes[i] = (c1 ? !b1 : b1) & (c2 ? !b2 : b2);
		if (verbose) {
			fprintf(stdout, "\rNode %4d / %4d", i, nodes.size());
			fflush(stdout);
		}
	}
	//bdd_mngr.ReduceHeap();
	//bdd_mngr.ReduceHeap(CUDD_REORDER_EXACT);
	if (verbose) {
		fprintf(stdout, " Done\n");
	}
	/* Outputs */
	std::vector<BDD> outputs;
	Gia_ManForEachCo(aig, obj, i) {
		const auto b = nodes[Gia_ObjFaninId0p(aig, obj)];
		const auto c = Gia_ObjFaninC0(obj);
		outputs.push_back(c ? !b : b);
		test(bdd_mngr.getManager(), outputs.back().getNode());
		fprintf(stdout, "[%d] ", i);
		if (outputs.back().getNode() == NULL) {
			fprintf(stdout, "empty DD.\n");
			continue;
		}
		outputs.back().summary(Gia_ManCiNum(aig));
		// outputs.back().PrintCover();
	}
	fprintf(stdout, " [Done]\n");
	if (reorder) {
		bdd_mngr.AutodynDisable();
	}
	return std::make_pair(bdd_mngr, outputs);
}

} // namespace lsy
<commit_msg>Better verbose info.<commit_after>/*------------------------------------------------------------------------------
| This file is distributed under the BSD 2-Clause License.
| See LICENSE for details.
*-----------------------------------------------------------------------------*/
#include <chrono>
#include <cstdio>
#include <vector>
#include <utility> /* std::pair */

#include <cuddObj.hh>
extern "C" {
#include "aig/gia/gia.h"
#include "cudd.h"
}

namespace lsy {

/* Black magic */
static inline int test(DdManager *dd, DdNode *l)
{
	if (l == NULL)
		return 0;
	DdNode *lb = l;
	::Cudd_Ref(lb);
	while (lb != ::Cudd_ReadLogicZero(dd)) {
		DdNode *implicant = ::Cudd_LargestCube(dd, lb, NULL);
		if (implicant == NULL) {
			::Cudd_RecursiveDeref(dd, lb);
			return 0;
		}
		::Cudd_Ref(implicant);

		DdNode *prime = ::Cudd_bddMakePrime(dd, implicant, l);
		if (prime == NULL) {
			::Cudd_RecursiveDeref(dd, lb);
			::Cudd_RecursiveDeref(dd, implicant);
			return 0;
		}
		::Cudd_Ref(prime);
		::Cudd_RecursiveDeref(dd, implicant);

		DdNode *tmp = ::Cudd_bddAnd(dd, lb, Cudd_Not(prime));
		if (tmp == NULL) {
			::Cudd_RecursiveDeref(dd, lb);
			::Cudd_RecursiveDeref(dd, prime);
			return 0;
		}
		::Cudd_Ref(tmp);
		::Cudd_RecursiveDeref(dd, lb);
		::Cudd_RecursiveDeref(dd, prime);
		lb = tmp;
	}
	::Cudd_RecursiveDeref(dd, lb);
	return 1;
}

std::pair<Cudd, std::vector<BDD>> aig_to_bdd(Gia_Man_t *aig, bool reorder, int verbose)
{
	uint32_t i, id;
	Gia_Obj_t* obj;
	Cudd bdd_mngr;
	std::vector<BDD> nodes(Gia_ManObjNum(aig));

	auto start = std::chrono::high_resolution_clock::now();
	if (reorder) {
		bdd_mngr.AutodynEnable();
	}
	printf("[i] Converting AIG to BDD\n");
	Gia_ManForEachCiId(aig, id, i) {
		nodes[id] = bdd_mngr.bddVar(i);
	}
	Gia_ManForEachAnd(aig, obj, i) {
		const auto b1 = nodes[Gia_ObjFaninId0(obj, i)];
		const auto c1 = Gia_ObjFaninC0(obj);
		const auto b2 = nodes[Gia_ObjFaninId1(obj, i)];
		const auto c2 = Gia_ObjFaninC1(obj);
		if (verbose) {
			fprintf(stdout, "\rNode %4d / %4lu", i,
			        nodes.size() - 1 - Gia_ManCoNum(aig));
			fflush(stdout);
		}
		nodes[i] = (c1 ? !b1 : b1) & (c2 ? !b2 : b2);
	}
	if (verbose) {
		fprintf(stdout, " [Done]\n");
	}
	/* Outputs */
	std::vector<BDD> outputs;
	Gia_ManForEachCo(aig, obj, i) {
		const auto b = nodes[Gia_ObjFaninId0p(aig, obj)];
		const auto c = Gia_ObjFaninC0(obj);
		if (verbose) {
			fprintf(stdout, "\rOutput %2d / %2d", i, Gia_ManCoNum(aig) - 1);
			fflush(stdout);
		}
		outputs.push_back(c ? !b : b);
	}
	if (verbose) {
		fprintf(stdout, " [Done]\n");
		std::chrono::duration<double> aig2bdd_time=
			std::chrono::high_resolution_clock::now() - start;

		printf("[i] Elapsed time: %f\n",  aig2bdd_time.count());
		for (auto &dd : outputs) {
			if (dd.getNode() == NULL) {
				fprintf(stdout, "empty DD.\n");
				continue;
			}
			dd.summary(Gia_ManCiNum(aig));
		}
	}
	if (reorder) {
		bdd_mngr.AutodynDisable();
	}
	return std::make_pair(bdd_mngr, outputs);
}

} // namespace lsy
<|endoftext|>


<commit_before><commit_msg>started with the main() modifications<commit_after><|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2013-2020 Baptiste Wicht.
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include <fstream>

#include "cpp_utils/assert.hpp"

#include "config.hpp"
#include "utils.hpp"
#include "server.hpp"
#include "api.hpp"
#include "server_lock.hpp"
#include "budget_exception.hpp"

namespace budget {

template<typename T>
struct data_handler {
    size_t next_id; // Note: No need to protect this since this is only accessed by GC (not run from server)

    data_handler(const char* module, const char* path) : module(module), path(path) {
        // Nothing else to init
    };

    //data_handler should never be copied
    data_handler(const data_handler& rhs) = delete;
    data_handler& operator=(const data_handler& rhs) = delete;

    bool is_changed() const {
        return changed;
    }

    void set_changed() {
        server_lock_guard l(lock);

        set_changed_internal();
    }

    template<typename Functor>
    void parse_stream(std::istream& file, Functor f){
        next_id = 1;

        std::string line;
        while (file.good() && getline(file, line)) {
            if (line.empty()) {
                continue;
            }

            auto parts = split(line, ':');

            T entry;

            f(parts, entry);

            if (entry.id >= next_id) {
                next_id = entry.id + 1;
            }

            data_.push_back(std::move(entry));
        }
    }

    template<typename Functor>
    void load(Functor f){
        //Make sure to clear the data first, as load_data can be called
        //several times
        data_.clear();

        if(is_server_mode()){
            auto res = budget::api_get(std::string("/") + module + "/list/");

            if(res.success){
                std::stringstream ss(res.result);
                parse_stream(ss, f);
            }
        } else {
            auto file_path = path_to_budget_file(path);

            if (!file_exists(file_path)) {
                next_id = 1;
            } else {
                std::ifstream file(file_path);

                if (file.is_open()) {
                    if (file.good()) {
                        // We do not use the next_id saved anymore
                        // Simply consume it
                        size_t fake;
                        file >> fake;
                        file.get();

                        parse_stream(file, f);
                    }
                }
            }
        }
    }

    void load(){
        load([](std::vector<std::string>& parts, T& entry){ parts >> entry; });
    }

    void save() {
        // In server mode, there is nothing to do
        if (is_server_mode()) {
            // It shoud not be changed
            cpp_assert(!is_changed(), "in server mode, is_changed() should never be true");

            return;
        }

        // In other modes, save if it's changed
        if (is_changed()) {
            force_save();
        }
    }

    bool indirect_edit(const T& value, bool propagate = true) {
        server_lock_guard l(lock);

        if (is_server_mode()) {
            auto params = value.get_params();

            auto res = budget::api_post(std::string("/") + get_module() + "/edit/", params);

            if (!res.success) {
                std::cerr << "error: Failed to edit from " << get_module() << std::endl;

                return false;
            } else {
                return true;
            }
        } else {
            for (auto& v : data_) {
                if (v.id == value.id) {
                    v = value;

                    if (propagate) {
                        set_changed_internal();
                    }

                    return true;
                }
            }

            return false;
        }
    }

    template <typename TT>
    size_t add(TT&& entry) {
        server_lock_guard l(lock);

        if (is_server_mode()) {
            auto params = entry.get_params();

            auto res = budget::api_post(std::string("/") + get_module() + "/add/", params);

            if (!res.success) {
                std::cerr << "error: Failed to add expense" << std::endl;

                entry.id = 0;
            } else {
                entry.id = budget::to_number<size_t>(res.result);

                data_.push_back(std::forward<T>(entry));
            }
        } else {
            entry.id = next_id++;

            data_.push_back(std::forward<T>(entry));

            set_changed_internal();
        }

        return entry.id;
    }

    bool remove(size_t id) {
        server_lock_guard l(lock);

        auto before = data_.size();
        data_.erase(std::remove_if(data_.begin(), data_.end(),
                                  [id](const T& entry) { return entry.id == id; }),
                   data_.end());

        if (is_server_mode()) {
            auto res = budget::api_get(std::string("/") + get_module() + "/delete/?input_id=" + budget::to_string(id));

            if (!res.success) {
                std::cerr << "error: Failed to delete from " << get_module() << std::endl;
            }

            return res.success;
        } else {
            set_changed_internal();

            return size() < before;
        }
    }

    bool exists(size_t id) {
        server_lock_guard l(lock);

        for (auto& entry : data_) {
            if (entry.id == id) {
                return true;
            }
        }

        return false;
    }

    T operator[](size_t id) const {
        server_lock_guard l(lock);

        for (auto& value : data_) {
            if (value.id == id) {
                return value;
            }
        }

        throw budget_exception("There is no data with id " + std::to_string(id) + " in " + module);
    }

    size_t size() const {
        return data_.size();
    }

    bool empty() const {
        return data_.empty();
    }

    const char* get_module() const {
        return module;
    }

    std::vector<T> data() const {
        std::vector<T> copy;
        copy.reserve(size());

        {
            server_lock_guard l(lock);
            std::copy(data_.begin(), data_.end(), std::back_inserter(copy));
        }

        return copy;
    }

    // This can only be accessed during loading
    std::vector<T> & unsafe_data() {
        return data_;
    }

private:
    void set_changed_internal() {
        if (is_server_running()) {
            force_save();
        } else {
            changed = true;
        }
    }

    void force_save() {
        cpp_assert(!is_server_mode(), "force_save() should never be called in server mode");

        if (budget::config_contains("random")) {
            std::cerr << "budget: error: Saving is disabled in random mode" << std::endl;
            return;
        }

        auto file_path = path_to_budget_file(path);

        std::ofstream file(file_path);

        // We still save the file ID so that it's still compatible with older versions for now
        file << next_id << std::endl;

        for (auto& entry : data_) {
            file << entry << std::endl;
        }

        changed = false;
    }

    const char* module;
    const char* path;
    volatile bool changed = false;
    mutable server_lock lock;
    std::vector<T> data_;
};

} //end of namespace budget
<commit_msg>Review next_id consumption<commit_after>//=======================================================================
// Copyright (c) 2013-2020 Baptiste Wicht.
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include <fstream>

#include "cpp_utils/assert.hpp"

#include "config.hpp"
#include "utils.hpp"
#include "server.hpp"
#include "api.hpp"
#include "server_lock.hpp"
#include "budget_exception.hpp"

namespace budget {

template<typename T>
struct data_handler {
    size_t next_id; // Note: No need to protect this since this is only accessed by GC (not run from server)

    data_handler(const char* module, const char* path) : module(module), path(path) {
        // Nothing else to init
    };

    //data_handler should never be copied
    data_handler(const data_handler& rhs) = delete;
    data_handler& operator=(const data_handler& rhs) = delete;

    bool is_changed() const {
        return changed;
    }

    void set_changed() {
        server_lock_guard l(lock);

        set_changed_internal();
    }

    template<typename Functor>
    void parse_stream(std::istream& file, Functor f){
        next_id = 1;

        std::string line;
        while (file.good() && getline(file, line)) {
            if (line.empty()) {
                continue;
            }

            auto parts = split(line, ':');

            T entry;

            f(parts, entry);

            if (entry.id >= next_id) {
                next_id = entry.id + 1;
            }

            data_.push_back(std::move(entry));
        }
    }

    template<typename Functor>
    void load(Functor f){
        //Make sure to clear the data first, as load_data can be called
        //several times
        data_.clear();

        if(is_server_mode()){
            auto res = budget::api_get(std::string("/") + module + "/list/");

            if(res.success){
                std::stringstream ss(res.result);
                parse_stream(ss, f);
            }
        } else {
            auto file_path = path_to_budget_file(path);

            if (!file_exists(file_path)) {
                next_id = 1;
            } else {
                std::ifstream file(file_path);

                if (file.is_open()) {
                    if (file.good()) {
                        // We do not use the next_id saved anymore
                        // Simply consume the line
                        std::string id_line;
                        getline(file, id_line);

                        parse_stream(file, f);
                    }
                }
            }
        }
    }

    void load(){
        load([](std::vector<std::string>& parts, T& entry){ parts >> entry; });
    }

    void save() {
        // In server mode, there is nothing to do
        if (is_server_mode()) {
            // It shoud not be changed
            cpp_assert(!is_changed(), "in server mode, is_changed() should never be true");

            return;
        }

        // In other modes, save if it's changed
        if (is_changed()) {
            force_save();
        }
    }

    bool indirect_edit(const T& value, bool propagate = true) {
        server_lock_guard l(lock);

        if (is_server_mode()) {
            auto params = value.get_params();

            auto res = budget::api_post(std::string("/") + get_module() + "/edit/", params);

            if (!res.success) {
                std::cerr << "error: Failed to edit from " << get_module() << std::endl;

                return false;
            } else {
                return true;
            }
        } else {
            for (auto& v : data_) {
                if (v.id == value.id) {
                    v = value;

                    if (propagate) {
                        set_changed_internal();
                    }

                    return true;
                }
            }

            return false;
        }
    }

    template <typename TT>
    size_t add(TT&& entry) {
        server_lock_guard l(lock);

        if (is_server_mode()) {
            auto params = entry.get_params();

            auto res = budget::api_post(std::string("/") + get_module() + "/add/", params);

            if (!res.success) {
                std::cerr << "error: Failed to add expense" << std::endl;

                entry.id = 0;
            } else {
                entry.id = budget::to_number<size_t>(res.result);

                data_.push_back(std::forward<T>(entry));
            }
        } else {
            entry.id = next_id++;

            data_.push_back(std::forward<T>(entry));

            set_changed_internal();
        }

        return entry.id;
    }

    bool remove(size_t id) {
        server_lock_guard l(lock);

        auto before = data_.size();
        data_.erase(std::remove_if(data_.begin(), data_.end(),
                                  [id](const T& entry) { return entry.id == id; }),
                   data_.end());

        if (is_server_mode()) {
            auto res = budget::api_get(std::string("/") + get_module() + "/delete/?input_id=" + budget::to_string(id));

            if (!res.success) {
                std::cerr << "error: Failed to delete from " << get_module() << std::endl;
            }

            return res.success;
        } else {
            set_changed_internal();

            return size() < before;
        }
    }

    bool exists(size_t id) {
        server_lock_guard l(lock);

        for (auto& entry : data_) {
            if (entry.id == id) {
                return true;
            }
        }

        return false;
    }

    T operator[](size_t id) const {
        server_lock_guard l(lock);

        for (auto& value : data_) {
            if (value.id == id) {
                return value;
            }
        }

        throw budget_exception("There is no data with id " + std::to_string(id) + " in " + module);
    }

    size_t size() const {
        return data_.size();
    }

    bool empty() const {
        return data_.empty();
    }

    const char* get_module() const {
        return module;
    }

    std::vector<T> data() const {
        std::vector<T> copy;
        copy.reserve(size());

        {
            server_lock_guard l(lock);
            std::copy(data_.begin(), data_.end(), std::back_inserter(copy));
        }

        return copy;
    }

    // This can only be accessed during loading
    std::vector<T> & unsafe_data() {
        return data_;
    }

private:
    void set_changed_internal() {
        if (is_server_running()) {
            force_save();
        } else {
            changed = true;
        }
    }

    void force_save() {
        cpp_assert(!is_server_mode(), "force_save() should never be called in server mode");

        if (budget::config_contains("random")) {
            std::cerr << "budget: error: Saving is disabled in random mode" << std::endl;
            return;
        }

        auto file_path = path_to_budget_file(path);

        std::ofstream file(file_path);

        // We still save the file ID so that it's still compatible with older versions for now
        file << next_id << std::endl;

        for (auto& entry : data_) {
            file << entry << std::endl;
        }

        changed = false;
    }

    const char* module;
    const char* path;
    volatile bool changed = false;
    mutable server_lock lock;
    std::vector<T> data_;
};

} //end of namespace budget
<|endoftext|>


<commit_before>#pragma once
#ifndef _DCPU_HPP_
#define _DCPU_HPP_ 1

#include <file.h>

#include <memory>
#include <cstdint>
#include <vector>
#include <deque>
#include <string>

namespace cpu {

const unsigned int DCPU_TOTAL_REGS  = 12;       /// DCPU registers
const unsigned int MAX_DEVICES      = 65535;    /// Max hardware devices
const unsigned int QUEUE_SIZE       = 256;      /// Int. queue size
const unsigned int RAM_SIZE         = 0x10000;  /// RAM size

class IHardware;

/**
 * @brief DCPU Virtual Machine
 * Based on Benedeck's DCPU VM (https://bitbucket.org/benedek/dcpu-16/overview)
 */

class DCPU : public std::enable_shared_from_this<DCPU> {
public:
    DCPU();
    virtual ~DCPU();

    /**
     * Return actual CPU model clock speed
     */
    virtual uint32_t getClock() const {return 100000; }

    /**
    * @brief Sets the CPU to the initial state
    * ADVICE: Also cleans the RAM
    */
    void reset();

    /**
     * @brief Executes a DCPU instrucction
     * @return Number of cycles that the DCPU need to do it
     */
    int step();

    /**
     * @brief Does a DCPU clock tick
     * @return True if executed an instrucction
     */
    bool tick(unsigned int n=1);

    /**
     * @brief Load a program to the DCPU RAM
     * @param prog Data program
     * @param size Data program size in 16 bit words
     * @param offset Offset to place the program in DCPU RAM
     */
    bool loadProgram (const uint16_t* prog,
                      unsigned int size,
                      unsigned int offset = 0);

    /**
     * @brief Load a program to the DCPU RAM from a file
     * @param filename filename of the program
     * @param reverse_endian need to change the endianess
     * @param offset Offset to place the program in DCPU RAM
     */
    bool loadProgramFromFile (const std::string& filename,
                              bool reverse_endian=true,
                              unsigned int offset = 0);

    /**
     * @brief Attach a Hardware device to the DCPU
     * @param new_hw Ptr. to the device
     * @return Device Index if can be atached. If not, return -1
     */
    size_t attachHardware (std::shared_ptr<IHardware> new_hw);

    /**
     * @brief Detach a hardware device
     * @param index hardware to detach at desired index
     * @return Ptr to detached device. NULL if don't exists
     */
    std::shared_ptr<IHardware> detachHardware (size_t index);

    /**
     * @brief Return a pointer to the RAM
     * @return Ptr. to the RAM
     */
    inline uint16_t* getMem() {
        return ram;
    }

    /**
     * @brief Return total number of CPU clock cycles
     * @return Total number of cycles
     */
    inline uint64_t getTotCycles() {
        return tot_cycles;
    };

    /**
     * @brief Return is in fire the CPU
     */
    inline bool getOnFire() {
        return on_fire;
    }

    // Get/Set for registers

    inline void setA (const uint16_t& ra) {
        this->ra = ra;
    }

    inline void setB (const uint16_t& rb) {
        this->rb = rb;
    }

    inline void setC (const uint16_t& rc) {
        this->rc = rc;
    }

    inline void setI (const uint16_t& ri) {
        this->ri = ri;
    }

    inline void setJ (const uint16_t& rj) {
        this->rj = rj;
    }

    inline void setX (const uint16_t& rx) {
        this->rx = rx;
    }

    inline void setY (const uint16_t& ry) {
        this->ry = ry;
    }

    inline void setZ (const uint16_t& rz) {
        this->rz = rz;
    }

    inline void setPC (const uint16_t& rpc) {
        this->rpc = rpc;
    }

    inline void setSP (const uint16_t& rsp) {
        this->rsp = rsp;
    }

    inline void setEX (const uint16_t& rex) {
        this->rex = rex;
    }

    inline void setIA (const uint16_t& ria) {
        this->ria = ria;
    }

    inline const uint16_t& getA() const {
        return ra;
    }

    inline const uint16_t& getB() const {
        return rb;
    }

    inline const uint16_t& getC() const {
        return rc;
    }

    inline const uint16_t& getI() const {
        return ri;
    }

    inline const uint16_t& getJ() const {
        return rj;
    }

    inline const uint16_t& getX() const {
        return rx;
    }

    inline const uint16_t& getY() const {
        return ry;
    }

    inline const uint16_t& getZ() const {
        return rz;
    }

    inline const uint16_t& getPC() const {
        return rpc;
    }

    inline const uint16_t& getSP() const {
        return rsp;
    }

    inline const uint16_t& getEX() const {
        return rex;
    }

    inline const uint16_t& getIA() const {
        return ria;
    }

    // pretty dump

    /**
     * @brief Generates a pretty print dump of registers values
     */
    std::string dumpRegisters();

    /**
     * @brief Generates a pretty HEX print dump of a RAM region
     */
    std::string dumpRam (uint16_t init = 0, uint16_t end = 0);

protected:

private:
    uint16_t ra, rb, rc, rx, ry, rz , ri, rj, rex, rpc, ria, rsp; /// Registers
    uint16_t* ram; /// RAM

    uint16_t* register_table[0x1E];

    inline int realStep();

    inline void triggerInterrupt (uint16_t msg);
    inline void handleInterrupt (uint16_t msg);
    inline void handleHWInterrupts();
    inline void tickHardware();

    bool int_queueing;  /// Queue interrupts
    bool skipping_flag; /// Skiping next instruccion ?
    bool on_fire;         /// HCF

    /* hardware: */
    std::vector<std::shared_ptr<IHardware>> attached_hardware;

    /* interrupt queue: */
    std::deque<uint16_t> int_queue;

    int wait_cycles;    // How many cycles need to wait to finish a instrucction
    uint64_t tot_cycles;

};

/**
 * Hardware device base class
 */
class IHardware {
public:

    IHardware() : cpu(NULL), index(-1)  { };
    virtual ~IHardware() {};

    virtual uint32_t getId() const = 0;             /// Hardware ID
    virtual uint16_t getRevision() const = 0;       /// Hardware Revision
    virtual uint32_t getManufacturer() const = 0;   /// Hardware Manufacturer

    /**
     * @brief Attach the Hardware device to the CPU
     * @param cpu Ptr to the CPU
     */
    virtual void attachTo (DCPU* cpu, size_t index) {
        this->cpu = cpu;
        this->index = index;
    }

    /**
     * @brief Detachs from the CPU
     */
    virtual void detach() {
        this->cpu = NULL;
    }

    /**
     * @brief Checks if need to trigger a interupt to the CPU
     * @param msg Ref. to the message
     * @return True if trigger a interrupt
    */
    virtual bool checkInterrupt (uint16_t &msg) {
        return false;
    }

    /**
     * @brief Handle a interrupt from DCP to Hardware
     * @return Number of cycles that DCPU waits
     */
    virtual unsigned handleInterrupt() = 0;

    /**
     * @brief Does a CPU Clock Tick
     */
    virtual void tick() = 0;

    /**
     * @brief Return attached Hardware Dev. Index
     */
    const size_t& getDevIndex() const { return index; }

protected:
    DCPU* cpu;
    size_t index;   /// Hardware Device index

};

} // END OF NAMESPACE

#endif // _DCPU_HPP_
<commit_msg>Retouches of interface and added a getter to int_queueing<commit_after>#pragma once
#ifndef _DCPU_HPP_
#define _DCPU_HPP_ 1

#include <file.h>

#include <memory>
#include <cstdint>
#include <vector>
#include <deque>
#include <string>

namespace cpu {

const unsigned int DCPU_TOTAL_REGS  = 12;       /// DCPU registers
const unsigned int MAX_DEVICES      = 65535;    /// Max hardware devices
const unsigned int QUEUE_SIZE       = 256;      /// Int. queue size
const unsigned int RAM_SIZE         = 0x10000;  /// RAM size

class IHardware;

/**
 * @brief DCPU Virtual Machine
 * Based on Benedeck's DCPU VM (https://bitbucket.org/benedek/dcpu-16/overview)
 */

class DCPU : public std::enable_shared_from_this<DCPU> {
public:
    DCPU();
    virtual ~DCPU();

    /**
     * Return actual CPU model clock speed
     */
    virtual uint32_t getClock() const {return 100000; }

    /**
    * @brief Sets the CPU to the initial state
    * ADVICE: Also cleans the RAM
    */
    void reset();

    /**
     * @brief Executes a DCPU instrucction
     * @return Number of cycles that the DCPU need to do it
     */
    int step();

    /**
     * @brief Does a DCPU clock tick
     * @return True if executed an instrucction
     */
    bool tick(unsigned int n=1);

    /**
     * @brief Load a program to the DCPU RAM
     * @param prog Data program
     * @param size Data program size in 16 bit words
     * @param offset Offset to place the program in DCPU RAM
     */
    bool loadProgram (const uint16_t* prog,
                      unsigned int size,
                      unsigned int offset = 0);

    /**
     * @brief Load a program to the DCPU RAM from a file
     * @param filename filename of the program
     * @param reverse_endian need to change the endianess
     * @param offset Offset to place the program in DCPU RAM
     */
    bool loadProgramFromFile (const std::string& filename,
                              bool reverse_endian=true,
                              unsigned int offset = 0);

    /**
     * @brief Attach a Hardware device to the DCPU
     * @param new_hw Ptr. to the device
     * @return Device Index if can be atached. If not, return -1
     */
    size_t attachHardware (std::shared_ptr<IHardware> new_hw);

    /**
     * @brief Detach a hardware device
     * @param index hardware to detach at desired index
     * @return Ptr to detached device. NULL if don't exists
     */
    std::shared_ptr<IHardware> detachHardware (size_t index);

    /**
     * @brief Return a pointer to the RAM
     * @return Ptr. to the RAM
     */
    inline uint16_t* getMem() {
        return ram;
    }

    /**
     * @brief Return total number of CPU clock cycles
     * @return Total number of cycles
     */
    inline uint64_t getTotCycles() const{
        return tot_cycles;
    };

    /**
     * @brief Return is in fire the CPU
     */
    inline bool getOnFire() const{
        return on_fire;
    }

    /**
     * @brief Return if is Queuing interrupts
     */
    inline bool isQueueing() const {
        return int_queueing;
    }

    // Get/Set for registers

    inline void setA (const uint16_t& ra) {
        this->ra = ra;
    }

    inline void setB (const uint16_t& rb) {
        this->rb = rb;
    }

    inline void setC (const uint16_t& rc) {
        this->rc = rc;
    }

    inline void setI (const uint16_t& ri) {
        this->ri = ri;
    }

    inline void setJ (const uint16_t& rj) {
        this->rj = rj;
    }

    inline void setX (const uint16_t& rx) {
        this->rx = rx;
    }

    inline void setY (const uint16_t& ry) {
        this->ry = ry;
    }

    inline void setZ (const uint16_t& rz) {
        this->rz = rz;
    }

    inline void setPC (const uint16_t& rpc) {
        this->rpc = rpc;
    }

    inline void setSP (const uint16_t& rsp) {
        this->rsp = rsp;
    }

    inline void setEX (const uint16_t& rex) {
        this->rex = rex;
    }

    inline void setIA (const uint16_t& ria) {
        this->ria = ria;
    }

    inline const uint16_t& getA() const {
        return ra;
    }

    inline const uint16_t& getB() const {
        return rb;
    }

    inline const uint16_t& getC() const {
        return rc;
    }

    inline const uint16_t& getI() const {
        return ri;
    }

    inline const uint16_t& getJ() const {
        return rj;
    }

    inline const uint16_t& getX() const {
        return rx;
    }

    inline const uint16_t& getY() const {
        return ry;
    }

    inline const uint16_t& getZ() const {
        return rz;
    }

    inline const uint16_t& getPC() const {
        return rpc;
    }

    inline const uint16_t& getSP() const {
        return rsp;
    }

    inline const uint16_t& getEX() const {
        return rex;
    }

    inline const uint16_t& getIA() const {
        return ria;
    }

    // pretty dump

    /**
     * @brief Generates a pretty print dump of registers values
     */
    std::string dumpRegisters();

    /**
     * @brief Generates a pretty HEX print dump of a RAM region
     */
    std::string dumpRam (uint16_t init = 0, uint16_t end = 0);

protected:

private:
    uint16_t ra, rb, rc, rx, ry, rz , ri, rj, rex, rpc, ria, rsp; /// Registers
    uint16_t* ram; /// RAM

    uint16_t* register_table[0x1E];

    inline int realStep();

    inline void triggerInterrupt (uint16_t msg);
    inline void handleInterrupt (uint16_t msg);
    inline void handleHWInterrupts();
    inline void tickHardware();

    bool int_queueing;  /// Queue interrupts
    bool skipping_flag; /// Skiping next instruccion ?
    bool on_fire;         /// HCF

    /* hardware: */
    std::vector<std::shared_ptr<IHardware>> attached_hardware;

    /* interrupt queue: */
    std::deque<uint16_t> int_queue;

    int wait_cycles;    // How many cycles need to wait to finish a instrucction
    uint64_t tot_cycles;

};

/**
 * Hardware device base class
 */
class IHardware {
public:

    IHardware() : cpu(NULL), index(-1)  { };
    virtual ~IHardware() {};

    virtual uint32_t getId() const = 0;             /// Hardware ID
    virtual uint16_t getRevision() const = 0;       /// Hardware Revision
    virtual uint32_t getManufacturer() const = 0;   /// Hardware Manufacturer

    /**
     * @brief Attach the Hardware device to the CPU
     * @param cpu Ptr to the CPU
     */
    virtual void attachTo (DCPU* cpu, size_t index) {
        this->cpu = cpu;
        this->index = index;
    }

    /**
     * @brief Detachs from the CPU
     */
    virtual void detach() {
        this->cpu = NULL;
    }

    /**
     * @brief Checks if need to trigger a interupt to the CPU
     * @param msg Ref. to the message
     * @return True if trigger a interrupt
    */
    virtual bool checkInterrupt (uint16_t &msg) {
        return false;
    }

    /**
     * @brief Handle a interrupt from DCP to Hardware
     * @return Number of cycles that DCPU waits
     */
    virtual unsigned handleInterrupt() = 0;

    /**
     * @brief Does a CPU Clock Tick
     */
    virtual void tick() = 0;

    /**
     * @brief Return attached Hardware Dev. Index
     */
    const size_t& getDevIndex() const { return index; }

protected:
    DCPU* cpu;
    size_t index;   /// Hardware Device index

};

} // END OF NAMESPACE

#endif // _DCPU_HPP_
<|endoftext|>


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

#ifndef HCKT_TREE_H
#define HCKT_TREE_H

#include <cassert>
#include <vector>
#include <bitset>
#include "lmemvector.hpp"

namespace hckt
{

template <typename ValueType>
class tree
{
protected:
    std::bitset<64>                    bitset;
    hckt::lmemvector<ValueType>        values;
    hckt::lmemvector<tree<ValueType>*> children;

    std::size_t get_children_position(const std::size_t position) const
    {
        assert(position >= 0 && position < 64);

        //lets avoid this.. we know it will be 0 regardless of ones set
        //plus we'll just have extra complexity lower down because
        //we can only shift by < width
        if(position == 0) {
            return 0;
        }

        //popcount / dont worry just believe
        std::uint64_t x = bitset.to_ullong() << (64 - position);

        constexpr std::uint64_t m1  = 0x5555555555555555;
        constexpr std::uint64_t m2  = 0x3333333333333333;
        constexpr std::uint64_t m4  = 0x0f0f0f0f0f0f0f0f;
        constexpr std::uint64_t h01 = 0x0101010101010101;

        x -= (x >> 1) & m1;
        x = (x & m2) + ((x >> 2) & m2);
        x = (x + (x >> 4)) & m4;

        return (x * h01) >> 56;
    }

public:
    tree() : bitset { 0 }, values { }, children { }
    {
    }

    ~tree()
    {
        collapse();
    }

    std::size_t calculate_memory_size() const
    {
        std::size_t size {
              sizeof(bitset)
            + sizeof(values)   + (values.capacity()   * sizeof(ValueType))
            + sizeof(children) + (children.capacity() * sizeof(tree<ValueType>*))
        };

        for(auto child : children) {
            size += child->calculate_memory_size();
        }

        return size;
    }

    /*
     * 2d get position
     * convert three part positions to memory location
     * as input: (left = 0 | right = 1) + (top = 0 | bottom = 2)
     *
     * result will be:
     * y1:x1:y2:x2:y3:x3
     *
     */
    static std::size_t get_position_2d(const std::size_t d1, const std::size_t d2, const std::size_t d3)
    {
        assert(d1 >= 0 && d1 < 4);
        assert(d2 >= 0 && d2 < 4);
        assert(d3 >= 0 && d3 < 4);

        return ((1 << 0) * ((d1 & 2) >> 1))
             + ((1 << 1) *  (d1 & 1))
             + ((1 << 2) * ((d2 & 2) >> 1))
             + ((1 << 3) *  (d2 & 1))
             + ((1 << 4) * ((d3 & 2) >> 1))
             + ((1 << 5) *  (d3 & 1));
    }

    static std::size_t get_x_2d(const std::size_t d1, const std::size_t d2, const std::size_t d3)
    {
        assert(d1 >= 0 && d1 < 4);
        assert(d2 >= 0 && d2 < 4);
        assert(d3 >= 0 && d3 < 4);

        return ((d1 & 1) << 0) + ((d2 & 1) << 1) + ((d3 & 1) << 2);
    }

    static std::size_t get_y_2d(const std::size_t d1, const std::size_t d2, const std::size_t d3)
    {
        assert(d1 >= 0 && d1 < 4);
        assert(d2 >= 0 && d2 < 4);
        assert(d3 >= 0 && d3 < 4);

        return ((d1 & 2) >> 1 << 0) + ((d2 & 2) >> 1 << 1) + ((d3 & 2) >> 1 << 2);
    }

    /*
     * 3d get position
     * convert two part positions to memory location
     * as input: (left = 0 | right = 1) + (top = 0 | bottom = 2) + (in = 0 | out = 4)
     *
     * result will be:
     * z1:y1:x1:z2:y2:x2
     *
     */
    static std::size_t get_position_3d(const std::size_t d1, const std::size_t d2)
    {
        assert(d1 >= 0 && d1 < 8);
        assert(d2 >= 0 && d2 < 8);

        return ((1 << 0) * ((d1 & 4) >> 2))
             + ((1 << 1) * ((d1 & 2) >> 1))
             + ((1 << 2) *  (d1 & 1))
             + ((1 << 3) * ((d2 & 4) >> 2))
             + ((1 << 4) * ((d2 & 2) >> 1))
             + ((1 << 5) *  (d2 & 1));
    }

    static std::size_t get_x_3d(const std::size_t d1, const std::size_t d2)
    {
        assert(d1 >= 0 && d1 < 8);
        assert(d2 >= 0 && d2 < 8);

        return ((d1 & 1) << 0) + ((d2 & 1) << 1);
    }

    static std::size_t get_y_3d(const std::size_t d1, const std::size_t d2)
    {
        assert(d1 >= 0 && d1 < 8);
        assert(d2 >= 0 && d2 < 8);

        return ((d1 & 2) >> 1 << 0) + ((d2 & 2) >> 1 << 1);
    }

    static std::size_t get_z_3d(const std::size_t d1, const std::size_t d2)
    {
        assert(d1 >= 0 && d1 < 8);
        assert(d2 >= 0 && d2 < 8);

        return ((d1 & 4) >> 2 << 0) + ((d2 & 4) >> 2 << 1);
    }

    /*
     * check if we have any children
     */
    bool empty() const
    {
        return bitset.none();
    }

    /*
     * destroy children
     */
    void collapse()
    {
        for(auto child : children) {
            child->collapse();
        }

        children.clear();
        values.clear();
        bitset.reset();
    }

    /*
     * insert an item into position of tree
     * position should be result of get_position
     */
    void insert(const std::size_t position, const ValueType value)
    {
        const std::size_t cpos { get_children_position(position) };
        assert(cpos >= 0 && cpos < 64);

        children.insert(cpos, new tree<ValueType>());
        values.insert(cpos, value);
        bitset.set(position);
    }

    /*
     * removes an item from tree
     * position should be result of get_position
     */
    void remove(const std::size_t position)
    {
        const std::size_t cpos { get_children_position(position) };
        assert(cpos >= 0 && cpos < 64);

        children[cpos]->collapse();
        children.erase(cpos);
        values.erase(cpos);
        bitset.reset(position);
    }

    /*
     * get child node
     * position should be result of get_position
     */
    tree<ValueType> * child(const std::size_t position) const
    {
        const std::size_t cpos { get_children_position(position) };
        assert(cpos >= 0 && cpos < 64);

        return children[cpos];
    }

    /*
     * sets node to specific value
     * note: this does not check whether a value has been inserted here yet
     * position should be result of get_position
     */
    void set_value(const std::size_t position, const ValueType value)
    {
        const std::size_t cpos { get_children_position(position) };
        assert(cpos >= 0 && cpos < 64);

        values[cpos] = value;
    }

    /*
     * gets value from specific position
     * note: this does not check whether a value has been inserted here yet
     * position should be result of get_position
     */
    ValueType get_value(const std::size_t position) const
    {
        const std::size_t cpos { get_children_position(position) };
        assert(cpos >= 0 && cpos < 64);

        return values[cpos];
    }
};

};

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

#ifndef HCKT_TREE_H
#define HCKT_TREE_H

#include <cassert>
#include <vector>
#include <bitset>
#include "lmemvector.hpp"

namespace hckt
{

template <typename ValueType>
class tree
{
protected:
    std::bitset<64>                    bitset;
    hckt::lmemvector<ValueType>        values;
    hckt::lmemvector<tree<ValueType>*> children;

    std::size_t get_children_position(const std::size_t position) const
    {
        assert(position >= 0 && position < 64);

        //lets avoid this.. we know it will be 0 regardless of ones set
        //plus we'll just have extra complexity lower down because
        //we can only shift by < width
        if(position == 0) {
            return 0;
        }

        //popcount / dont worry just believe
        std::uint64_t x = bitset.to_ullong() << (64 - position);

        constexpr std::uint64_t m1  = 0x5555555555555555;
        constexpr std::uint64_t m2  = 0x3333333333333333;
        constexpr std::uint64_t m4  = 0x0f0f0f0f0f0f0f0f;
        constexpr std::uint64_t h01 = 0x0101010101010101;

        x -= (x >> 1) & m1;
        x = (x & m2) + ((x >> 2) & m2);
        x = (x + (x >> 4)) & m4;

        return (x * h01) >> 56;
    }

public:
    tree() : bitset { 0 }, values { }, children { }
    {
    }

    ~tree()
    {
        collapse();
    }

    std::size_t calculate_memory_size() const
    {
        std::size_t size {
              sizeof(bitset)
            + sizeof(values)   + (values.capacity()   * sizeof(ValueType))
            + sizeof(children) + (children.capacity() * sizeof(tree<ValueType>*))
        };

        for(auto child : children) {
            size += child->calculate_memory_size();
        }

        return size;
    }

    std::size_t calculate_children_amount() const
    {
        std::size_t amount { bitset.count() };

        for(auto child : children) {
            amount += child->calculate_children_amount();
        }

        return amount;
    }

    /*
     * 2d get position
     * convert three part positions to memory location
     * as input: (left = 0 | right = 1) + (top = 0 | bottom = 2)
     *
     * result will be:
     * y1:x1:y2:x2:y3:x3
     *
     */
    static std::size_t get_position_2d(const std::size_t d1, const std::size_t d2, const std::size_t d3)
    {
        assert(d1 >= 0 && d1 < 4);
        assert(d2 >= 0 && d2 < 4);
        assert(d3 >= 0 && d3 < 4);

        return ((1 << 0) * ((d1 & 2) >> 1))
             + ((1 << 1) *  (d1 & 1))
             + ((1 << 2) * ((d2 & 2) >> 1))
             + ((1 << 3) *  (d2 & 1))
             + ((1 << 4) * ((d3 & 2) >> 1))
             + ((1 << 5) *  (d3 & 1));
    }

    static std::size_t get_x_2d(const std::size_t d1, const std::size_t d2, const std::size_t d3)
    {
        assert(d1 >= 0 && d1 < 4);
        assert(d2 >= 0 && d2 < 4);
        assert(d3 >= 0 && d3 < 4);

        return ((d1 & 1) << 0) + ((d2 & 1) << 1) + ((d3 & 1) << 2);
    }

    static std::size_t get_y_2d(const std::size_t d1, const std::size_t d2, const std::size_t d3)
    {
        assert(d1 >= 0 && d1 < 4);
        assert(d2 >= 0 && d2 < 4);
        assert(d3 >= 0 && d3 < 4);

        return ((d1 & 2) >> 1 << 0) + ((d2 & 2) >> 1 << 1) + ((d3 & 2) >> 1 << 2);
    }

    /*
     * 3d get position
     * convert two part positions to memory location
     * as input: (left = 0 | right = 1) + (top = 0 | bottom = 2) + (in = 0 | out = 4)
     *
     * result will be:
     * z1:y1:x1:z2:y2:x2
     *
     */
    static std::size_t get_position_3d(const std::size_t d1, const std::size_t d2)
    {
        assert(d1 >= 0 && d1 < 8);
        assert(d2 >= 0 && d2 < 8);

        return ((1 << 0) * ((d1 & 4) >> 2))
             + ((1 << 1) * ((d1 & 2) >> 1))
             + ((1 << 2) *  (d1 & 1))
             + ((1 << 3) * ((d2 & 4) >> 2))
             + ((1 << 4) * ((d2 & 2) >> 1))
             + ((1 << 5) *  (d2 & 1));
    }

    static std::size_t get_x_3d(const std::size_t d1, const std::size_t d2)
    {
        assert(d1 >= 0 && d1 < 8);
        assert(d2 >= 0 && d2 < 8);

        return ((d1 & 1) << 0) + ((d2 & 1) << 1);
    }

    static std::size_t get_y_3d(const std::size_t d1, const std::size_t d2)
    {
        assert(d1 >= 0 && d1 < 8);
        assert(d2 >= 0 && d2 < 8);

        return ((d1 & 2) >> 1 << 0) + ((d2 & 2) >> 1 << 1);
    }

    static std::size_t get_z_3d(const std::size_t d1, const std::size_t d2)
    {
        assert(d1 >= 0 && d1 < 8);
        assert(d2 >= 0 && d2 < 8);

        return ((d1 & 4) >> 2 << 0) + ((d2 & 4) >> 2 << 1);
    }

    /*
     * check if we have any children
     */
    bool empty() const
    {
        return bitset.none();
    }

    /*
     * destroy children
     */
    void collapse()
    {
        for(auto child : children) {
            child->collapse();
        }

        children.clear();
        values.clear();
        bitset.reset();
    }

    /*
     * insert an item into position of tree
     * position should be result of get_position
     */
    void insert(const std::size_t position, const ValueType value)
    {
        const std::size_t cpos { get_children_position(position) };
        assert(cpos >= 0 && cpos < 64);

        children.insert(cpos, new tree<ValueType>());
        values.insert(cpos, value);
        bitset.set(position);
    }

    /*
     * removes an item from tree
     * position should be result of get_position
     */
    void remove(const std::size_t position)
    {
        const std::size_t cpos { get_children_position(position) };
        assert(cpos >= 0 && cpos < 64);

        children[cpos]->collapse();
        children.erase(cpos);
        values.erase(cpos);
        bitset.reset(position);
    }

    /*
     * get child node
     * position should be result of get_position
     */
    tree<ValueType> * child(const std::size_t position) const
    {
        const std::size_t cpos { get_children_position(position) };
        assert(cpos >= 0 && cpos < 64);

        return children[cpos];
    }

    /*
     * sets node to specific value
     * note: this does not check whether a value has been inserted here yet
     * position should be result of get_position
     */
    void set_value(const std::size_t position, const ValueType value)
    {
        const std::size_t cpos { get_children_position(position) };
        assert(cpos >= 0 && cpos < 64);

        values[cpos] = value;
    }

    /*
     * gets value from specific position
     * note: this does not check whether a value has been inserted here yet
     * position should be result of get_position
     */
    ValueType get_value(const std::size_t position) const
    {
        const std::size_t cpos { get_children_position(position) };
        assert(cpos >= 0 && cpos < 64);

        return values[cpos];
    }
};

};

#endif
<|endoftext|>


<commit_before>
#include <fstream>
#include <iostream>

using namespace std;

template <class T>
class Tree
{
private:
	struct Node

	{
		T value_;
		Node *left;
		Node *right;
		Node() {};
		Node(const T value) : value_(value) { };
		~Node() {};
		void show(ostream &out, const int level) const;
	};

	Node *root, *null_tr;
	void null_tree(Node *tr_)
	{
		if (!tr_) return;
		if (tr_->left)
		{
			null_tree(tr_->left);
			tr_->left = nullptr;
		}
		if (tr_->right)
		{
			null_tree(tr_->right);
			tr_->right = nullptr;
		}
		delete tr_;
	}
	Node *  find_(const T &value)
	{

		Node *tr = root;
		while (tr)
		{
		       if (tr->value_ != value)
		{
			if (value < tr->value_)
				tr = tr->left;
			else tr = tr->right;
		}
			else break;
		}
		if (!tr) return null_tr;
		else return tr;
	}
	void add_node(Node *&add_n, T value)
	{
		add_n = new Node(value);
		add_n->left = nullptr;
		add_n->right = nullptr;

	}
	Node* add_(const T &value, Node * tr = 0)
	{
		if (!root)
		{
			root = new Node(value);
			root->left = nullptr;
			root->right = nullptr;
			return root;
		}
		if (!tr) tr = root;
		if ((tr) && (tr->value_ != value))

		{
			if (value < tr->value_)

			{
				if (tr->left)
					add_(value, tr->left);
				else
				{
					add_node(tr->left, value);
					return tr->left;
				}
			}

			else
			{
				if (tr->right)
					add_(value, tr->right);
				else
				{
					add_node(tr->right, value);
					return tr->right;
				}
			}
		}
		return 0;
	}
int count(Node* tr)
	{
		if (!tr) return 0;
			int l=0, r=0;
		if (tr->left) l = count(tr->left);
		if (tr->right) r = count(tr->right);
		return l + r + 1;
	}
void print_pre(const Node * tr, std::ofstream &file) const
	{
		if (!tr) return;
		file << tr->value_ << "  ";
		if (tr->left)
			print_pre(tr->left, file);
		if (tr->right)
			print_pre(tr->right, file);
	}
public:
	Tree()
	{
		root = nullptr;
		null_tr = nullptr;
	};
	~Tree()
	{
		null_tree(root);
		null_tree(null_tr);
	};
	Node* tree_one ()
	{
		return root;
	};
	void file_tree(char* name);
	bool add(const T &value);
	bool find(const T &value);
	void print(ostream &out) const;
	int count_();
	void pr(char* name);
};
template <class T>
void Tree<T>:: pr(char* name)
{
		ofstream file(name);
		if (file.is_open())
		{
			file << count_()<<" ";
				print_pre(root, file);

			file.close();
		}
}
template <class T>
int Tree<T>:: count_()
{
		return count(root);
}
template <class T>
void  Tree<T>::print(ostream &out) const
{
	root->show(out, 0);
}
template <class T>
void Tree<T>::Node::show(ostream &out, const int level) const
{
	const Node *tr = this;
	if (tr) tr->right->show(out, level + 1);
	for (int i = 0; i<level; i++)
		out << "   ";
	if (tr) out << tr->value_ << endl;
	else out << "End" << endl;
	if (tr) tr->left->show(out, level + 1);
}
template <class T>
bool Tree<T>::add(const T &value)
{
	Node *tr = add_(value);
	if (tr) return true;
	else    return false;
}
template <class T>
void Tree<T>::file_tree(char* name)
{
	ifstream file(name);
	if (file.is_open())
	{
		int i_max;
		file >> i_max;
		for (int i = 0; i < i_max; ++i)
		{
			T node;
			file >> node;
			add(node);
		}
		file.close();
	}
}
template <class T>
bool Tree<T>::find(const T &value)
{
	Node *tr = find_(value);
	if (tr) return true;
	else    return false;
}
<commit_msg>Update tree.hpp<commit_after>
#include <fstream>
#include <iostream>

using namespace std;

template <class T>
class Tree
{
private:
	struct Node

	{
		T value_;
		Node *left;
		Node *right;
		Node() {};
		Node(const T value) : value_(value) { };
		~Node() {};
		void show(ostream &out, const int level) const;
	};

	Node *root, *null_tr;
	void null_tree(Node *tr_)
	{
		if (!tr_) return;
		if (tr_->left)
		{
			null_tree(tr_->left);
			tr_->left = nullptr;
		}
		if (tr_->right)
		{
			null_tree(tr_->right);
			tr_->right = nullptr;
		}
		delete tr_;
	}
	Node *  find_(const T &value) const
	{

		Node *tr = root;
		while (tr)
		{
		       if (tr->value_ != value)
		{
			if (value < tr->value_)
				tr = tr->left;
			else tr = tr->right;
		}
			else break;
		}
		if (!tr) return null_tr;
		else return tr;
	}
	void add_node(Node *&add_n, T value)
	{
		add_n = new Node(value);
		add_n->left = nullptr;
		add_n->right = nullptr;

	}
	Node* add_(const T &value, Node * tr = 0)
	{
		if (!root)
		{
			root = new Node(value);
			root->left = nullptr;
			root->right = nullptr;
			return root;
		}
		if (!tr) tr = root;
		if ((tr) && (tr->value_ != value))

		{
			if (value < tr->value_)

			{
				if (tr->left)
					add_(value, tr->left);
				else
				{
					add_node(tr->left, value);
					return tr->left;
				}
			}

			else
			{
				if (tr->right)
					add_(value, tr->right);
				else
				{
					add_node(tr->right, value);
					return tr->right;
				}
			}
		}
		return 0;
	}
int count(Node* tr)
	{
		if (!tr) return 0;
			int l=0, r=0;
		if (tr->left) l = count(tr->left);
		if (tr->right) r = count(tr->right);
		return l + r + 1;
	}
void print_pre(const Node * tr, std::ofstream &file) const
	{
		if (!tr) return;
		file << tr->value_ << "  ";
		if (tr->left)
			print_pre(tr->left, file);
		if (tr->right)
			print_pre(tr->right, file);
	}
public:
	Tree()
	{
		root = nullptr;
		null_tr = nullptr;
	};
	~Tree()
	{
		null_tree(root);
		null_tree(null_tr);
	};
	Node* tree_one ()
	{
		return root;
	};
	void file_tree(char* name);
	bool add(const T &value);
	bool find(const T &value);
	void print(ostream &out) const;
	int count_();
	void pr(char* name);
};
template <class T>
void Tree<T>:: pr(char* name)
{
		ofstream file(name);
		if (file.is_open())
		{
			file << count_()<<" ";
				print_pre(root, file);

			file.close();
		}
}
template <class T>
int Tree<T>:: count_()
{
		return count(root);
}
template <class T>
void  Tree<T>::print(ostream &out) const
{
	root->show(out, 0);
}
template <class T>
void Tree<T>::Node::show(ostream &out, const int level) const
{
	const Node *tr = this;
	if (tr) tr->right->show(out, level + 1);
	for (int i = 0; i<level; i++)
		out << "   ";
	if (tr) out << tr->value_ << endl;
	else out << "End" << endl;
	if (tr) tr->left->show(out, level + 1);
}
template <class T>
bool Tree<T>::add(const T &value)
{
	Node *tr = add_(value);
	if (tr) return true;
	else    return false;
}
template <class T>
void Tree<T>::file_tree(char* name)
{
	ifstream file(name);
	if (file.is_open())
	{
		int i_max;
		file >> i_max;
		for (int i = 0; i < i_max; ++i)
		{
			T node;
			file >> node;
			add(node);
		}
		file.close();
	}
}
template <class T>
bool Tree<T>::find(const T &value)
{
	Node *tr = find_(value);
	if (tr) return true;
	else    return false;
}
<|endoftext|>