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

#include "chrome/browser/options_window.h"

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/scoped_ptr.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/chromeos/options/internet_page_view.h"
#include "chrome/browser/chromeos/options/system_page_view.h"
#include "chrome/browser/gtk/options/advanced_page_gtk.h"
#include "chrome/browser/gtk/options/content_page_gtk.h"
#include "chrome/browser/gtk/options/general_page_gtk.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/window_sizer.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/pref_names.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "views/controls/native/native_view_host.h"
#include "views/controls/tabbed_pane/native_tabbed_pane_gtk.h"
#include "views/controls/tabbed_pane/tabbed_pane.h"
#include "views/widget/root_view.h"
#include "views/window/dialog_delegate.h"
#include "views/window/window.h"
#include "views/window/window_gtk.h"

namespace chromeos {

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowView
//
//  The contents of the Options dialog window.
//
class OptionsWindowView : public views::View,
                          public views::DialogDelegate,
                          public views::TabbedPane::Listener {
 public:
  static const int kDialogPadding;
  static const SkColor kDialogBackground;
  static OptionsWindowView* instance_;

  explicit OptionsWindowView(Profile* profile);
  virtual ~OptionsWindowView();

  // Shows the Tab corresponding to the specified OptionsPage.
  void ShowOptionsPage(OptionsPage page, OptionsGroup highlight_group);

  // views::DialogDelegate implementation:
  virtual int GetDialogButtons() const {
    return 0;
  }
  virtual std::wstring GetWindowTitle() const;
  virtual void WindowClosing();
  virtual bool Cancel();
  virtual views::View* GetContentsView();
  virtual bool ShouldShowClientEdge() const {
    return false;
  }

  // views::TabbedPane::Listener implementation:
  virtual void TabSelectedAt(int index);

  // views::View overrides:
  virtual void Layout();
  virtual gfx::Size GetPreferredSize();

 protected:
  // views::View overrides:
  virtual void ViewHierarchyChanged(bool is_add,
                                    views::View* parent,
                                    views::View* child);
 private:
  // Init the assorted Tabbed pages
  void Init();

  // Returns the currently selected OptionsPageView.
  OptionsPageView* GetCurrentOptionsPageView() const;

  // Flag of whether we are fully initialized.
  bool initialized_;

  // The Tab view that contains all of the options pages.
  views::TabbedPane* tabs_;

  // The Profile associated with these options.
  Profile* profile_;

  // Native Gtk options pages.
  GeneralPageGtk general_page_;
  ContentPageGtk content_page_;
  AdvancedPageGtk advanced_page_;

  // The last page the user was on when they opened the Options window.
  IntegerPrefMember last_selected_page_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(OptionsWindowView);
};

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowView, public:

// No dialog padding.
const int OptionsWindowView::kDialogPadding = 0;

// Shaded frame color that matches the rendered frame. It's the result
// of SRC_OVER frame top center image on top of frame color.
const SkColor OptionsWindowView::kDialogBackground =
    SkColorSetRGB(0x4E, 0x7D, 0xD0);

// Live instance of the options view.
OptionsWindowView* OptionsWindowView::instance_ = NULL;

OptionsWindowView::OptionsWindowView(Profile* profile)
      // Always show preferences for the original profile. Most state when off
      // the record comes from the original profile, but we explicitly use
      // the original profile to avoid potential problems.
    : initialized_(false),
      tabs_(NULL),
      profile_(profile->GetOriginalProfile()),
      general_page_(profile_),
      content_page_(profile_),
      advanced_page_(profile_) {
  // We don't need to observe changes in this value.
  last_selected_page_.Init(prefs::kOptionsWindowLastTabIndex,
                           g_browser_process->local_state(), NULL);

  set_background(views::Background::CreateSolidBackground(kDialogBackground));
}

OptionsWindowView::~OptionsWindowView() {
}

void OptionsWindowView::ShowOptionsPage(OptionsPage page,
                                        OptionsGroup highlight_group) {
  // This will show invisible windows and bring visible windows to the front.
  window()->Show();

  // Show all controls in tab after tab's size is allocated. We have
  // to do this after size allocation otherwise WrapLabelAtAllocationHack
  // in ContentPageGtk would break.
  GtkWidget* notebook = static_cast<views::NativeTabbedPaneGtk*>(
      tabs_->native_wrapper())->native_view();
  gtk_widget_show_all(notebook);

  if (page == OPTIONS_PAGE_DEFAULT) {
    // Remember the last visited page from local state.
    page = static_cast<OptionsPage>(last_selected_page_.GetValue());
    if (page == OPTIONS_PAGE_DEFAULT)
      page = OPTIONS_PAGE_GENERAL;
  }
  // If the page number is out of bounds, reset to the first tab.
  if (page < 0 || page >= tabs_->GetTabCount())
    page = OPTIONS_PAGE_GENERAL;

  tabs_->SelectTabAt(static_cast<int>(page));

  // TODO(xiyuan): set highlight_group
}

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowView, views::DialogDelegate implementation:

std::wstring OptionsWindowView::GetWindowTitle() const {
  return l10n_util::GetStringF(IDS_OPTIONS_DIALOG_TITLE,
                               l10n_util::GetString(IDS_PRODUCT_NAME));
}

void OptionsWindowView::WindowClosing() {
  // Clear the static instance so that the next time ShowOptionsWindow() is
  // called a new window is opened.
  instance_ = NULL;
}

bool OptionsWindowView::Cancel() {
  return GetCurrentOptionsPageView()->CanClose();
}

views::View* OptionsWindowView::GetContentsView() {
  return this;
}

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowView, views::TabbedPane::Listener implementation:

void OptionsWindowView::TabSelectedAt(int index) {
  if (!initialized_)
    return;

  DCHECK(index > OPTIONS_PAGE_DEFAULT && index < OPTIONS_PAGE_COUNT);
  last_selected_page_.SetValue(index);
}

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowView, views::View overrides:

void OptionsWindowView::Layout() {
  tabs_->SetBounds(kDialogPadding, kDialogPadding,
                   width() - (2 * kDialogPadding),
                   height() - (2 * kDialogPadding));
}

gfx::Size OptionsWindowView::GetPreferredSize() {
  return gfx::Size(views::Window::GetLocalizedContentsSize(
      IDS_OPTIONS_DIALOG_WIDTH_CHARS,
      IDS_OPTIONS_DIALOG_HEIGHT_LINES));
}

void OptionsWindowView::ViewHierarchyChanged(bool is_add,
                                             views::View* parent,
                                             views::View* child) {
  // Can't init before we're inserted into a Container, because we require a
  // HWND to parent native child controls to.
  if (is_add && child == this)
    Init();
}

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowView, private:

void OptionsWindowView::Init() {
  tabs_ = new views::TabbedPane;
  tabs_->SetListener(this);
  AddChildView(tabs_);

  GtkWidget* notebook = static_cast<views::NativeTabbedPaneGtk*>(
      tabs_->native_wrapper())->native_view();

  // Set vertical padding of tab header.
  gtk_notebook_set_tab_vborder(GTK_NOTEBOOK(notebook), 5);

  // Set a name for notebook. Note that the name is also used in theme engine
  // to apply specific drawings for this widget.
  gtk_widget_set_name(GTK_WIDGET(notebook), "chromeos-options-tab");

  // Setup tab pages.
  int tab_index = 0;

  SystemPageView* system_page = new SystemPageView(profile_);
  system_page->set_background(views::Background::CreateSolidBackground(
      SK_ColorWHITE));
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_OPTIONS_SYSTEM_TAB_LABEL),
                       system_page, false);

  InternetPageView* internet_page = new InternetPageView(profile_);
  internet_page->set_background(views::Background::CreateSolidBackground(
      SK_ColorWHITE));
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_OPTIONS_INTERNET_TAB_LABEL),
                       internet_page, false);

  views::NativeViewHost* general_page_view = new views::NativeViewHost();
  general_page_view->set_background(views::Background::CreateSolidBackground(
      SK_ColorWHITE));
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_OPTIONS_GENERAL_TAB_LABEL),
                       general_page_view, false);
  general_page_view->Attach(general_page_.get_page_widget());

  views::NativeViewHost* content_page_view = new views::NativeViewHost();
  content_page_view->set_background(views::Background::CreateSolidBackground(
      SK_ColorWHITE));
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_OPTIONS_CONTENT_TAB_LABEL),
                       content_page_view, false);
  content_page_view->Attach(content_page_.get_page_widget());

  views::NativeViewHost* advanced_page_view = new views::NativeViewHost();
  advanced_page_view->set_background(views::Background::CreateSolidBackground(
      SK_ColorWHITE));
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_OPTIONS_ADVANCED_TAB_LABEL),
                       advanced_page_view, false);
  advanced_page_view->Attach(advanced_page_.get_page_widget());

  DCHECK(tabs_->GetTabCount() == OPTIONS_PAGE_COUNT);

  initialized_ = true;
}

OptionsPageView* OptionsWindowView::GetCurrentOptionsPageView() const {
  return static_cast<OptionsPageView*>(tabs_->GetSelectedTab());
}

gfx::NativeWindow GetOptionsViewParent() {
  if (Browser* b = BrowserList::GetLastActive())
    return b->window()->GetNativeHandle();

  return NULL;
}

};  // namespace chromeos

///////////////////////////////////////////////////////////////////////////////
// Factory/finder method:

void ShowOptionsWindow(OptionsPage page,
                       OptionsGroup highlight_group,
                       Profile* profile) {
  DCHECK(profile);

  using chromeos::OptionsWindowView;

  // If there's already an existing options window, close it and create
  // a new one for the current active browser.
  if (OptionsWindowView::instance_)
    OptionsWindowView::instance_->window()->Close();

  OptionsWindowView::instance_ = new OptionsWindowView(profile);
  views::Window::CreateChromeWindow(chromeos::GetOptionsViewParent(),
                                    gfx::Rect(),
                                    OptionsWindowView::instance_);

  OptionsWindowView::instance_->ShowOptionsPage(page, highlight_group);
}

<commit_msg>Fix a potential crash in ChromeOS options dialog.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/options_window.h"

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/scoped_ptr.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/chromeos/options/internet_page_view.h"
#include "chrome/browser/chromeos/options/system_page_view.h"
#include "chrome/browser/gtk/options/advanced_page_gtk.h"
#include "chrome/browser/gtk/options/content_page_gtk.h"
#include "chrome/browser/gtk/options/general_page_gtk.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/window_sizer.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/pref_names.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "views/controls/native/native_view_host.h"
#include "views/controls/tabbed_pane/native_tabbed_pane_gtk.h"
#include "views/controls/tabbed_pane/tabbed_pane.h"
#include "views/widget/root_view.h"
#include "views/window/dialog_delegate.h"
#include "views/window/window.h"
#include "views/window/window_gtk.h"

namespace chromeos {

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowView
//
//  The contents of the Options dialog window.
//
class OptionsWindowView : public views::View,
                          public views::DialogDelegate,
                          public views::TabbedPane::Listener {
 public:
  static const int kDialogPadding;
  static const SkColor kDialogBackground;
  static OptionsWindowView* instance_;

  explicit OptionsWindowView(Profile* profile);
  virtual ~OptionsWindowView();

  // Shows the Tab corresponding to the specified OptionsPage.
  void ShowOptionsPage(OptionsPage page, OptionsGroup highlight_group);

  // views::DialogDelegate implementation:
  virtual int GetDialogButtons() const {
    return 0;
  }
  virtual std::wstring GetWindowTitle() const;
  virtual void WindowClosing();
  virtual bool Cancel();
  virtual views::View* GetContentsView();
  virtual bool ShouldShowClientEdge() const {
    return false;
  }

  // views::TabbedPane::Listener implementation:
  virtual void TabSelectedAt(int index);

  // views::View overrides:
  virtual void Layout();
  virtual gfx::Size GetPreferredSize();

 protected:
  // views::View overrides:
  virtual void ViewHierarchyChanged(bool is_add,
                                    views::View* parent,
                                    views::View* child);
 private:
  // Init the assorted Tabbed pages
  void Init();

  // Returns the currently selected OptionsPageView.
  OptionsPageView* GetCurrentOptionsPageView() const;

  // Flag of whether we are fully initialized.
  bool initialized_;

  // The Tab view that contains all of the options pages.
  views::TabbedPane* tabs_;

  // The Profile associated with these options.
  Profile* profile_;

  // Native Gtk options pages.
  GeneralPageGtk general_page_;
  ContentPageGtk content_page_;
  AdvancedPageGtk advanced_page_;

  // The last page the user was on when they opened the Options window.
  IntegerPrefMember last_selected_page_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(OptionsWindowView);
};

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowView, public:

// No dialog padding.
const int OptionsWindowView::kDialogPadding = 0;

// Shaded frame color that matches the rendered frame. It's the result
// of SRC_OVER frame top center image on top of frame color.
const SkColor OptionsWindowView::kDialogBackground =
    SkColorSetRGB(0x4E, 0x7D, 0xD0);

// Live instance of the options view.
OptionsWindowView* OptionsWindowView::instance_ = NULL;

OptionsWindowView::OptionsWindowView(Profile* profile)
      // Always show preferences for the original profile. Most state when off
      // the record comes from the original profile, but we explicitly use
      // the original profile to avoid potential problems.
    : initialized_(false),
      tabs_(NULL),
      profile_(profile->GetOriginalProfile()),
      general_page_(profile_),
      content_page_(profile_),
      advanced_page_(profile_) {
  // We don't need to observe changes in this value.
  last_selected_page_.Init(prefs::kOptionsWindowLastTabIndex,
                           g_browser_process->local_state(), NULL);

  set_background(views::Background::CreateSolidBackground(kDialogBackground));
}

OptionsWindowView::~OptionsWindowView() {
}

void OptionsWindowView::ShowOptionsPage(OptionsPage page,
                                        OptionsGroup highlight_group) {
  // This will show invisible windows and bring visible windows to the front.
  window()->Show();

  // Show all controls in tab after tab's size is allocated. We have
  // to do this after size allocation otherwise WrapLabelAtAllocationHack
  // in ContentPageGtk would break.
  GtkWidget* notebook = static_cast<views::NativeTabbedPaneGtk*>(
      tabs_->native_wrapper())->native_view();
  gtk_widget_show_all(notebook);

  if (page == OPTIONS_PAGE_DEFAULT) {
    // Remember the last visited page from local state.
    page = static_cast<OptionsPage>(last_selected_page_.GetValue());
    if (page == OPTIONS_PAGE_DEFAULT)
      page = OPTIONS_PAGE_GENERAL;
  }
  // If the page number is out of bounds, reset to the first tab.
  if (page < 0 || page >= tabs_->GetTabCount())
    page = OPTIONS_PAGE_GENERAL;

  tabs_->SelectTabAt(static_cast<int>(page));

  // TODO(xiyuan): set highlight_group
}

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowView, views::DialogDelegate implementation:

std::wstring OptionsWindowView::GetWindowTitle() const {
  return l10n_util::GetStringF(IDS_OPTIONS_DIALOG_TITLE,
                               l10n_util::GetString(IDS_PRODUCT_NAME));
}

void OptionsWindowView::WindowClosing() {
  // Clear the static instance so that the next time ShowOptionsWindow() is
  // called a new window is opened.
  instance_ = NULL;
}

bool OptionsWindowView::Cancel() {
  OptionsPageView* selected_option_page = GetCurrentOptionsPageView();
  if (selected_option_page) {
    return selected_option_page->CanClose();
  } else {
    // Gtk option pages does not support CanClose.
    return true;
  }
}

views::View* OptionsWindowView::GetContentsView() {
  return this;
}

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowView, views::TabbedPane::Listener implementation:

void OptionsWindowView::TabSelectedAt(int index) {
  if (!initialized_)
    return;

  DCHECK(index > OPTIONS_PAGE_DEFAULT && index < OPTIONS_PAGE_COUNT);
  last_selected_page_.SetValue(index);
}

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowView, views::View overrides:

void OptionsWindowView::Layout() {
  tabs_->SetBounds(kDialogPadding, kDialogPadding,
                   width() - (2 * kDialogPadding),
                   height() - (2 * kDialogPadding));
}

gfx::Size OptionsWindowView::GetPreferredSize() {
  return gfx::Size(views::Window::GetLocalizedContentsSize(
      IDS_OPTIONS_DIALOG_WIDTH_CHARS,
      IDS_OPTIONS_DIALOG_HEIGHT_LINES));
}

void OptionsWindowView::ViewHierarchyChanged(bool is_add,
                                             views::View* parent,
                                             views::View* child) {
  // Can't init before we're inserted into a Container, because we require a
  // HWND to parent native child controls to.
  if (is_add && child == this)
    Init();
}

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowView, private:

void OptionsWindowView::Init() {
  tabs_ = new views::TabbedPane;
  tabs_->SetListener(this);
  AddChildView(tabs_);

  GtkWidget* notebook = static_cast<views::NativeTabbedPaneGtk*>(
      tabs_->native_wrapper())->native_view();

  // Set vertical padding of tab header.
  gtk_notebook_set_tab_vborder(GTK_NOTEBOOK(notebook), 5);

  // Set a name for notebook. Note that the name is also used in theme engine
  // to apply specific drawings for this widget.
  gtk_widget_set_name(GTK_WIDGET(notebook), "chromeos-options-tab");

  // Setup tab pages.
  int tab_index = 0;

  SystemPageView* system_page = new SystemPageView(profile_);
  system_page->set_background(views::Background::CreateSolidBackground(
      SK_ColorWHITE));
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_OPTIONS_SYSTEM_TAB_LABEL),
                       system_page, false);

  InternetPageView* internet_page = new InternetPageView(profile_);
  internet_page->set_background(views::Background::CreateSolidBackground(
      SK_ColorWHITE));
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_OPTIONS_INTERNET_TAB_LABEL),
                       internet_page, false);

  views::NativeViewHost* general_page_view = new views::NativeViewHost();
  general_page_view->set_background(views::Background::CreateSolidBackground(
      SK_ColorWHITE));
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_OPTIONS_GENERAL_TAB_LABEL),
                       general_page_view, false);
  general_page_view->Attach(general_page_.get_page_widget());

  views::NativeViewHost* content_page_view = new views::NativeViewHost();
  content_page_view->set_background(views::Background::CreateSolidBackground(
      SK_ColorWHITE));
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_OPTIONS_CONTENT_TAB_LABEL),
                       content_page_view, false);
  content_page_view->Attach(content_page_.get_page_widget());

  views::NativeViewHost* advanced_page_view = new views::NativeViewHost();
  advanced_page_view->set_background(views::Background::CreateSolidBackground(
      SK_ColorWHITE));
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_OPTIONS_ADVANCED_TAB_LABEL),
                       advanced_page_view, false);
  advanced_page_view->Attach(advanced_page_.get_page_widget());

  DCHECK(tabs_->GetTabCount() == OPTIONS_PAGE_COUNT);

  initialized_ = true;
}

OptionsPageView* OptionsWindowView::GetCurrentOptionsPageView() const {
  int selected_option_page = tabs_->GetSelectedTabIndex();
  if (selected_option_page < OPTIONS_PAGE_GENERAL) {
    return static_cast<OptionsPageView*>(tabs_->GetSelectedTab());
  } else {
    return NULL;
  }
}

gfx::NativeWindow GetOptionsViewParent() {
  if (Browser* b = BrowserList::GetLastActive())
    return b->window()->GetNativeHandle();

  return NULL;
}

};  // namespace chromeos

///////////////////////////////////////////////////////////////////////////////
// Factory/finder method:

void ShowOptionsWindow(OptionsPage page,
                       OptionsGroup highlight_group,
                       Profile* profile) {
  DCHECK(profile);

  using chromeos::OptionsWindowView;

  // If there's already an existing options window, close it and create
  // a new one for the current active browser.
  if (OptionsWindowView::instance_)
    OptionsWindowView::instance_->window()->Close();

  OptionsWindowView::instance_ = new OptionsWindowView(profile);
  views::Window::CreateChromeWindow(chromeos::GetOptionsViewParent(),
                                    gfx::Rect(),
                                    OptionsWindowView::instance_);

  OptionsWindowView::instance_->ShowOptionsPage(page, highlight_group);
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2004-2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Kevin Lim
 */

#include "base/intmath.hh"
#include "cpu/pred/tournament.hh"

TournamentBP::TournamentBP(unsigned _localPredictorSize,
                           unsigned _localCtrBits,
                           unsigned _localHistoryTableSize,
                           unsigned _localHistoryBits,
                           unsigned _globalPredictorSize,
                           unsigned _globalHistoryBits,
                           unsigned _globalCtrBits,
                           unsigned _choicePredictorSize,
                           unsigned _choiceCtrBits,
                           unsigned _instShiftAmt)
    : localPredictorSize(_localPredictorSize),
      localCtrBits(_localCtrBits),
      localHistoryTableSize(_localHistoryTableSize),
      localHistoryBits(_localHistoryBits),
      globalPredictorSize(_globalPredictorSize),
      globalCtrBits(_globalCtrBits),
      globalHistoryBits(_globalHistoryBits),
      choicePredictorSize(_globalPredictorSize),
      choiceCtrBits(_choiceCtrBits),
      instShiftAmt(_instShiftAmt)
{
    if (!isPowerOf2(localPredictorSize)) {
        fatal("Invalid local predictor size!\n");
    }

    //Setup the array of counters for the local predictor
    localCtrs.resize(localPredictorSize);

    for (int i = 0; i < localPredictorSize; ++i)
        localCtrs[i].setBits(localCtrBits);

    localPredictorMask = floorPow2(localPredictorSize) - 1;

    if (!isPowerOf2(localHistoryTableSize)) {
        fatal("Invalid local history table size!\n");
    }

    //Setup the history table for the local table
    localHistoryTable.resize(localHistoryTableSize);

    for (int i = 0; i < localHistoryTableSize; ++i)
        localHistoryTable[i] = 0;

    // Setup the local history mask
    localHistoryMask = (1 << localHistoryBits) - 1;

    if (!isPowerOf2(globalPredictorSize)) {
        fatal("Invalid global predictor size!\n");
    }

    //Setup the array of counters for the global predictor
    globalCtrs.resize(globalPredictorSize);

    for (int i = 0; i < globalPredictorSize; ++i)
        globalCtrs[i].setBits(globalCtrBits);

    //Clear the global history
    globalHistory = 0;
    // Setup the global history mask
    globalHistoryMask = (1 << globalHistoryBits) - 1;

    if (!isPowerOf2(choicePredictorSize)) {
        fatal("Invalid choice predictor size!\n");
    }

    //Setup the array of counters for the choice predictor
    choiceCtrs.resize(choicePredictorSize);

    for (int i = 0; i < choicePredictorSize; ++i)
        choiceCtrs[i].setBits(choiceCtrBits);

    // @todo: Allow for different thresholds between the predictors.
    threshold = (1 << (localCtrBits - 1)) - 1;
}

inline
unsigned
TournamentBP::calcLocHistIdx(Addr &branch_addr)
{
    // Get low order bits after removing instruction offset.
    return (branch_addr >> instShiftAmt) & (localHistoryTableSize - 1);
}

inline
void
TournamentBP::updateGlobalHistTaken()
{
    globalHistory = (globalHistory << 1) | 1;
    globalHistory = globalHistory & globalHistoryMask;
}

inline
void
TournamentBP::updateGlobalHistNotTaken()
{
    globalHistory = (globalHistory << 1);
    globalHistory = globalHistory & globalHistoryMask;
}

inline
void
TournamentBP::updateLocalHistTaken(unsigned local_history_idx)
{
    localHistoryTable[local_history_idx] =
        (localHistoryTable[local_history_idx] << 1) | 1;
}

inline
void
TournamentBP::updateLocalHistNotTaken(unsigned local_history_idx)
{
    localHistoryTable[local_history_idx] =
        (localHistoryTable[local_history_idx] << 1);
}

void
TournamentBP::BTBUpdate(Addr &branch_addr, void * &bp_history)
{
    unsigned local_history_idx = calcLocHistIdx(branch_addr);
    //Update Global History to Not Taken
    globalHistory = globalHistory & (globalHistoryMask - 1);
    //Update Local History to Not Taken
    localHistoryTable[local_history_idx] =
       localHistoryTable[local_history_idx] & (localPredictorMask - 1);
}

bool
TournamentBP::lookup(Addr &branch_addr, void * &bp_history)
{
    bool local_prediction;
    unsigned local_history_idx;
    unsigned local_predictor_idx;

    bool global_prediction;
    bool choice_prediction;

    //Lookup in the local predictor to get its branch prediction
    local_history_idx = calcLocHistIdx(branch_addr);
    local_predictor_idx = localHistoryTable[local_history_idx]
        & localPredictorMask;
    local_prediction = localCtrs[local_predictor_idx].read() > threshold;

    //Lookup in the global predictor to get its branch prediction
    global_prediction = globalCtrs[globalHistory].read() > threshold;

    //Lookup in the choice predictor to see which one to use
    choice_prediction = choiceCtrs[globalHistory].read() > threshold;

    // Create BPHistory and pass it back to be recorded.
    BPHistory *history = new BPHistory;
    history->globalHistory = globalHistory;
    history->localPredTaken = local_prediction;
    history->globalPredTaken = global_prediction;
    history->globalUsed = choice_prediction;
    history->localHistory = local_predictor_idx;
    bp_history = (void *)history;

    assert(globalHistory < globalPredictorSize &&
           local_history_idx < localHistoryTableSize &&
           local_predictor_idx < localPredictorSize);

    // Commented code is for doing speculative update of counters and
    // all histories.
    if (choice_prediction) {
        if (global_prediction) {
            updateGlobalHistTaken();
            updateLocalHistTaken(local_history_idx);
            return true;
        } else {
            updateGlobalHistNotTaken();
            updateLocalHistNotTaken(local_history_idx);
            return false;
        }
    } else {
        if (local_prediction) {
            updateGlobalHistTaken();
            updateLocalHistTaken(local_history_idx);
            return true;
        } else {
            updateGlobalHistNotTaken();
            updateLocalHistNotTaken(local_history_idx);
            return false;
        }
    }
}

void
TournamentBP::uncondBr(void * &bp_history)
{
    // Create BPHistory and pass it back to be recorded.
    BPHistory *history = new BPHistory;
    history->globalHistory = globalHistory;
    history->localPredTaken = true;
    history->globalPredTaken = true;
    history->globalUsed = true;
    history->localHistory = invalidPredictorIndex;
    bp_history = static_cast<void *>(history);

    updateGlobalHistTaken();
}

void
TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history,
                     bool squashed)
{
    unsigned local_history_idx;
    unsigned local_predictor_idx M5_VAR_USED;
    unsigned local_predictor_hist;

    // Get the local predictor's current prediction
    local_history_idx = calcLocHistIdx(branch_addr);
    local_predictor_hist = localHistoryTable[local_history_idx];
    local_predictor_idx = local_predictor_hist & localPredictorMask;

    if (bp_history) {
        BPHistory *history = static_cast<BPHistory *>(bp_history);
        // Update may also be called if the Branch target is incorrect even if
        // the prediction is correct. In that case do not update the counters.
        bool historyPred = false;
        unsigned old_local_pred_index = history->localHistory
                      & localPredictorMask;
        if (history->globalUsed) {
           historyPred = history->globalPredTaken;
        } else {
           historyPred = history->localPredTaken;
        }
        if (historyPred != taken || !squashed) {
            // Update the choice predictor to tell it which one was correct if
            // there was a prediction.
            if (history->localPredTaken != history->globalPredTaken) {
                 // If the local prediction matches the actual outcome,
                 // decerement the counter.  Otherwise increment the
                 // counter.
                 if (history->localPredTaken == taken) {
                     choiceCtrs[history->globalHistory].decrement();
                 } else if (history->globalPredTaken == taken) {
                     choiceCtrs[history->globalHistory].increment();
                 }

             }

             // Update the counters and local history with the proper
             // resolution of the branch.  Global history is updated
             // speculatively and restored upon squash() calls, so it does not
             // need to be updated.
             if (taken) {
                  globalCtrs[history->globalHistory].increment();
                  if (old_local_pred_index != invalidPredictorIndex) {
                          localCtrs[old_local_pred_index].increment();
                  }
             } else {
                  globalCtrs[history->globalHistory].decrement();
                  if (old_local_pred_index != invalidPredictorIndex) {
                          localCtrs[old_local_pred_index].decrement();
                  }
             }
        }
        if (squashed) {
             if (taken) {
                globalHistory = (history->globalHistory << 1) | 1;
                globalHistory = globalHistory & globalHistoryMask;
                if (old_local_pred_index != invalidPredictorIndex) {
                    localHistoryTable[old_local_pred_index] =
                     (history->localHistory << 1) | 1;
                }
             } else {
                globalHistory = (history->globalHistory << 1);
                globalHistory = globalHistory & globalHistoryMask;
                if (old_local_pred_index != invalidPredictorIndex) {
                     localHistoryTable[old_local_pred_index] =
                     history->localHistory << 1;
                }
             }

        }
        // We're done with this history, now delete it.
        delete history;

    }

    assert(globalHistory < globalPredictorSize &&
           local_history_idx < localHistoryTableSize &&
           local_predictor_idx < localPredictorSize);

}

void
TournamentBP::squash(void *bp_history)
{
    BPHistory *history = static_cast<BPHistory *>(bp_history);

    // Restore global history to state prior to this branch.
    globalHistory = history->globalHistory;

    // Delete this BPHistory now that we're done with it.
    delete history;
}

#ifdef DEBUG
int
TournamentBP::BPHistory::newCount = 0;
#endif
<commit_msg>o3: Fix a couple of issues with the local predictor.<commit_after>/*
 * Copyright (c) 2011 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2004-2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Kevin Lim
 */

#include "base/intmath.hh"
#include "cpu/pred/tournament.hh"

TournamentBP::TournamentBP(unsigned _localPredictorSize,
                           unsigned _localCtrBits,
                           unsigned _localHistoryTableSize,
                           unsigned _localHistoryBits,
                           unsigned _globalPredictorSize,
                           unsigned _globalHistoryBits,
                           unsigned _globalCtrBits,
                           unsigned _choicePredictorSize,
                           unsigned _choiceCtrBits,
                           unsigned _instShiftAmt)
    : localPredictorSize(_localPredictorSize),
      localCtrBits(_localCtrBits),
      localHistoryTableSize(_localHistoryTableSize),
      localHistoryBits(_localHistoryBits),
      globalPredictorSize(_globalPredictorSize),
      globalCtrBits(_globalCtrBits),
      globalHistoryBits(_globalHistoryBits),
      choicePredictorSize(_globalPredictorSize),
      choiceCtrBits(_choiceCtrBits),
      instShiftAmt(_instShiftAmt)
{
    if (!isPowerOf2(localPredictorSize)) {
        fatal("Invalid local predictor size!\n");
    }

    //Setup the array of counters for the local predictor
    localCtrs.resize(localPredictorSize);

    for (int i = 0; i < localPredictorSize; ++i)
        localCtrs[i].setBits(localCtrBits);

    localPredictorMask = floorPow2(localPredictorSize) - 1;

    if (!isPowerOf2(localHistoryTableSize)) {
        fatal("Invalid local history table size!\n");
    }

    //Setup the history table for the local table
    localHistoryTable.resize(localHistoryTableSize);

    for (int i = 0; i < localHistoryTableSize; ++i)
        localHistoryTable[i] = 0;

    // Setup the local history mask
    localHistoryMask = (1 << localHistoryBits) - 1;

    if (!isPowerOf2(globalPredictorSize)) {
        fatal("Invalid global predictor size!\n");
    }

    //Setup the array of counters for the global predictor
    globalCtrs.resize(globalPredictorSize);

    for (int i = 0; i < globalPredictorSize; ++i)
        globalCtrs[i].setBits(globalCtrBits);

    //Clear the global history
    globalHistory = 0;
    // Setup the global history mask
    globalHistoryMask = (1 << globalHistoryBits) - 1;

    if (!isPowerOf2(choicePredictorSize)) {
        fatal("Invalid choice predictor size!\n");
    }

    //Setup the array of counters for the choice predictor
    choiceCtrs.resize(choicePredictorSize);

    for (int i = 0; i < choicePredictorSize; ++i)
        choiceCtrs[i].setBits(choiceCtrBits);

    // @todo: Allow for different thresholds between the predictors.
    threshold = (1 << (localCtrBits - 1)) - 1;
}

inline
unsigned
TournamentBP::calcLocHistIdx(Addr &branch_addr)
{
    // Get low order bits after removing instruction offset.
    return (branch_addr >> instShiftAmt) & (localHistoryTableSize - 1);
}

inline
void
TournamentBP::updateGlobalHistTaken()
{
    globalHistory = (globalHistory << 1) | 1;
    globalHistory = globalHistory & globalHistoryMask;
}

inline
void
TournamentBP::updateGlobalHistNotTaken()
{
    globalHistory = (globalHistory << 1);
    globalHistory = globalHistory & globalHistoryMask;
}

inline
void
TournamentBP::updateLocalHistTaken(unsigned local_history_idx)
{
    localHistoryTable[local_history_idx] =
        (localHistoryTable[local_history_idx] << 1) | 1;
}

inline
void
TournamentBP::updateLocalHistNotTaken(unsigned local_history_idx)
{
    localHistoryTable[local_history_idx] =
        (localHistoryTable[local_history_idx] << 1);
}

void
TournamentBP::BTBUpdate(Addr &branch_addr, void * &bp_history)
{
    unsigned local_history_idx = calcLocHistIdx(branch_addr);
    //Update Global History to Not Taken
    globalHistory = globalHistory & (globalHistoryMask - 1);
    //Update Local History to Not Taken
    localHistoryTable[local_history_idx] =
       localHistoryTable[local_history_idx] & (localPredictorMask & ~ULL(1));
}

bool
TournamentBP::lookup(Addr &branch_addr, void * &bp_history)
{
    bool local_prediction;
    unsigned local_history_idx;
    unsigned local_predictor_idx;

    bool global_prediction;
    bool choice_prediction;

    //Lookup in the local predictor to get its branch prediction
    local_history_idx = calcLocHistIdx(branch_addr);
    local_predictor_idx = localHistoryTable[local_history_idx]
        & localPredictorMask;
    local_prediction = localCtrs[local_predictor_idx].read() > threshold;

    //Lookup in the global predictor to get its branch prediction
    global_prediction = globalCtrs[globalHistory].read() > threshold;

    //Lookup in the choice predictor to see which one to use
    choice_prediction = choiceCtrs[globalHistory].read() > threshold;

    // Create BPHistory and pass it back to be recorded.
    BPHistory *history = new BPHistory;
    history->globalHistory = globalHistory;
    history->localPredTaken = local_prediction;
    history->globalPredTaken = global_prediction;
    history->globalUsed = choice_prediction;
    history->localHistory = local_predictor_idx;
    bp_history = (void *)history;

    assert(globalHistory < globalPredictorSize &&
           local_history_idx < localHistoryTableSize &&
           local_predictor_idx < localPredictorSize);

    // Commented code is for doing speculative update of counters and
    // all histories.
    if (choice_prediction) {
        if (global_prediction) {
            updateGlobalHistTaken();
            updateLocalHistTaken(local_history_idx);
            return true;
        } else {
            updateGlobalHistNotTaken();
            updateLocalHistNotTaken(local_history_idx);
            return false;
        }
    } else {
        if (local_prediction) {
            updateGlobalHistTaken();
            updateLocalHistTaken(local_history_idx);
            return true;
        } else {
            updateGlobalHistNotTaken();
            updateLocalHistNotTaken(local_history_idx);
            return false;
        }
    }
}

void
TournamentBP::uncondBr(void * &bp_history)
{
    // Create BPHistory and pass it back to be recorded.
    BPHistory *history = new BPHistory;
    history->globalHistory = globalHistory;
    history->localPredTaken = true;
    history->globalPredTaken = true;
    history->globalUsed = true;
    history->localHistory = invalidPredictorIndex;
    bp_history = static_cast<void *>(history);

    updateGlobalHistTaken();
}

void
TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history,
                     bool squashed)
{
    unsigned local_history_idx;
    unsigned local_predictor_idx M5_VAR_USED;
    unsigned local_predictor_hist;

    // Get the local predictor's current prediction
    local_history_idx = calcLocHistIdx(branch_addr);
    local_predictor_hist = localHistoryTable[local_history_idx];
    local_predictor_idx = local_predictor_hist & localPredictorMask;

    if (bp_history) {
        BPHistory *history = static_cast<BPHistory *>(bp_history);
        // Update may also be called if the Branch target is incorrect even if
        // the prediction is correct. In that case do not update the counters.
        bool historyPred = false;
        unsigned old_local_pred_index = history->localHistory &
                localPredictorMask;

        bool old_local_pred_valid = history->localHistory !=
            invalidPredictorIndex;

        assert(old_local_pred_index < localPredictorSize);

        if (history->globalUsed) {
           historyPred = history->globalPredTaken;
        } else {
           historyPred = history->localPredTaken;
        }
        if (historyPred != taken || !squashed) {
            // Update the choice predictor to tell it which one was correct if
            // there was a prediction.
            if (history->localPredTaken != history->globalPredTaken) {
                 // If the local prediction matches the actual outcome,
                 // decerement the counter.  Otherwise increment the
                 // counter.
                 if (history->localPredTaken == taken) {
                     choiceCtrs[history->globalHistory].decrement();
                 } else if (history->globalPredTaken == taken) {
                     choiceCtrs[history->globalHistory].increment();
                 }

             }

             // Update the counters and local history with the proper
             // resolution of the branch.  Global history is updated
             // speculatively and restored upon squash() calls, so it does not
             // need to be updated.
             if (taken) {
                  globalCtrs[history->globalHistory].increment();
                  if (old_local_pred_valid) {
                          localCtrs[old_local_pred_index].increment();
                  }
             } else {
                  globalCtrs[history->globalHistory].decrement();
                  if (old_local_pred_valid) {
                          localCtrs[old_local_pred_index].decrement();
                  }
             }
        }
        if (squashed) {
             if (taken) {
                globalHistory = (history->globalHistory << 1) | 1;
                globalHistory = globalHistory & globalHistoryMask;
                if (old_local_pred_valid) {
                    localHistoryTable[local_history_idx] =
                     (history->localHistory << 1) | 1;
                }
             } else {
                globalHistory = (history->globalHistory << 1);
                globalHistory = globalHistory & globalHistoryMask;
                if (old_local_pred_valid) {
                     localHistoryTable[local_history_idx] =
                     history->localHistory << 1;
                }
             }

        }
        // We're done with this history, now delete it.
        delete history;

    }

    assert(globalHistory < globalPredictorSize &&
           local_history_idx < localHistoryTableSize &&
           local_predictor_idx < localPredictorSize);

}

void
TournamentBP::squash(void *bp_history)
{
    BPHistory *history = static_cast<BPHistory *>(bp_history);

    // Restore global history to state prior to this branch.
    globalHistory = history->globalHistory;

    // Delete this BPHistory now that we're done with it.
    delete history;
}

#ifdef DEBUG
int
TournamentBP::BPHistory::newCount = 0;
#endif
<|endoftext|>


<commit_before>///
/// @file  PrimeGenerator.cpp
///        Generates the sieving primes up to sqrt(stop) and adds
///        them to PrimeFinder.
///
/// Copyright (C) 2016 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve/config.hpp>
#include <primesieve/PrimeGenerator.hpp>
#include <primesieve/PrimeFinder.hpp>
#include <primesieve/PreSieve.hpp>
#include <primesieve/SieveOfEratosthenes.hpp>
#include <primesieve/SieveOfEratosthenes-inline.hpp>
#include <primesieve/littleendian_cast.hpp>

#include <vector>
#include <cassert>

namespace primesieve {

PrimeGenerator::PrimeGenerator(PrimeFinder& finder, const PreSieve& preSieve) :
  SieveOfEratosthenes(preSieve.getLimit() + 1,
                      finder.getSqrtStop(),
                      config::PRIMEGENERATOR_SIEVESIZE,
                      preSieve),
  finder_(finder)
{ }

/// Generate the primes up to finder.stop_^0.25 using
/// the sieve of Eratosthenes.
///
void PrimeGenerator::generateTinyPrimes()
{
  uint_t s = (uint_t) getStart();
  uint_t n = getSqrtStop();

  std::vector<char> isPrime(n + 1, true);

  for (uint_t i = 3; i * i <= n; i += 2)
    if (isPrime[i])
      for (uint_t j = i * i; j <= n; j += i * 2)
        isPrime[j] = false;

  assert(s > 5);
  for (uint_t i = s + (~s & 1); i <= n; i += 2)
    if (isPrime[i])
      addSievingPrime(i);
}

void PrimeGenerator::doIt()
{
  generateTinyPrimes();
  // calls segmentFinished() when done
  sieve();
}

void PrimeGenerator::segmentFinished(const byte_t* sieve, uint_t sieveSize)
{
  generateSievingPrimes(sieve, sieveSize);
}

/// Reconstruct primes from 1 bits of the sieve array
/// and use them for sieving in finder_.
///
void PrimeGenerator::generateSievingPrimes(const byte_t* sieve, uint_t sieveSize)
{
  uint64_t base = getSegmentLow();
  for (uint_t i = 0; i < sieveSize; i += 8)
  {
    uint64_t bits = littleendian_cast<uint64_t>(&sieve[i]);
    while (bits != 0)
    {
      uint_t prime = (uint_t) getNextPrime(&bits, base);
      finder_.addSievingPrime(prime);
    }
    base += NUMBERS_PER_BYTE * 8;
  }
}

} // namespace primesieve
<commit_msg>Refactor<commit_after>///
/// @file  PrimeGenerator.cpp
///        Generates the sieving primes up to sqrt(stop) and adds
///        them to PrimeFinder.
///
/// Copyright (C) 2016 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve/config.hpp>
#include <primesieve/PrimeGenerator.hpp>
#include <primesieve/PrimeFinder.hpp>
#include <primesieve/PreSieve.hpp>
#include <primesieve/SieveOfEratosthenes.hpp>
#include <primesieve/SieveOfEratosthenes-inline.hpp>
#include <primesieve/littleendian_cast.hpp>

#include <stdint.h>
#include <vector>

namespace primesieve {

PrimeGenerator::PrimeGenerator(PrimeFinder& finder, const PreSieve& preSieve) :
  SieveOfEratosthenes(preSieve.getLimit() + 1,
                      finder.getSqrtStop(),
                      config::PRIMEGENERATOR_SIEVESIZE,
                      preSieve),
  finder_(finder)
{ }

void PrimeGenerator::generateSievingPrimes()
{
  generateTinyPrimes();
  // calls segmentFinished() when done
  sieve();
}

/// Generate the primes up to finder.getSqrtStop()
/// using the sieve of Eratosthenes.
///
void PrimeGenerator::generateTinyPrimes()
{
  uint_t s = (uint_t) getStart();
  uint_t n = getSqrtStop();

  std::vector<char> isPrime(n + 1, true);

  for (uint_t i = 3; i * i <= n; i += 2)
    if (isPrime[i])
      for (uint_t j = i * i; j <= n; j += i * 2)
        isPrime[j] = false;

  // make sure s is odd
  s += (~s & 1);
  for (uint_t i = s; i <= n; i += 2)
    if (isPrime[i])
      addSievingPrime(i);
}

void PrimeGenerator::segmentFinished(const byte_t* sieve, uint_t sieveSize)
{
  generateSievingPrimes(sieve, sieveSize);
}

/// Reconstruct primes from 1 bits of the sieve array
/// and use them for sieving in finder_.
///
void PrimeGenerator::generateSievingPrimes(const byte_t* sieve, uint_t sieveSize)
{
  uint64_t base = getSegmentLow();

  for (uint_t i = 0; i < sieveSize; i += 8)
  {
    uint64_t bits = littleendian_cast<uint64_t>(&sieve[i]);

    while (bits != 0)
      finder_.addSievingPrime((uint_t) getNextPrime(&bits, base));

    base += NUMBERS_PER_BYTE * 8;
  }
}

} // namespace primesieve
<|endoftext|>


<commit_before>#include "decisioncreationwidget.h"
#include "ui_decisioncreationwidget.h"

#include <QMessageBox>

DecisionCreationWidget::DecisionCreationWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::DecisionCreationWidget)
{
    ui->setupUi(this);

    ui->pushButtonUpdateDecision->hide();
    updateIndex = -1;

    connect(this, SIGNAL(inputError(QString)),
            this, SLOT(on_inputError(QString)));
}

DecisionCreationWidget::~DecisionCreationWidget()
{
    delete ui;
}

json_spirit::Array DecisionCreationWidget::createDecisionArray()
{
    // Main branch ID
    QString branchID;
    if (ui->comboBoxBranch->currentText() == "Main") {
        branchID = "0f894a25c5e0318ee148fe54600ebbf50782f0a1df1eb2aab06321a8ccec270d";
    } else if (ui->comboBoxBranch->currentText() == "Sports") {
        branchID = "419cd87761f45c108a976ca6d93d4929c7c4d1ff4386f5089fc2f7ff7ae21ddf";
    } else if (ui->comboBoxBranch->currentText() == "Econ") {
        branchID = "3277b5057ac9cda54e9edfbb45fd8bab38be1b5afc3cd6c587f6d17779f34f74";
    }

    // Grab user input from ui
    QString address = ui->lineEditOwnerAddr->text();
    QString prompt = ui->plainTextEditPrompt->toPlainText();
    int eventOverBy = 1; // Temporary placeholder
    bool answerOptionality = false;
    if (ui->checkBoxVoteMandatory->isChecked()) {
        answerOptionality = false;
    } else {
        answerOptionality = true;
    }
    bool scaled = ui->radioButtonScaled->isChecked();
    double scaledMin = ui->doubleSpinBoxScaledMin->value();
    double scaledMax = ui->doubleSpinBoxScaledMax->value();

    bool error = false;

    // Perform basic checks and avoid wasting json calls
    if (branchID.isEmpty()) {
        emit inputError("You must select a branch!");
        error = true;
    }

    if (address.isEmpty()) {
        emit inputError("You must enter a valid Hivemind address!");
        error = true;
    }

    if (prompt.isEmpty()) {
        emit inputError("You must enter a valid prompt!");
        error = true;
    }

    if (eventOverBy == 0) {
        emit inputError("You must enter a valid ending date!");
        error = true;
    }

    if (scaled && (scaledMax == scaledMin)) {
        emit inputError("You must enter  valid scaled values!");
        error = true;
    }

    // Setup json_spirit array
    json_spirit::Array params;

    // Return empty array if there was an input error
    if (error) return params;

    // Add parmeters to array
    params.push_back(address.toStdString());
    params.push_back(branchID.toStdString());
    params.push_back(prompt.toStdString());
    params.push_back(eventOverBy);
    params.push_back(answerOptionality);
    params.push_back(scaled);
    if (scaled) {
        params.push_back(scaledMin);
        params.push_back(scaledMax);
    }
    // Type of array
    params.push_back("decision");

    return params;
}

void DecisionCreationWidget::on_pushButtonCreateDecision_clicked()
{
    json_spirit::Array decisionArray = createDecisionArray();
    if (!decisionArray.empty()) {
        emit newDecisionArray(decisionArray);
    }
}

void DecisionCreationWidget::on_radioButtonBinary_clicked(bool checked)
{
    // Enable scale doublespinbox widgets for binary decision
    if (checked) {
        ui->doubleSpinBoxScaledMin->setEnabled(false);
        ui->doubleSpinBoxScaledMax->setEnabled(false);
    } else {
        ui->doubleSpinBoxScaledMin->setEnabled(true);
        ui->doubleSpinBoxScaledMax->setEnabled(true);
    }
}

void DecisionCreationWidget::on_radioButtonScaled_clicked(bool checked)
{
    // Enable scale doublespinbox widgets for scaled decision
    if (checked) {
        ui->doubleSpinBoxScaledMin->setEnabled(true);
        ui->doubleSpinBoxScaledMax->setEnabled(true);
    } else {
        ui->doubleSpinBoxScaledMin->setEnabled(false);
        ui->doubleSpinBoxScaledMax->setEnabled(false);
    }
}

void DecisionCreationWidget::on_inputError(const QString &errorMessage)
{
    QMessageBox errorMessageBox;
    errorMessageBox.setWindowTitle("Input error!");
    errorMessageBox.setText(errorMessage);
    errorMessageBox.setStandardButtons(QMessageBox::Ok);
    errorMessageBox.setDefaultButton(QMessageBox::Ok);
    errorMessageBox.exec();
}

void DecisionCreationWidget::editArray(json_spirit::Array array)
{
    if (array.size() < 6) {
        return;
    }

    // Load owner address
    json_spirit::Value ownerAddr = array.at(0);
    ui->lineEditOwnerAddr->setText(QString::fromStdString(ownerAddr.get_str()));

    // Load branchID
    json_spirit::Value branch = array.at(1);
    QString branchLabel = "Branch: ";
    QString branchID = QString::fromStdString(branch.get_str());
    branchLabel.append(branchID.left(12));
    branchLabel.append("...");
    ui->labelBranch->setText(branchLabel);
    if (branchID == "0f894a25c5e0318ee148fe54600ebbf50782f0a1df1eb2aab06321a8ccec270d") {
        ui->comboBoxBranch->setCurrentIndex(0); // Main
    } else if (branchID == "419cd87761f45c108a976ca6d93d4929c7c4d1ff4386f5089fc2f7ff7ae21ddf") {
        ui->comboBoxBranch->setCurrentIndex(1); // Sports
    } else if (branchID == "3277b5057ac9cda54e9edfbb45fd8bab38be1b5afc3cd6c587f6d17779f34f74") {
        ui->comboBoxBranch->setCurrentIndex(2); // Econ
    }

    // Load prompt
    json_spirit::Value prompt = array.at(2);
    ui->plainTextEditPrompt->setPlainText(QString::fromStdString(prompt.get_str()));

    // Load event over by
//    TODO: Replace with nLockTime
//    json_spirit::Value eventOverBy = array.at(3);
//    int overBy = eventOverBy.get_int();

    // Load voteMandatory
    json_spirit::Value voteMandatory = array.at(4);
    ui->checkBoxVoteMandatory->setChecked(voteMandatory.get_bool());

    // Load scaled
    json_spirit::Value scaled = array.at(5);
    bool isScaled = scaled.get_bool();
    ui->radioButtonScaled->setChecked(isScaled);
    if (isScaled) {
        // Load scale values
        json_spirit::Value scaledMin = array.at(6);
        ui->doubleSpinBoxScaledMin->setValue(scaledMin.get_real());
        json_spirit::Value scaledMax = array.at(7);
        ui->doubleSpinBoxScaledMax->setValue(scaledMax.get_real());
    }

    // Check for update index from model
    if (isScaled && array.size() == 10) {
        ui->pushButtonCreateDecision->hide();
        ui->pushButtonUpdateDecision->show();
        updateIndex = array.at(9).get_int();
    } else if (!isScaled && array.size() == 8) {
        ui->pushButtonCreateDecision->hide();
        ui->pushButtonUpdateDecision->show();
        updateIndex = array.at(7).get_int();
    }
}

void DecisionCreationWidget::on_pushButtonUpdateDecision_clicked()
{
    json_spirit::Array updatedDecision = createDecisionArray();
    if (!updatedDecision.empty() && updateIndex >= 0) {
        updatedDecision.push_back(updateIndex);
        emit updatedDecisionArray(updatedDecision);
    }
}

// Setup the UI for the combo creation widget
void DecisionCreationWidget::comboCreationUI()
{
    ui->pushButtonCreateDecision->hide();
}
<commit_msg>Enable scaled value combo spinboxes on decision edit<commit_after>#include "decisioncreationwidget.h"
#include "ui_decisioncreationwidget.h"

#include <QMessageBox>

DecisionCreationWidget::DecisionCreationWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::DecisionCreationWidget)
{
    ui->setupUi(this);

    ui->pushButtonUpdateDecision->hide();
    updateIndex = -1;

    connect(this, SIGNAL(inputError(QString)),
            this, SLOT(on_inputError(QString)));
}

DecisionCreationWidget::~DecisionCreationWidget()
{
    delete ui;
}

json_spirit::Array DecisionCreationWidget::createDecisionArray()
{
    // Main branch ID
    QString branchID;
    if (ui->comboBoxBranch->currentText() == "Main") {
        branchID = "0f894a25c5e0318ee148fe54600ebbf50782f0a1df1eb2aab06321a8ccec270d";
    } else if (ui->comboBoxBranch->currentText() == "Sports") {
        branchID = "419cd87761f45c108a976ca6d93d4929c7c4d1ff4386f5089fc2f7ff7ae21ddf";
    } else if (ui->comboBoxBranch->currentText() == "Econ") {
        branchID = "3277b5057ac9cda54e9edfbb45fd8bab38be1b5afc3cd6c587f6d17779f34f74";
    }

    // Grab user input from ui
    QString address = ui->lineEditOwnerAddr->text();
    QString prompt = ui->plainTextEditPrompt->toPlainText();
    int eventOverBy = 1; // Temporary placeholder
    bool answerOptionality = false;
    if (ui->checkBoxVoteMandatory->isChecked()) {
        answerOptionality = false;
    } else {
        answerOptionality = true;
    }
    bool scaled = ui->radioButtonScaled->isChecked();
    double scaledMin = ui->doubleSpinBoxScaledMin->value();
    double scaledMax = ui->doubleSpinBoxScaledMax->value();

    bool error = false;

    // Perform basic checks and avoid wasting json calls
    if (branchID.isEmpty()) {
        emit inputError("You must select a branch!");
        error = true;
    }

    if (address.isEmpty()) {
        emit inputError("You must enter a valid Hivemind address!");
        error = true;
    }

    if (prompt.isEmpty()) {
        emit inputError("You must enter a valid prompt!");
        error = true;
    }

    if (eventOverBy == 0) {
        emit inputError("You must enter a valid ending date!");
        error = true;
    }

    if (scaled && (scaledMax == scaledMin)) {
        emit inputError("You must enter  valid scaled values!");
        error = true;
    }

    // Setup json_spirit array
    json_spirit::Array params;

    // Return empty array if there was an input error
    if (error) return params;

    // Add parmeters to array
    params.push_back(address.toStdString());
    params.push_back(branchID.toStdString());
    params.push_back(prompt.toStdString());
    params.push_back(eventOverBy);
    params.push_back(answerOptionality);
    params.push_back(scaled);
    if (scaled) {
        params.push_back(scaledMin);
        params.push_back(scaledMax);
    }
    // Type of array
    params.push_back("decision");

    return params;
}

void DecisionCreationWidget::on_pushButtonCreateDecision_clicked()
{
    json_spirit::Array decisionArray = createDecisionArray();
    if (!decisionArray.empty()) {
        emit newDecisionArray(decisionArray);
    }
}

void DecisionCreationWidget::on_radioButtonBinary_clicked(bool checked)
{
    // Enable scale doublespinbox widgets for binary decision
    if (checked) {
        ui->doubleSpinBoxScaledMin->setEnabled(false);
        ui->doubleSpinBoxScaledMax->setEnabled(false);
    } else {
        ui->doubleSpinBoxScaledMin->setEnabled(true);
        ui->doubleSpinBoxScaledMax->setEnabled(true);
    }
}

void DecisionCreationWidget::on_radioButtonScaled_clicked(bool checked)
{
    // Enable scale doublespinbox widgets for scaled decision
    if (checked) {
        ui->doubleSpinBoxScaledMin->setEnabled(true);
        ui->doubleSpinBoxScaledMax->setEnabled(true);
    } else {
        ui->doubleSpinBoxScaledMin->setEnabled(false);
        ui->doubleSpinBoxScaledMax->setEnabled(false);
    }
}

void DecisionCreationWidget::on_inputError(const QString &errorMessage)
{
    QMessageBox errorMessageBox;
    errorMessageBox.setWindowTitle("Input error!");
    errorMessageBox.setText(errorMessage);
    errorMessageBox.setStandardButtons(QMessageBox::Ok);
    errorMessageBox.setDefaultButton(QMessageBox::Ok);
    errorMessageBox.exec();
}

void DecisionCreationWidget::editArray(json_spirit::Array array)
{
    if (array.size() < 6) {
        return;
    }

    // Load owner address
    json_spirit::Value ownerAddr = array.at(0);
    ui->lineEditOwnerAddr->setText(QString::fromStdString(ownerAddr.get_str()));

    // Load branchID
    json_spirit::Value branch = array.at(1);
    QString branchLabel = "Branch: ";
    QString branchID = QString::fromStdString(branch.get_str());
    branchLabel.append(branchID.left(12));
    branchLabel.append("...");
    ui->labelBranch->setText(branchLabel);
    if (branchID == "0f894a25c5e0318ee148fe54600ebbf50782f0a1df1eb2aab06321a8ccec270d") {
        ui->comboBoxBranch->setCurrentIndex(0); // Main
    } else if (branchID == "419cd87761f45c108a976ca6d93d4929c7c4d1ff4386f5089fc2f7ff7ae21ddf") {
        ui->comboBoxBranch->setCurrentIndex(1); // Sports
    } else if (branchID == "3277b5057ac9cda54e9edfbb45fd8bab38be1b5afc3cd6c587f6d17779f34f74") {
        ui->comboBoxBranch->setCurrentIndex(2); // Econ
    }

    // Load prompt
    json_spirit::Value prompt = array.at(2);
    ui->plainTextEditPrompt->setPlainText(QString::fromStdString(prompt.get_str()));

    // Load event over by
//    TODO: Replace with nLockTime
//    json_spirit::Value eventOverBy = array.at(3);
//    int overBy = eventOverBy.get_int();

    // Load voteMandatory
    json_spirit::Value voteMandatory = array.at(4);
    ui->checkBoxVoteMandatory->setChecked(voteMandatory.get_bool());

    // Load scaled
    json_spirit::Value scaled = array.at(5);
    bool isScaled = scaled.get_bool();
    ui->radioButtonScaled->setChecked(isScaled);
    if (isScaled) {
        // Load scale values
        json_spirit::Value scaledMin = array.at(6);
        ui->doubleSpinBoxScaledMin->setValue(scaledMin.get_real());
        json_spirit::Value scaledMax = array.at(7);
        ui->doubleSpinBoxScaledMax->setValue(scaledMax.get_real());
    }

    // Unhide the scaled spinboxes if the decision is scaled
    on_radioButtonScaled_clicked(isScaled);

    // Check for update index from model
    if (isScaled && array.size() == 10) {
        ui->pushButtonCreateDecision->hide();
        ui->pushButtonUpdateDecision->show();
        updateIndex = array.at(9).get_int();
    } else if (!isScaled && array.size() == 8) {
        ui->pushButtonCreateDecision->hide();
        ui->pushButtonUpdateDecision->show();
        updateIndex = array.at(7).get_int();
    }
}

void DecisionCreationWidget::on_pushButtonUpdateDecision_clicked()
{
    json_spirit::Array updatedDecision = createDecisionArray();
    if (!updatedDecision.empty() && updateIndex >= 0) {
        updatedDecision.push_back(updateIndex);
        emit updatedDecisionArray(updatedDecision);
    }
}

// Setup the UI for the combo creation widget
void DecisionCreationWidget::comboCreationUI()
{
    ui->pushButtonCreateDecision->hide();
}
<|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

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

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes

// Local includes
#include "libmesh/quadrature_clough.h"
#include "libmesh/quadrature_gauss.h"
#include "libmesh/quadrature_gm.h"
#include "libmesh/quadrature_grid.h"
#include "libmesh/quadrature_jacobi.h"
#include "libmesh/quadrature_monomial.h"
#include "libmesh/quadrature_simpson.h"
#include "libmesh/quadrature_trap.h"
#include "libmesh/quadrature_gauss_lobatto.h"
#include "libmesh/string_to_enum.h"

namespace libMesh
{

//---------------------------------------------------------------
AutoPtr<QBase> QBase::build (const std::string &type,
                             const unsigned int _dim,
                             const Order _order)
{
  return QBase::build (Utility::string_to_enum<QuadratureType> (type),
                       _dim,
                       _order);
}

AutoPtr<QBase> QBase::build(const QuadratureType _qt,
                            const unsigned int _dim,
                            const Order _order)
{
  switch (_qt)
    {

    case QCLOUGH:
      {
#ifdef DEBUG
        if (_order > TWENTYTHIRD)
          {
            libMesh::out << "WARNING: Clough quadrature implemented" << std::endl
                         << " up to TWENTYTHIRD order." << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QClough(_dim, _order));
        return ap;
      }

    case QGAUSS:
      {

#ifdef DEBUG
        if (_order > FORTYTHIRD)
          {
            libMesh::out << "WARNING: Gauss quadrature implemented" << std::endl
                         << " up to FORTYTHIRD order." << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QGauss(_dim, _order));
        return ap;
      }

    case QJACOBI_1_0:
      {

#ifdef DEBUG
        if (_order > TWENTYTHIRD)
          {
            libMesh::out << "WARNING: Jacobi(1,0) quadrature implemented" << std::endl
                         << " up to TWENTYTHIRD order." << std::endl;
          }

        if (_dim > 1)
          {
            libMesh::out << "WARNING: Jacobi(1,0) quadrature implemented" << std::endl
                         << " in 1D only." << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QJacobi(_dim, _order, 1, 0));
        return ap;
      }

    case QJACOBI_2_0:
      {

#ifdef DEBUG
        if (_order > TWENTYTHIRD)
          {
            libMesh::out << "WARNING: Jacobi(2,0) quadrature implemented" << std::endl
                         << " up to TWENTYTHIRD order." << std::endl;
          }

        if (_dim > 1)
          {
            libMesh::out << "WARNING: Jacobi(2,0) quadrature implemented" << std::endl
                         << " in 1D only." << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QJacobi(_dim, _order, 2, 0));
        return ap;
      }

    case QSIMPSON:
      {

#ifdef DEBUG
        if (_order > THIRD)
          {
            libMesh::out << "WARNING: Simpson rule provides only" << std::endl
                         << " THIRD order!" << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QSimpson(_dim));
        return ap;
      }

    case QTRAP:
      {

#ifdef DEBUG
        if (_order > FIRST)
          {
            libMesh::out << "WARNING: Trapezoidal rule provides only" << std::endl
                         << " FIRST order!" << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QTrap(_dim));
        return ap;
      }

    case QGRID:
      {
        AutoPtr<QBase> ap(new QGrid(_dim, _order));
        return ap;
      }

    case QGRUNDMANN_MOLLER:
      {
        AutoPtr<QBase> ap(new QGrundmann_Moller(_dim, _order));
        return ap;
      }

    case QMONOMIAL:
      {
        AutoPtr<QBase> ap(new QMonomial(_dim, _order));
        return ap;
      }

    case QGAUSS_LOBATTO:
      {
        AutoPtr<QBase> ap(new QGaussLobatto(_dim, _order));
        return ap;
      }

    default:
      libmesh_error_msg("ERROR: Bad qt=" << _qt);
    }

  libmesh_error_msg("We'll never get here!");
  AutoPtr<QBase> ap(NULL);
  return ap;
}

} // namespace libMesh
<commit_msg>Fix warning message when building Jacobi quadrature rules.<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

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

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes

// Local includes
#include "libmesh/quadrature_clough.h"
#include "libmesh/quadrature_gauss.h"
#include "libmesh/quadrature_gm.h"
#include "libmesh/quadrature_grid.h"
#include "libmesh/quadrature_jacobi.h"
#include "libmesh/quadrature_monomial.h"
#include "libmesh/quadrature_simpson.h"
#include "libmesh/quadrature_trap.h"
#include "libmesh/quadrature_gauss_lobatto.h"
#include "libmesh/string_to_enum.h"

namespace libMesh
{

//---------------------------------------------------------------
AutoPtr<QBase> QBase::build (const std::string &type,
                             const unsigned int _dim,
                             const Order _order)
{
  return QBase::build (Utility::string_to_enum<QuadratureType> (type),
                       _dim,
                       _order);
}

AutoPtr<QBase> QBase::build(const QuadratureType _qt,
                            const unsigned int _dim,
                            const Order _order)
{
  switch (_qt)
    {

    case QCLOUGH:
      {
#ifdef DEBUG
        if (_order > TWENTYTHIRD)
          {
            libMesh::out << "WARNING: Clough quadrature implemented" << std::endl
                         << " up to TWENTYTHIRD order." << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QClough(_dim, _order));
        return ap;
      }

    case QGAUSS:
      {

#ifdef DEBUG
        if (_order > FORTYTHIRD)
          {
            libMesh::out << "WARNING: Gauss quadrature implemented" << std::endl
                         << " up to FORTYTHIRD order." << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QGauss(_dim, _order));
        return ap;
      }

    case QJACOBI_1_0:
      {

#ifdef DEBUG
        if (_order > FORTYTHIRD)
          {
            libMesh::out << "WARNING: Jacobi(1,0) quadrature implemented" << std::endl
                         << " up to FORTYTHIRD order." << std::endl;
          }

        if (_dim > 1)
          {
            libMesh::out << "WARNING: Jacobi(1,0) quadrature implemented" << std::endl
                         << " in 1D only." << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QJacobi(_dim, _order, 1, 0));
        return ap;
      }

    case QJACOBI_2_0:
      {

#ifdef DEBUG
        if (_order > FORTYTHIRD)
          {
            libMesh::out << "WARNING: Jacobi(2,0) quadrature implemented" << std::endl
                         << " up to FORTYTHIRD order." << std::endl;
          }

        if (_dim > 1)
          {
            libMesh::out << "WARNING: Jacobi(2,0) quadrature implemented" << std::endl
                         << " in 1D only." << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QJacobi(_dim, _order, 2, 0));
        return ap;
      }

    case QSIMPSON:
      {

#ifdef DEBUG
        if (_order > THIRD)
          {
            libMesh::out << "WARNING: Simpson rule provides only" << std::endl
                         << " THIRD order!" << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QSimpson(_dim));
        return ap;
      }

    case QTRAP:
      {

#ifdef DEBUG
        if (_order > FIRST)
          {
            libMesh::out << "WARNING: Trapezoidal rule provides only" << std::endl
                         << " FIRST order!" << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QTrap(_dim));
        return ap;
      }

    case QGRID:
      {
        AutoPtr<QBase> ap(new QGrid(_dim, _order));
        return ap;
      }

    case QGRUNDMANN_MOLLER:
      {
        AutoPtr<QBase> ap(new QGrundmann_Moller(_dim, _order));
        return ap;
      }

    case QMONOMIAL:
      {
        AutoPtr<QBase> ap(new QMonomial(_dim, _order));
        return ap;
      }

    case QGAUSS_LOBATTO:
      {
        AutoPtr<QBase> ap(new QGaussLobatto(_dim, _order));
        return ap;
      }

    default:
      libmesh_error_msg("ERROR: Bad qt=" << _qt);
    }

  libmesh_error_msg("We'll never get here!");
  AutoPtr<QBase> ap(NULL);
  return ap;
}

} // namespace libMesh
<|endoftext|>


<commit_before>#include "assert.hh"

#include "exception.hh"

namespace Kakoune
{

struct assert_failed : logic_error
{
    assert_failed(const String& message)
        : m_message(message) {}

    String description() const override { return m_message; }
private:
    String m_message;
};

void on_assert_failed(const char* message)
{
    int res = system(("xmessage -buttons 'quit:0,ignore:1' '"_str + message + "'").c_str());
    switch (res)
    {
    case 0:
        throw assert_failed(message);
    case 1:
        return;
    }
}

}
<commit_msg>assert: throw if launching xmessage fails<commit_after>#include "assert.hh"

#include "exception.hh"

namespace Kakoune
{

struct assert_failed : logic_error
{
    assert_failed(const String& message)
        : m_message(message) {}

    String description() const override { return m_message; }
private:
    String m_message;
};

void on_assert_failed(const char* message)
{
    int res = system(("xmessage -buttons 'quit:0,ignore:1' '"_str + message + "'").c_str());
    switch (res)
    {
    case -1:
    case  0:
        throw assert_failed(message);
    case 1:
        return;
    }
}

}
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>
#include <new>

#include "base64.h"

char *cordpp::b64_encode(const char *src, size_t length) {
    // (length * 4 / 3) rounded up to nearest multiple of 4
    size_t encoded_length = ((length<<2)/3+3)&-4;
    char *buffer = new char[encoded_length + 1];

    if (buffer == nullptr) {
        printf("Call to malloc() in io::b64_encode() failed. Exiting...");
        exit(EXIT_FAILURE);
    }

    char *p = buffer;
    size_t i;

    for(i = 0; i < length-2; i += 3) {
        *p++ = B64_CHARSET[(src[i] >> 2) & 0x3F];
        *p++ = B64_CHARSET[(src[i] << 4 | src[i+1] >> 4) & 0x3F];
        *p++ = B64_CHARSET[(src[i+1] << 2 | src[i+2] >> 6) & 0x3F];
        *p++ = B64_CHARSET[src[i+2] & 0x3F];
    }

    // this returns 3 instead of 0 if we need no padding but
    // if we need no padding we dont need to do anything
    int padding = (length % 3)^3;

    if (padding == 1) {
        *p++ = B64_CHARSET[(src[i] >> 2) & 0x3F];
        *p++ = B64_CHARSET[(src[i] << 4 | src[i+1] >> 4) & 0x3F];
        *p++ = B64_CHARSET[(src[i+1] << 2) & 0x3F];
        *p++ = '=';
    } else if (padding == 2) {
        *p++ = B64_CHARSET[(src[i] >> 2) & 0x3F];
        *p++ = B64_CHARSET[(src[i] << 4) & 0x3F];
        *p++ = '=';
        *p++ = '=';
    }

    *p = '\0';

    return buffer;
}

char *cordpp::b64_decode(const char *src, size_t length) {
    // The input is invalid or not properly padded
    if (length % 4 != 0)
        return nullptr;

    // instead of figuring out exactly how long the decoded string should be
    // allocate enough. at most this is an extra 2 bytes
    char *buffer = new char[(length * 3 >> 2) + 1];

    if (buffer == nullptr) {
        printf("Call to malloc() in io::b64_decode() failed. Exiting...");
        exit(EXIT_FAILURE);
    }

    char *p = buffer;
    size_t i;

    for(i = 0; i < length - 4; i += 4) {
        *p++ = (B64_LOOKUP[(int)src[i]] << 2 | B64_LOOKUP[(int)src[i+1]] >> 4) & 0xff;
        *p++ = (B64_LOOKUP[(int)src[i+1]] << 4 | B64_LOOKUP[(int)src[i+2]] >> 2) & 0xff;
        *p++ = (B64_LOOKUP[(int)src[i+2]] << 6 | B64_LOOKUP[(int)src[i+3]]) & 0xff;
    }

    *p++ = (B64_LOOKUP[(int)src[i]] << 2 | B64_LOOKUP[(int)src[i+1]] >> 4) & 0xff;

    if (src[i+2] != '=') {
        *p++ = (B64_LOOKUP[(int)src[i+1]] << 4 | B64_LOOKUP[(int)src[i+2]] >> 2) & 0xff;
        if (src[i+3] != '=') {
            *p++ = (B64_LOOKUP[(int)src[i+2]] << 6 | B64_LOOKUP[(int)src[i+3]]) & 0xff;
        } else {
            *p++ = B64_LOOKUP[(int)src[i+2]] << 6 & 0xff;
        }
    } else {
        *p++ = B64_LOOKUP[(int)src[i+1]] << 4 & 0xff;
    }

    *p = '\0';

    return buffer;
}
<commit_msg>remove redundant check in base64 functions<commit_after>#include <cstdio>
#include <cstdlib>
#include <new>

#include "base64.h"

char *cordpp::b64_encode(const char *src, size_t length) {
    // (length * 4 / 3) rounded up to nearest multiple of 4
    size_t encoded_length = ((length<<2)/3+3)&-4;
    char *buffer = new char[encoded_length + 1];

    char *p = buffer;
    size_t i;

    for(i = 0; i < length-2; i += 3) {
        *p++ = B64_CHARSET[(src[i] >> 2) & 0x3F];
        *p++ = B64_CHARSET[(src[i] << 4 | src[i+1] >> 4) & 0x3F];
        *p++ = B64_CHARSET[(src[i+1] << 2 | src[i+2] >> 6) & 0x3F];
        *p++ = B64_CHARSET[src[i+2] & 0x3F];
    }

    // this returns 3 instead of 0 if we need no padding but
    // if we need no padding we dont need to do anything
    int padding = (length % 3)^3;

    if (padding == 1) {
        *p++ = B64_CHARSET[(src[i] >> 2) & 0x3F];
        *p++ = B64_CHARSET[(src[i] << 4 | src[i+1] >> 4) & 0x3F];
        *p++ = B64_CHARSET[(src[i+1] << 2) & 0x3F];
        *p++ = '=';
    } else if (padding == 2) {
        *p++ = B64_CHARSET[(src[i] >> 2) & 0x3F];
        *p++ = B64_CHARSET[(src[i] << 4) & 0x3F];
        *p++ = '=';
        *p++ = '=';
    }

    *p = '\0';

    return buffer;
}

char *cordpp::b64_decode(const char *src, size_t length) {
    // The input is invalid or not properly padded
    if (length % 4 != 0)
        return nullptr;

    // instead of figuring out exactly how long the decoded string should be
    // allocate enough. at most this is an extra 2 bytes
    char *buffer = new char[(length * 3 >> 2) + 1];

    char *p = buffer;
    size_t i;

    for(i = 0; i < length - 4; i += 4) {
        *p++ = (B64_LOOKUP[(int)src[i]] << 2 | B64_LOOKUP[(int)src[i+1]] >> 4) & 0xff;
        *p++ = (B64_LOOKUP[(int)src[i+1]] << 4 | B64_LOOKUP[(int)src[i+2]] >> 2) & 0xff;
        *p++ = (B64_LOOKUP[(int)src[i+2]] << 6 | B64_LOOKUP[(int)src[i+3]]) & 0xff;
    }

    *p++ = (B64_LOOKUP[(int)src[i]] << 2 | B64_LOOKUP[(int)src[i+1]] >> 4) & 0xff;

    if (src[i+2] != '=') {
        *p++ = (B64_LOOKUP[(int)src[i+1]] << 4 | B64_LOOKUP[(int)src[i+2]] >> 2) & 0xff;
        if (src[i+3] != '=') {
            *p++ = (B64_LOOKUP[(int)src[i+2]] << 6 | B64_LOOKUP[(int)src[i+3]]) & 0xff;
        } else {
            *p++ = B64_LOOKUP[(int)src[i+2]] << 6 & 0xff;
        }
    } else {
        *p++ = B64_LOOKUP[(int)src[i+1]] << 4 & 0xff;
    }

    *p = '\0';

    return buffer;
}
<|endoftext|>