<commit_before>/*************************************************************************
 *
 *  $RCSfile: YViews.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2005-03-10 15:41:43 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_MYSQL_VIEWS_HXX_
#define _CONNECTIVITY_MYSQL_VIEWS_HXX_

#ifndef _CONNECTIVITY_SDBCX_COLLECTION_HXX_
#include "connectivity/sdbcx/VCollection.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
#endif
namespace connectivity
{
    namespace mysql
    {
        class OViews : public sdbcx::OCollection
        {
            ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >       m_xMetaData;
            sal_Bool m_bInDrop;
            //  OCatalog*                                           m_pParent;
        protected:
            virtual sdbcx::ObjectType createObject(const ::rtl::OUString& _rName);
            virtual void impl_refresh() throw(::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > createEmptyObject();
            virtual void appendObject( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor );
            virtual void dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName);

            void createView( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor );
        public:
            OViews(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >& _rMetaData,::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex,
                const TStringVector &_rVector) : sdbcx::OCollection(_rParent,sal_True,_rMutex,_rVector)
                ,m_xMetaData(_rMetaData)
                ,m_bInDrop(sal_False)
            {}

            // only the name is identical to ::cppu::OComponentHelper
            virtual void SAL_CALL disposing(void);

            void appendNew(const ::rtl::OUString& _rsNewTable);
            void dropByNameImpl(const ::rtl::OUString& elementName);
        };
    }
}
#endif // _CONNECTIVITY_MYSQL_VIEWS_HXX_

<commit_msg>INTEGRATION: CWS ooo19126 (1.2.74); FILE MERGED 2005/09/05 17:25:44 rt 1.2.74.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: YViews.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 07:34:10 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_MYSQL_VIEWS_HXX_
#define _CONNECTIVITY_MYSQL_VIEWS_HXX_

#ifndef _CONNECTIVITY_SDBCX_COLLECTION_HXX_
#include "connectivity/sdbcx/VCollection.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
#endif
namespace connectivity
{
    namespace mysql
    {
        class OViews : public sdbcx::OCollection
        {
            ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >       m_xMetaData;
            sal_Bool m_bInDrop;
            //  OCatalog*                                           m_pParent;
        protected:
            virtual sdbcx::ObjectType createObject(const ::rtl::OUString& _rName);
            virtual void impl_refresh() throw(::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > createEmptyObject();
            virtual void appendObject( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor );
            virtual void dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName);

            void createView( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor );
        public:
            OViews(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >& _rMetaData,::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex,
                const TStringVector &_rVector) : sdbcx::OCollection(_rParent,sal_True,_rMutex,_rVector)
                ,m_xMetaData(_rMetaData)
                ,m_bInDrop(sal_False)
            {}

            // only the name is identical to ::cppu::OComponentHelper
            virtual void SAL_CALL disposing(void);

            void appendNew(const ::rtl::OUString& _rsNewTable);
            void dropByNameImpl(const ::rtl::OUString& elementName);
        };
    }
}
#endif // _CONNECTIVITY_MYSQL_VIEWS_HXX_

<|endoftext|>


<commit_before>#ifndef K3_RUNTIME_BASESTRING_H
#define K3_RUNTIME_BASESTRING_H

#include <cstring>
#include <memory>

char* strdup(const char*);

namespace K3 {
  class base_string {
   public:
    // Constructors/Destructors/Assignment.

    base_string(): buffer(nullptr) {}

    base_string(const base_string& other): buffer(strdup(other.buffer)) {}

    base_string(base_string&& other): base_string() {
      swap(*this, other);
    }

    base_string(const char* b): buffer(strdup(b)) {}
    base_string(const std::string& s) : buffer(strdup(s.c_str())) {}

    base_string(const char* from, std::size_t count) {
      buffer = new char[count + 1];
      strncpy(buffer, from, count);
      buffer[count] = 0;
    }

    ~base_string() {
      delete [] buffer;
    }

    base_string& operator =(const base_string& other) {
      *this = base_string { other };
      return *this;
    }

    base_string& operator =(base_string&& other) {
      swap(*this, other);
      return *this;
    }

    friend void swap(base_string& first, base_string& second) {
      using std::swap;
      swap(first.buffer, second.buffer);
    }

    // Conversions
    operator std::string() const {
      return std::string(buffer);
    }

    // Accessors
    std::size_t length() {
      return strlen(buffer);
    }

    const char* c_str() const {
      return buffer;
    }

    // Comparisons
    bool operator ==(const base_string& other) const {
      return strcmp(buffer, other.buffer) == 0;
    }

    bool operator !=(const base_string& other) const {
      return strcmp(buffer, other.buffer) != 0;
    }

    bool operator <=(const base_string& other) const {
      return strcmp(buffer, other.buffer) <= 0;
    }

    bool operator <(const base_string& other) const {
      return strcmp(buffer, other.buffer) < 0;
    }

    bool operator >=(const base_string& other) const {
      return strcmp(buffer, other.buffer) >= 0;
    }

    bool operator >(const base_string& other) const {
      return strcmp(buffer, other.buffer) > 0;
    }

    // Operations
    base_string substr(std::size_t from, std::size_t to) const {
      auto n = strlen(buffer);

      if (from > n) {
        from = n;
      }

      if (to > n) {
        to = n;
      }

      return base_string(buffer + from, to - from);
    }

   private:
    char* buffer;
  };
}

#endif
<commit_msg>Implement serialization on base_strings.<commit_after>#ifndef K3_RUNTIME_BASESTRING_H
#define K3_RUNTIME_BASESTRING_H

#include <cstring>
#include <memory>

char* strdup(const char*);

namespace K3 {
  class base_string {
   public:
    // Constructors/Destructors/Assignment.

    base_string(): buffer(nullptr) {}

    base_string(const base_string& other): buffer(strdup(other.buffer)) {}

    base_string(base_string&& other): base_string() {
      swap(*this, other);
    }

    base_string(const char* b): buffer(strdup(b)) {}
    base_string(const std::string& s) : buffer(strdup(s.c_str())) {}

    base_string(const char* from, std::size_t count) {
      buffer = new char[count + 1];
      strncpy(buffer, from, count);
      buffer[count] = 0;
    }

    ~base_string() {
      delete [] buffer;
    }

    base_string& operator =(const base_string& other) {
      *this = base_string { other };
      return *this;
    }

    base_string& operator =(base_string&& other) {
      swap(*this, other);
      return *this;
    }

    friend void swap(base_string& first, base_string& second) {
      using std::swap;
      swap(first.buffer, second.buffer);
    }

    // Conversions
    operator std::string() const {
      return std::string(buffer);
    }

    // Accessors
    std::size_t length() {
      return strlen(buffer);
    }

    const char* c_str() const {
      return buffer;
    }

    // Comparisons
    bool operator ==(const base_string& other) const {
      return strcmp(buffer, other.buffer) == 0;
    }

    bool operator !=(const base_string& other) const {
      return strcmp(buffer, other.buffer) != 0;
    }

    bool operator <=(const base_string& other) const {
      return strcmp(buffer, other.buffer) <= 0;
    }

    bool operator <(const base_string& other) const {
      return strcmp(buffer, other.buffer) < 0;
    }

    bool operator >=(const base_string& other) const {
      return strcmp(buffer, other.buffer) >= 0;
    }

    bool operator >(const base_string& other) const {
      return strcmp(buffer, other.buffer) > 0;
    }

    // Operations
    base_string substr(std::size_t from, std::size_t to) const {
      auto n = strlen(buffer);

      if (from > n) {
        from = n;
      }

      if (to > n) {
        to = n;
      }

      return base_string(buffer + from, to - from);
    }

    template <class archive>
    void serialize(archive& a, const unsigned int) {
      a & boost::serialization::make_array(buffer, strlen(buffer));
    }
   private:
    char* buffer;
  };
}

#endif
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 1837
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1166624 by johtaylo@johtaylo-JTBUILDER03-increment on 2015/07/01 03:00:49<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 1838
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2931
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1896279 by chui@ocl-promo-incrementor on 2019/06/25 03:00:02<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2932
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2217
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1316519 by johtaylo@johtaylo_L7_stg on 2016/09/20 12:50:43<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2218
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3051
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>P4 to Git Change 2039930 by chui@ocl-promo-incrementor on 2019/12/03 03:00:16<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3052
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2269
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1338576 by johtaylo@johtaylo-jtincrementor-increment on 2016/11/09 03:00:05<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2270
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 1958
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1215590 by johtaylo@johtaylo-JTBUILDER03-increment on 2015/11/29 03:00:12<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 1959
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2074
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1251492 by johtaylo@johtaylo-JTBUILDER03-increment on 2016/03/26 03:00:15<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2075
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>// Copyright 2018 Ulf Adams
//
// The contents of this file may be used under the terms of the Apache License,
// Version 2.0.
//
//    (See accompanying file LICENSE-Apache or copy at
//     http://www.apache.org/licenses/LICENSE-2.0)
//
// Alternatively, the contents of this file may be used under the terms of
// the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE-Boost or copy at
//     https://www.boost.org/LICENSE_1_0.txt)
//
// Unless required by applicable law or agreed to in writing, this software
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.

#include <math.h>
#include <inttypes.h>
#include <iostream>
#include <string.h>
#include <chrono>
#include <random>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#if defined(__linux__)
#include <sys/types.h>
#include <unistd.h>
#endif

#include "ryu/ryu.h"
#include "third_party/double-conversion/double-conversion/utils.h"
#include "third_party/double-conversion/double-conversion/double-conversion.h"

using double_conversion::StringBuilder;
using double_conversion::DoubleToStringConverter;
using namespace std::chrono;

constexpr int BUFFER_SIZE = 40;
static char buffer[BUFFER_SIZE];
static DoubleToStringConverter converter(
    DoubleToStringConverter::Flags::EMIT_TRAILING_DECIMAL_POINT
        | DoubleToStringConverter::Flags::EMIT_TRAILING_ZERO_AFTER_POINT,
    "Infinity",
    "NaN",
    'E',
    7,
    7,
    0,
    0);
static StringBuilder builder(buffer, BUFFER_SIZE);

void fcv(float value) {
  builder.Reset();
  converter.ToShortestSingle(value, &builder);
  builder.Finalize();
}

void dcv(double value) {
  builder.Reset();
  converter.ToShortest(value, &builder);
  builder.Finalize();
}

static float int32Bits2Float(uint32_t bits) {
  float f;
  memcpy(&f, &bits, sizeof(float));
  return f;
}

static double int64Bits2Double(uint64_t bits) {
  double f;
  memcpy(&f, &bits, sizeof(double));
  return f;
}

struct mean_and_variance {
  int64_t n = 0;
  double mean = 0;
  double m2 = 0;

  void update(double x) {
    ++n;
    double d = x - mean;
    mean += d / n;
    double d2 = x - mean;
    m2 += d * d2;
  }

  double variance() const {
    return m2 / (n - 1);
  }

  double stddev() const {
    return sqrt(variance());
  }
};

float generate_float(std::mt19937& mt32) {
  uint32_t r = mt32();
  float f = int32Bits2Float(r);
  return f;
}

static int bench32(int samples, int iterations, bool verbose, bool ryu_only, bool invert) {
  char bufferown[BUFFER_SIZE];
  std::mt19937 mt32(12345);
  mean_and_variance mv1;
  mean_and_variance mv2;
  int throwaway = 0;
  if (!invert) {
    for (int i = 0; i < samples; ++i) {
      const float f = generate_float(mt32);

      auto t1 = steady_clock::now();
      for (int j = 0; j < iterations; ++j) {
        f2s_buffered(f, bufferown);
        throwaway += bufferown[2];
      }
      auto t2 = steady_clock::now();
      double delta1 = duration_cast<nanoseconds>(t2 - t1).count() / static_cast<double>(iterations);
      mv1.update(delta1);

      double delta2 = 0.0;
      if (!ryu_only) {
        t1 = steady_clock::now();
        for (int j = 0; j < iterations; ++j) {
          fcv(f);
          throwaway += buffer[2];
        }
        t2 = steady_clock::now();
        delta2 = duration_cast<nanoseconds>(t2 - t1).count() / static_cast<double>(iterations);
        mv2.update(delta2);
      }

      if (verbose) {
        if (ryu_only) {
          printf("%.6a,%f\n", f, delta1);
        } else {
          printf("%.6a,%f,%f\n", f, delta1, delta2);
        }
      }

      if (!ryu_only && strcmp(bufferown, buffer) != 0) {
        printf("For %.6a %20s %20s\n", f, bufferown, buffer);
      }
    }
  } else {
    std::vector<float> vec(samples);
    for (int i = 0; i < samples; ++i) {
      vec[i] = generate_float(mt32);
    }

    for (int j = 0; j < iterations; ++j) {
      auto t1 = steady_clock::now();
      for (int i = 0; i < samples; ++i) {
        f2s_buffered(vec[i], bufferown);
        throwaway += bufferown[2];
      }
      auto t2 = steady_clock::now();
      double delta1 = duration_cast<nanoseconds>(t2 - t1).count() / static_cast<double>(samples);
      mv1.update(delta1);

      double delta2 = 0.0;
      if (!ryu_only) {
        t1 = steady_clock::now();
        for (int i = 0; i < samples; ++i) {
          fcv(vec[i]);
          throwaway += buffer[2];
        }
        t2 = steady_clock::now();
        delta2 = duration_cast<nanoseconds>(t2 - t1).count() / static_cast<double>(samples);
        mv2.update(delta2);
      }

      if (verbose) {
        if (ryu_only) {
          printf("%f\n", delta1);
        } else {
          printf("%f,%f\n", delta1, delta2);
        }
      }
    }
  }
  if (!verbose) {
    printf("32: %8.3f %8.3f", mv1.mean, mv1.stddev());
    if (!ryu_only) {
      printf("     %8.3f %8.3f", mv2.mean, mv2.stddev());
    }
    printf("\n");
  }
  return throwaway;
}

double generate_double(std::mt19937& mt32) {
  uint64_t r = mt32();
  r <<= 32;
  r |= mt32(); // calling mt32() in separate statements guarantees order of evaluation
  double f = int64Bits2Double(r);
  return f;
}

static int bench64(int samples, int iterations, bool verbose, bool ryu_only, bool invert) {
  char bufferown[BUFFER_SIZE];
  std::mt19937 mt32(12345);
  mean_and_variance mv1;
  mean_and_variance mv2;
  int throwaway = 0;
  if (!invert) {
    for (int i = 0; i < samples; ++i) {
      const double f = generate_double(mt32);

      auto t1 = steady_clock::now();
      for (int j = 0; j < iterations; ++j) {
        d2s_buffered(f, bufferown);
        throwaway += bufferown[2];
      }
      auto t2 = steady_clock::now();
      double delta1 = duration_cast<nanoseconds>(t2 - t1).count() / static_cast<double>(iterations);
      mv1.update(delta1);

      double delta2 = 0.0;
      if (!ryu_only) {
        t1 = steady_clock::now();
        for (int j = 0; j < iterations; ++j) {
          dcv(f);
          throwaway += buffer[2];
        }
        t2 = steady_clock::now();
        delta2 = duration_cast<nanoseconds>(t2 - t1).count() / static_cast<double>(iterations);
        mv2.update(delta2);
      }

      if (verbose) {
        if (ryu_only) {
          printf("%.13a,%f\n", f, delta1);
        } else {
          printf("%.13a,%f,%f\n", f, delta1, delta2);
        }
      }

      if (!ryu_only && strcmp(bufferown, buffer) != 0) {
        printf("For %.13a %28s %28s\n", f, bufferown, buffer);
      }
    }
  } else {
    std::vector<double> vec(samples);
    for (int i = 0; i < samples; ++i) {
      vec[i] = generate_double(mt32);
    }

    for (int j = 0; j < iterations; ++j) {
      auto t1 = steady_clock::now();
      for (int i = 0; i < samples; ++i) {
        d2s_buffered(vec[i], bufferown);
        throwaway += bufferown[2];
      }
      auto t2 = steady_clock::now();
      double delta1 = duration_cast<nanoseconds>(t2 - t1).count() / static_cast<double>(samples);
      mv1.update(delta1);

      double delta2 = 0.0;
      if (!ryu_only) {
        t1 = steady_clock::now();
        for (int i = 0; i < samples; ++i) {
          dcv(vec[i]);
          throwaway += buffer[2];
        }
        t2 = steady_clock::now();
        delta2 = duration_cast<nanoseconds>(t2 - t1).count() / static_cast<double>(samples);
        mv2.update(delta2);
      }

      if (verbose) {
        if (ryu_only) {
          printf("%f\n", delta1);
        } else {
          printf("%f,%f\n", delta1, delta2);
        }
      }
    }
  }
  if (!verbose) {
    printf("64: %8.3f %8.3f", mv1.mean, mv1.stddev());
    if (!ryu_only) {
      printf("     %8.3f %8.3f", mv2.mean, mv2.stddev());
    }
    printf("\n");
  }
  return throwaway;
}

int main(int argc, char** argv) {
#if defined(__linux__)
  // Also disable hyperthreading with something like this:
  // cat /sys/devices/system/cpu/cpu*/topology/core_id
  // sudo /bin/bash -c "echo 0 > /sys/devices/system/cpu/cpu6/online"
  cpu_set_t my_set;
  CPU_ZERO(&my_set);
  CPU_SET(2, &my_set);
  sched_setaffinity(getpid(), sizeof(cpu_set_t), &my_set);
#endif

  // By default, run both 32 and 64-bit benchmarks with 10000 samples and 1000 iterations each.
  bool run32 = true;
  bool run64 = true;
  int samples = 10000;
  int iterations = 1000;
  bool verbose = false;
  bool ryu_only = false;
  bool invert = false;
  for (int i = 1; i < argc; ++i) {
    if (strcmp(argv[i], "-32") == 0) {
      run32 = true;
      run64 = false;
    } else if (strcmp(argv[i], "-64") == 0) {
      run32 = false;
      run64 = true;
    } else if (strcmp(argv[i], "-v") == 0) {
      verbose = true;
    } else if (strcmp(argv[i], "-ryu") == 0) {
      ryu_only = true;
    } else if (strcmp(argv[i], "-invert") == 0) {
      invert = true;
    } else if (strncmp(argv[i], "-samples=", 9) == 0) {
      sscanf(argv[i], "-samples=%i", &samples);
    } else if (strncmp(argv[i], "-iterations=", 12) == 0) {
      sscanf(argv[i], "-iterations=%i", &iterations);
    } else {
      printf("Unrecognized option '%s'.\n", argv[i]);
      return EXIT_FAILURE;
    }
  }

  if (!verbose) {
    // No need to buffer the output if we're just going to print three lines.
    setbuf(stdout, NULL);
  }

  if (verbose) {
    printf("%sryu_time_in_ns%s\n", invert ? "" : "hexfloat,", ryu_only ? "" : ",grisu3_time_in_ns");
  } else {
    printf("    Average & Stddev Ryu%s\n", ryu_only ? "" : "  Average & Stddev Grisu3");
  }
  int throwaway = 0;
  if (run32) {
    throwaway += bench32(samples, iterations, verbose, ryu_only, invert);
  }
  if (run64) {
    throwaway += bench64(samples, iterations, verbose, ryu_only, invert);
  }
  if (argc == 1000) {
    // Prevent the compiler from optimizing the code away.
    printf("%d\n", throwaway);
  }
  return 0;
}
<commit_msg>benchmark.cc: Default to inverted mode, add "-classic".<commit_after>// Copyright 2018 Ulf Adams
//
// The contents of this file may be used under the terms of the Apache License,
// Version 2.0.
//
//    (See accompanying file LICENSE-Apache or copy at
//     http://www.apache.org/licenses/LICENSE-2.0)
//
// Alternatively, the contents of this file may be used under the terms of
// the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE-Boost or copy at
//     https://www.boost.org/LICENSE_1_0.txt)
//
// Unless required by applicable law or agreed to in writing, this software
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.

#include <math.h>
#include <inttypes.h>
#include <iostream>
#include <string.h>
#include <chrono>
#include <random>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#if defined(__linux__)
#include <sys/types.h>
#include <unistd.h>
#endif

#include "ryu/ryu.h"
#include "third_party/double-conversion/double-conversion/utils.h"
#include "third_party/double-conversion/double-conversion/double-conversion.h"

using double_conversion::StringBuilder;
using double_conversion::DoubleToStringConverter;
using namespace std::chrono;

constexpr int BUFFER_SIZE = 40;
static char buffer[BUFFER_SIZE];
static DoubleToStringConverter converter(
    DoubleToStringConverter::Flags::EMIT_TRAILING_DECIMAL_POINT
        | DoubleToStringConverter::Flags::EMIT_TRAILING_ZERO_AFTER_POINT,
    "Infinity",
    "NaN",
    'E',
    7,
    7,
    0,
    0);
static StringBuilder builder(buffer, BUFFER_SIZE);

void fcv(float value) {
  builder.Reset();
  converter.ToShortestSingle(value, &builder);
  builder.Finalize();
}

void dcv(double value) {
  builder.Reset();
  converter.ToShortest(value, &builder);
  builder.Finalize();
}

static float int32Bits2Float(uint32_t bits) {
  float f;
  memcpy(&f, &bits, sizeof(float));
  return f;
}

static double int64Bits2Double(uint64_t bits) {
  double f;
  memcpy(&f, &bits, sizeof(double));
  return f;
}

struct mean_and_variance {
  int64_t n = 0;
  double mean = 0;
  double m2 = 0;

  void update(double x) {
    ++n;
    double d = x - mean;
    mean += d / n;
    double d2 = x - mean;
    m2 += d * d2;
  }

  double variance() const {
    return m2 / (n - 1);
  }

  double stddev() const {
    return sqrt(variance());
  }
};

float generate_float(std::mt19937& mt32) {
  uint32_t r = mt32();
  float f = int32Bits2Float(r);
  return f;
}

static int bench32(int samples, int iterations, bool verbose, bool ryu_only, bool classic) {
  char bufferown[BUFFER_SIZE];
  std::mt19937 mt32(12345);
  mean_and_variance mv1;
  mean_and_variance mv2;
  int throwaway = 0;
  if (classic) {
    for (int i = 0; i < samples; ++i) {
      const float f = generate_float(mt32);

      auto t1 = steady_clock::now();
      for (int j = 0; j < iterations; ++j) {
        f2s_buffered(f, bufferown);
        throwaway += bufferown[2];
      }
      auto t2 = steady_clock::now();
      double delta1 = duration_cast<nanoseconds>(t2 - t1).count() / static_cast<double>(iterations);
      mv1.update(delta1);

      double delta2 = 0.0;
      if (!ryu_only) {
        t1 = steady_clock::now();
        for (int j = 0; j < iterations; ++j) {
          fcv(f);
          throwaway += buffer[2];
        }
        t2 = steady_clock::now();
        delta2 = duration_cast<nanoseconds>(t2 - t1).count() / static_cast<double>(iterations);
        mv2.update(delta2);
      }

      if (verbose) {
        if (ryu_only) {
          printf("%.6a,%f\n", f, delta1);
        } else {
          printf("%.6a,%f,%f\n", f, delta1, delta2);
        }
      }

      if (!ryu_only && strcmp(bufferown, buffer) != 0) {
        printf("For %.6a %20s %20s\n", f, bufferown, buffer);
      }
    }
  } else {
    std::vector<float> vec(samples);
    for (int i = 0; i < samples; ++i) {
      vec[i] = generate_float(mt32);
    }

    for (int j = 0; j < iterations; ++j) {
      auto t1 = steady_clock::now();
      for (int i = 0; i < samples; ++i) {
        f2s_buffered(vec[i], bufferown);
        throwaway += bufferown[2];
      }
      auto t2 = steady_clock::now();
      double delta1 = duration_cast<nanoseconds>(t2 - t1).count() / static_cast<double>(samples);
      mv1.update(delta1);

      double delta2 = 0.0;
      if (!ryu_only) {
        t1 = steady_clock::now();
        for (int i = 0; i < samples; ++i) {
          fcv(vec[i]);
          throwaway += buffer[2];
        }
        t2 = steady_clock::now();
        delta2 = duration_cast<nanoseconds>(t2 - t1).count() / static_cast<double>(samples);
        mv2.update(delta2);
      }

      if (verbose) {
        if (ryu_only) {
          printf("%f\n", delta1);
        } else {
          printf("%f,%f\n", delta1, delta2);
        }
      }
    }
  }
  if (!verbose) {
    printf("32: %8.3f %8.3f", mv1.mean, mv1.stddev());
    if (!ryu_only) {
      printf("     %8.3f %8.3f", mv2.mean, mv2.stddev());
    }
    printf("\n");
  }
  return throwaway;
}

double generate_double(std::mt19937& mt32) {
  uint64_t r = mt32();
  r <<= 32;
  r |= mt32(); // calling mt32() in separate statements guarantees order of evaluation
  double f = int64Bits2Double(r);
  return f;
}

static int bench64(int samples, int iterations, bool verbose, bool ryu_only, bool classic) {
  char bufferown[BUFFER_SIZE];
  std::mt19937 mt32(12345);
  mean_and_variance mv1;
  mean_and_variance mv2;
  int throwaway = 0;
  if (classic) {
    for (int i = 0; i < samples; ++i) {
      const double f = generate_double(mt32);

      auto t1 = steady_clock::now();
      for (int j = 0; j < iterations; ++j) {
        d2s_buffered(f, bufferown);
        throwaway += bufferown[2];
      }
      auto t2 = steady_clock::now();
      double delta1 = duration_cast<nanoseconds>(t2 - t1).count() / static_cast<double>(iterations);
      mv1.update(delta1);

      double delta2 = 0.0;
      if (!ryu_only) {
        t1 = steady_clock::now();
        for (int j = 0; j < iterations; ++j) {
          dcv(f);
          throwaway += buffer[2];
        }
        t2 = steady_clock::now();
        delta2 = duration_cast<nanoseconds>(t2 - t1).count() / static_cast<double>(iterations);
        mv2.update(delta2);
      }

      if (verbose) {
        if (ryu_only) {
          printf("%.13a,%f\n", f, delta1);
        } else {
          printf("%.13a,%f,%f\n", f, delta1, delta2);
        }
      }

      if (!ryu_only && strcmp(bufferown, buffer) != 0) {
        printf("For %.13a %28s %28s\n", f, bufferown, buffer);
      }
    }
  } else {
    std::vector<double> vec(samples);
    for (int i = 0; i < samples; ++i) {
      vec[i] = generate_double(mt32);
    }

    for (int j = 0; j < iterations; ++j) {
      auto t1 = steady_clock::now();
      for (int i = 0; i < samples; ++i) {
        d2s_buffered(vec[i], bufferown);
        throwaway += bufferown[2];
      }
      auto t2 = steady_clock::now();
      double delta1 = duration_cast<nanoseconds>(t2 - t1).count() / static_cast<double>(samples);
      mv1.update(delta1);

      double delta2 = 0.0;
      if (!ryu_only) {
        t1 = steady_clock::now();
        for (int i = 0; i < samples; ++i) {
          dcv(vec[i]);
          throwaway += buffer[2];
        }
        t2 = steady_clock::now();
        delta2 = duration_cast<nanoseconds>(t2 - t1).count() / static_cast<double>(samples);
        mv2.update(delta2);
      }

      if (verbose) {
        if (ryu_only) {
          printf("%f\n", delta1);
        } else {
          printf("%f,%f\n", delta1, delta2);
        }
      }
    }
  }
  if (!verbose) {
    printf("64: %8.3f %8.3f", mv1.mean, mv1.stddev());
    if (!ryu_only) {
      printf("     %8.3f %8.3f", mv2.mean, mv2.stddev());
    }
    printf("\n");
  }
  return throwaway;
}

int main(int argc, char** argv) {
#if defined(__linux__)
  // Also disable hyperthreading with something like this:
  // cat /sys/devices/system/cpu/cpu*/topology/core_id
  // sudo /bin/bash -c "echo 0 > /sys/devices/system/cpu/cpu6/online"
  cpu_set_t my_set;
  CPU_ZERO(&my_set);
  CPU_SET(2, &my_set);
  sched_setaffinity(getpid(), sizeof(cpu_set_t), &my_set);
#endif

  // By default, run both 32 and 64-bit benchmarks with 10000 samples and 1000 iterations each.
  bool run32 = true;
  bool run64 = true;
  int samples = 10000;
  int iterations = 1000;
  bool verbose = false;
  bool ryu_only = false;
  bool classic = false;
  for (int i = 1; i < argc; ++i) {
    if (strcmp(argv[i], "-32") == 0) {
      run32 = true;
      run64 = false;
    } else if (strcmp(argv[i], "-64") == 0) {
      run32 = false;
      run64 = true;
    } else if (strcmp(argv[i], "-v") == 0) {
      verbose = true;
    } else if (strcmp(argv[i], "-ryu") == 0) {
      ryu_only = true;
    } else if (strcmp(argv[i], "-classic") == 0) {
      classic = true;
    } else if (strncmp(argv[i], "-samples=", 9) == 0) {
      sscanf(argv[i], "-samples=%i", &samples);
    } else if (strncmp(argv[i], "-iterations=", 12) == 0) {
      sscanf(argv[i], "-iterations=%i", &iterations);
    } else {
      printf("Unrecognized option '%s'.\n", argv[i]);
      return EXIT_FAILURE;
    }
  }

  if (!verbose) {
    // No need to buffer the output if we're just going to print three lines.
    setbuf(stdout, NULL);
  }

  if (verbose) {
    printf("%sryu_time_in_ns%s\n", classic ? "hexfloat," : "", ryu_only ? "" : ",grisu3_time_in_ns");
  } else {
    printf("    Average & Stddev Ryu%s\n", ryu_only ? "" : "  Average & Stddev Grisu3");
  }
  int throwaway = 0;
  if (run32) {
    throwaway += bench32(samples, iterations, verbose, ryu_only, classic);
  }
  if (run64) {
    throwaway += bench64(samples, iterations, verbose, ryu_only, classic);
  }
  if (argc == 1000) {
    // Prevent the compiler from optimizing the code away.
    printf("%d\n", throwaway);
  }
  return 0;
}
<|endoftext|>


<commit_before>
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkBenchmark.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkDashPathEffect.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkRandom.h"
#include "SkString.h"
#include "SkTDArray.h"

/*
 *  Cases to consider:
 *
 *  1. antialiasing on/off (esp. width <= 1)
 *  2. strokewidth == 0, 1, 2
 *  3. hline, vline, diagonal, rect, oval
 *  4. dots [1,1] ([N,N] where N=strokeWidth?) or arbitrary (e.g. [2,1] or [1,2,3,2])
 */
static void path_hline(SkPath* path) {
    path->moveTo(SkIntToScalar(10), SkIntToScalar(10));
    path->lineTo(SkIntToScalar(600), SkIntToScalar(10));
}

class DashBench : public SkBenchmark {
protected:
    SkString            fName;
    SkTDArray<SkScalar> fIntervals;
    int                 fWidth;
    SkPoint             fPts[2];
    bool                fDoClip;

    enum {
        N = SkBENCHLOOP(100)
    };
public:
    DashBench(void* param, const SkScalar intervals[], int count, int width,
              bool doClip = false) : INHERITED(param) {
        fIntervals.append(count, intervals);
        for (int i = 0; i < count; ++i) {
            fIntervals[i] *= width;
        }
        fWidth = width;
        fName.printf("dash_%d_%s", width, doClip ? "clipped" : "noclip");
        fDoClip = doClip;

        fPts[0].set(SkIntToScalar(10), SkIntToScalar(10));
        fPts[1].set(SkIntToScalar(600), SkIntToScalar(10));
    }

    virtual void makePath(SkPath* path) {
        path_hline(path);
    }

protected:
    virtual const char* onGetName() SK_OVERRIDE {
        return fName.c_str();
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        SkPaint paint;
        this->setupPaint(&paint);
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setStrokeWidth(SkIntToScalar(fWidth));
        paint.setAntiAlias(false);

        SkPath path;
        this->makePath(&path);

        paint.setPathEffect(new SkDashPathEffect(fIntervals.begin(),
                                                 fIntervals.count(), 0))->unref();

        if (fDoClip) {
            SkRect r = path.getBounds();
            r.inset(-SkIntToScalar(20), -SkIntToScalar(20));
            // now move it so we don't intersect
            r.offset(0, r.height() * 3 / 2);
            canvas->clipRect(r);
        }

        this->handlePath(canvas, path, paint, N);
    }

    virtual void handlePath(SkCanvas* canvas, const SkPath& path,
                            const SkPaint& paint, int N) {
        for (int i = 0; i < N; ++i) {
//            canvas->drawPoints(SkCanvas::kLines_PointMode, 2, fPts, paint);
            canvas->drawPath(path, paint);
        }
    }

private:
    typedef SkBenchmark INHERITED;
};

class RectDashBench : public DashBench {
public:
    RectDashBench(void* param, const SkScalar intervals[], int count, int width, bool doClip = false)
    : INHERITED(param, intervals, count, width) {
        fName.append("_rect");
    }

protected:
    virtual void handlePath(SkCanvas* canvas, const SkPath& path,
                            const SkPaint& paint, int N) SK_OVERRIDE {
        SkPoint pts[2];
        if (!path.isLine(pts) || pts[0].fY != pts[1].fY) {
            this->INHERITED::handlePath(canvas, path, paint, N);
        } else {
            SkRect rect;
            rect.fLeft = pts[0].fX;
            rect.fTop = pts[0].fY - paint.getStrokeWidth() / 2;
            rect.fRight = rect.fLeft + SkIntToScalar(fWidth);
            rect.fBottom = rect.fTop + paint.getStrokeWidth();

            SkPaint p(paint);
            p.setStyle(SkPaint::kFill_Style);
            p.setPathEffect(NULL);

            int count = SkScalarRoundToInt((pts[1].fX - pts[0].fX) / (2*fWidth));
            SkScalar dx = SkIntToScalar(2 * fWidth);

            for (int i = 0; i < N*10; ++i) {
                SkRect r = rect;
                for (int j = 0; j < count; ++j) {
                    canvas->drawRect(r, p);
                    r.offset(dx, 0);
                }
            }
        }
    }

private:
    typedef DashBench INHERITED;
};

static void make_unit_star(SkPath* path, int n) {
    SkScalar rad = -SK_ScalarPI / 2;
    const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n;

    path->moveTo(0, -SK_Scalar1);
    for (int i = 1; i < n; i++) {
        rad += drad;
        SkScalar cosV, sinV = SkScalarSinCos(rad, &cosV);
        path->lineTo(cosV, sinV);
    }
    path->close();
}

static void make_poly(SkPath* path) {
    make_unit_star(path, 9);
    SkMatrix matrix;
    matrix.setScale(SkIntToScalar(100), SkIntToScalar(100));
    path->transform(matrix);
}

static void make_quad(SkPath* path) {
    SkScalar x0 = SkIntToScalar(10);
    SkScalar y0 = SkIntToScalar(10);
    path->moveTo(x0, y0);
    path->quadTo(x0,                    y0 + 400 * SK_Scalar1,
                 x0 + 600 * SK_Scalar1, y0 + 400 * SK_Scalar1);
}

static void make_cubic(SkPath* path) {
    SkScalar x0 = SkIntToScalar(10);
    SkScalar y0 = SkIntToScalar(10);
    path->moveTo(x0, y0);
    path->cubicTo(x0,                    y0 + 400 * SK_Scalar1,
                  x0 + 600 * SK_Scalar1, y0 + 400 * SK_Scalar1,
                  x0 + 600 * SK_Scalar1, y0);
}

class MakeDashBench : public SkBenchmark {
    SkString fName;
    SkPath   fPath;
    SkAutoTUnref<SkPathEffect> fPE;

    enum {
        N = SkBENCHLOOP(400)
    };

public:
    MakeDashBench(void* param, void (*proc)(SkPath*), const char name[]) : INHERITED(param) {
        fName.printf("makedash_%s", name);
        proc(&fPath);

        SkScalar vals[] = { SkIntToScalar(4), SkIntToScalar(4) };
        fPE.reset(new SkDashPathEffect(vals, 2, 0));
    }

protected:
    virtual const char* onGetName() SK_OVERRIDE {
        return fName.c_str();
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        SkPath dst;
        for (int i = 0; i < N; ++i) {
            SkStrokeRec rec(SkStrokeRec::kHairline_InitStyle);

            fPE->filterPath(&dst, fPath, &rec);
            dst.rewind();
        }
    }

private:
    typedef SkBenchmark INHERITED;
};

class DashLineBench : public SkBenchmark {
    SkString fName;
    SkPath   fPath;
    SkAutoTUnref<SkPathEffect> fPE;

    enum {
        N = SkBENCHLOOP(200)
    };

public:
    DashLineBench(void* param) : INHERITED(param) {
        fName.printf("dashline");

        SkScalar vals[] = { SkIntToScalar(1), SkIntToScalar(1) };
        fPE.reset(new SkDashPathEffect(vals, 2, 0));
    }

protected:
    virtual const char* onGetName() SK_OVERRIDE {
        return fName.c_str();
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        SkPaint paint;
        this->setupPaint(&paint);
        paint.setStrokeWidth(1);
        paint.setPathEffect(fPE);
        for (int i = 0; i < N; ++i) {
            canvas->drawLine(10, 10, 640, 10, paint);
        }
    }

private:
    typedef SkBenchmark INHERITED;
};

///////////////////////////////////////////////////////////////////////////////

static const SkScalar gDots[] = { SK_Scalar1, SK_Scalar1 };

#define PARAM(array)    array, SK_ARRAY_COUNT(array)

static SkBenchmark* gF0(void* p) { return new DashBench(p, PARAM(gDots), 0); }
static SkBenchmark* gF1(void* p) { return new DashBench(p, PARAM(gDots), 1); }
static SkBenchmark* gF2(void* p) { return new DashBench(p, PARAM(gDots), 1, true); }
static SkBenchmark* gF3(void* p) { return new DashBench(p, PARAM(gDots), 4); }
static SkBenchmark* gF4(void* p) { return new MakeDashBench(p, make_poly, "poly"); }
static SkBenchmark* gF5(void* p) { return new MakeDashBench(p, make_quad, "quad"); }
static SkBenchmark* gF6(void* p) { return new MakeDashBench(p, make_cubic, "cubic"); }
static SkBenchmark* gF7(void* p) { return new DashLineBench(p); }

static BenchRegistry gR0(gF0);
static BenchRegistry gR1(gF1);
static BenchRegistry gR2(gF2);
static BenchRegistry gR3(gF3);
static BenchRegistry gR4(gF4);
static BenchRegistry gR5(gF5);
static BenchRegistry gR6(gF6);
static BenchRegistry gR7(gF7);
<commit_msg>add more cases to dashline: circle-vs-square, 0,1,2 stroke_width<commit_after>
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkBenchmark.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkDashPathEffect.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkRandom.h"
#include "SkString.h"
#include "SkTDArray.h"

/*
 *  Cases to consider:
 *
 *  1. antialiasing on/off (esp. width <= 1)
 *  2. strokewidth == 0, 1, 2
 *  3. hline, vline, diagonal, rect, oval
 *  4. dots [1,1] ([N,N] where N=strokeWidth?) or arbitrary (e.g. [2,1] or [1,2,3,2])
 */
static void path_hline(SkPath* path) {
    path->moveTo(SkIntToScalar(10), SkIntToScalar(10));
    path->lineTo(SkIntToScalar(600), SkIntToScalar(10));
}

class DashBench : public SkBenchmark {
protected:
    SkString            fName;
    SkTDArray<SkScalar> fIntervals;
    int                 fWidth;
    SkPoint             fPts[2];
    bool                fDoClip;

    enum {
        N = SkBENCHLOOP(100)
    };
public:
    DashBench(void* param, const SkScalar intervals[], int count, int width,
              bool doClip = false) : INHERITED(param) {
        fIntervals.append(count, intervals);
        for (int i = 0; i < count; ++i) {
            fIntervals[i] *= width;
        }
        fWidth = width;
        fName.printf("dash_%d_%s", width, doClip ? "clipped" : "noclip");
        fDoClip = doClip;

        fPts[0].set(SkIntToScalar(10), SkIntToScalar(10));
        fPts[1].set(SkIntToScalar(600), SkIntToScalar(10));
    }

    virtual void makePath(SkPath* path) {
        path_hline(path);
    }

protected:
    virtual const char* onGetName() SK_OVERRIDE {
        return fName.c_str();
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        SkPaint paint;
        this->setupPaint(&paint);
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setStrokeWidth(SkIntToScalar(fWidth));
        paint.setAntiAlias(false);

        SkPath path;
        this->makePath(&path);

        paint.setPathEffect(new SkDashPathEffect(fIntervals.begin(),
                                                 fIntervals.count(), 0))->unref();

        if (fDoClip) {
            SkRect r = path.getBounds();
            r.inset(-SkIntToScalar(20), -SkIntToScalar(20));
            // now move it so we don't intersect
            r.offset(0, r.height() * 3 / 2);
            canvas->clipRect(r);
        }

        this->handlePath(canvas, path, paint, N);
    }

    virtual void handlePath(SkCanvas* canvas, const SkPath& path,
                            const SkPaint& paint, int N) {
        for (int i = 0; i < N; ++i) {
//            canvas->drawPoints(SkCanvas::kLines_PointMode, 2, fPts, paint);
            canvas->drawPath(path, paint);
        }
    }

private:
    typedef SkBenchmark INHERITED;
};

class RectDashBench : public DashBench {
public:
    RectDashBench(void* param, const SkScalar intervals[], int count, int width, bool doClip = false)
    : INHERITED(param, intervals, count, width) {
        fName.append("_rect");
    }

protected:
    virtual void handlePath(SkCanvas* canvas, const SkPath& path,
                            const SkPaint& paint, int N) SK_OVERRIDE {
        SkPoint pts[2];
        if (!path.isLine(pts) || pts[0].fY != pts[1].fY) {
            this->INHERITED::handlePath(canvas, path, paint, N);
        } else {
            SkRect rect;
            rect.fLeft = pts[0].fX;
            rect.fTop = pts[0].fY - paint.getStrokeWidth() / 2;
            rect.fRight = rect.fLeft + SkIntToScalar(fWidth);
            rect.fBottom = rect.fTop + paint.getStrokeWidth();

            SkPaint p(paint);
            p.setStyle(SkPaint::kFill_Style);
            p.setPathEffect(NULL);

            int count = SkScalarRoundToInt((pts[1].fX - pts[0].fX) / (2*fWidth));
            SkScalar dx = SkIntToScalar(2 * fWidth);

            for (int i = 0; i < N*10; ++i) {
                SkRect r = rect;
                for (int j = 0; j < count; ++j) {
                    canvas->drawRect(r, p);
                    r.offset(dx, 0);
                }
            }
        }
    }

private:
    typedef DashBench INHERITED;
};

static void make_unit_star(SkPath* path, int n) {
    SkScalar rad = -SK_ScalarPI / 2;
    const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n;

    path->moveTo(0, -SK_Scalar1);
    for (int i = 1; i < n; i++) {
        rad += drad;
        SkScalar cosV, sinV = SkScalarSinCos(rad, &cosV);
        path->lineTo(cosV, sinV);
    }
    path->close();
}

static void make_poly(SkPath* path) {
    make_unit_star(path, 9);
    SkMatrix matrix;
    matrix.setScale(SkIntToScalar(100), SkIntToScalar(100));
    path->transform(matrix);
}

static void make_quad(SkPath* path) {
    SkScalar x0 = SkIntToScalar(10);
    SkScalar y0 = SkIntToScalar(10);
    path->moveTo(x0, y0);
    path->quadTo(x0,                    y0 + 400 * SK_Scalar1,
                 x0 + 600 * SK_Scalar1, y0 + 400 * SK_Scalar1);
}

static void make_cubic(SkPath* path) {
    SkScalar x0 = SkIntToScalar(10);
    SkScalar y0 = SkIntToScalar(10);
    path->moveTo(x0, y0);
    path->cubicTo(x0,                    y0 + 400 * SK_Scalar1,
                  x0 + 600 * SK_Scalar1, y0 + 400 * SK_Scalar1,
                  x0 + 600 * SK_Scalar1, y0);
}

class MakeDashBench : public SkBenchmark {
    SkString fName;
    SkPath   fPath;
    SkAutoTUnref<SkPathEffect> fPE;

    enum {
        N = SkBENCHLOOP(400)
    };

public:
    MakeDashBench(void* param, void (*proc)(SkPath*), const char name[]) : INHERITED(param) {
        fName.printf("makedash_%s", name);
        proc(&fPath);

        SkScalar vals[] = { SkIntToScalar(4), SkIntToScalar(4) };
        fPE.reset(new SkDashPathEffect(vals, 2, 0));
    }

protected:
    virtual const char* onGetName() SK_OVERRIDE {
        return fName.c_str();
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        SkPath dst;
        for (int i = 0; i < N; ++i) {
            SkStrokeRec rec(SkStrokeRec::kHairline_InitStyle);

            fPE->filterPath(&dst, fPath, &rec);
            dst.rewind();
        }
    }

private:
    typedef SkBenchmark INHERITED;
};

/*
 *  We try to special case square dashes (intervals are equal to strokewidth).
 */
class DashLineBench : public SkBenchmark {
    SkString fName;
    SkPath   fPath;
    SkScalar fStrokeWidth;
    bool     fIsRound;
    SkAutoTUnref<SkPathEffect> fPE;

    enum {
        N = SkBENCHLOOP(200)
    };

public:
    DashLineBench(void* param, SkScalar width, bool isRound) : INHERITED(param) {
        fName.printf("dashline_%g_%s", SkScalarToFloat(width), isRound ? "circle" : "square");
        fStrokeWidth = width;
        fIsRound = isRound;

        SkScalar vals[] = { SK_Scalar1, SK_Scalar1 };
        fPE.reset(new SkDashPathEffect(vals, 2, 0));
    }

protected:
    virtual const char* onGetName() SK_OVERRIDE {
        return fName.c_str();
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        SkPaint paint;
        this->setupPaint(&paint);
        paint.setStrokeWidth(fStrokeWidth);
        paint.setStrokeCap(fIsRound ? SkPaint::kRound_Cap : SkPaint::kSquare_Cap);
        paint.setPathEffect(fPE);
        for (int i = 0; i < N; ++i) {
            canvas->drawLine(10 * SK_Scalar1, 10 * SK_Scalar1,
                             640 * SK_Scalar1, 10 * SK_Scalar1, paint);
        }
    }

private:
    typedef SkBenchmark INHERITED;
};

///////////////////////////////////////////////////////////////////////////////

static const SkScalar gDots[] = { SK_Scalar1, SK_Scalar1 };

#define PARAM(array)    array, SK_ARRAY_COUNT(array)

static SkBenchmark* gF0(void* p) { return new DashBench(p, PARAM(gDots), 0); }
static SkBenchmark* gF1(void* p) { return new DashBench(p, PARAM(gDots), 1); }
static SkBenchmark* gF2(void* p) { return new DashBench(p, PARAM(gDots), 1, true); }
static SkBenchmark* gF3(void* p) { return new DashBench(p, PARAM(gDots), 4); }
static SkBenchmark* gF4(void* p) { return new MakeDashBench(p, make_poly, "poly"); }
static SkBenchmark* gF5(void* p) { return new MakeDashBench(p, make_quad, "quad"); }
static SkBenchmark* gF6(void* p) { return new MakeDashBench(p, make_cubic, "cubic"); }
static SkBenchmark* gF700(void* p) { return new DashLineBench(p, 0, false); }
static SkBenchmark* gF710(void* p) { return new DashLineBench(p, SK_Scalar1, false); }
static SkBenchmark* gF720(void* p) { return new DashLineBench(p, 2 * SK_Scalar1, false); }
static SkBenchmark* gF701(void* p) { return new DashLineBench(p, 0, true); }
static SkBenchmark* gF711(void* p) { return new DashLineBench(p, SK_Scalar1, true); }
static SkBenchmark* gF721(void* p) { return new DashLineBench(p, 2 * SK_Scalar1, true); }

static BenchRegistry gR0(gF0);
static BenchRegistry gR1(gF1);
static BenchRegistry gR2(gF2);
static BenchRegistry gR3(gF3);
static BenchRegistry gR4(gF4);
static BenchRegistry gR5(gF5);
static BenchRegistry gR6(gF6);
static BenchRegistry gR700(gF700);
static BenchRegistry gR710(gF710);
static BenchRegistry gR720(gF720);
static BenchRegistry gR701(gF701);
static BenchRegistry gR711(gF711);
static BenchRegistry gR721(gF721);
<|endoftext|>


<commit_before>#include <yamail/resource_pool/async/pool.hpp>

#include <benchmark/benchmark.h>

#include <boost/asio/post.hpp>
#include <boost/numeric/conversion/cast.hpp>

#include <atomic>
#include <condition_variable>
#include <iomanip>
#include <random>
#include <thread>

namespace {

using namespace yamail::resource_pool;

class benchmark_args {
public:
    constexpr benchmark_args sequences(std::size_t value) const {
        auto copy = *this;
        copy.sequences_ = value;
        return copy;
    }

    constexpr std::size_t sequences() const {
        return sequences_;
    }

    constexpr benchmark_args threads(std::size_t value) const {
        auto copy = *this;
        copy.threads_ = value;
        return copy;
    }

    constexpr std::size_t threads() const {
        return threads_;
    }

    constexpr benchmark_args resources(std::size_t value) const {
        auto copy = *this;
        copy.resources_ = value;
        return copy;
    }

    constexpr std::size_t resources() const {
        return resources_;
    }

    constexpr benchmark_args queue_size(std::size_t value) const {
        auto copy = *this;
        copy.queue_size_ = value;
        return copy;
    }

    constexpr std::size_t queue_size() const {
        return queue_size_;
    }

private:
    std::size_t sequences_ = 0;
    std::size_t threads_ = 0;
    std::size_t resources_ = 0;
    std::size_t queue_size_ = 0;
};

struct resource {};

struct context {
    boost::asio::io_context io_context;
    boost::asio::executor_work_guard<boost::asio::io_context::executor_type> guard = boost::asio::make_work_guard(io_context);
    std::atomic_bool stop {false};
    time_traits::duration timeout {std::chrono::milliseconds(100)};
    double recycle_probability {0};
    std::vector<std::chrono::steady_clock::duration> durations;
    std::mutex get_next_mutex;
    std::condition_variable get_next;
    std::unique_lock<std::mutex> get_next_lock {get_next_mutex};
    std::atomic<std::int64_t> ready_count {0};

    void wait_next() {
        if (--ready_count < 0) {
            get_next.wait(get_next_lock);
        }
    }

    void allow_next() {
        ++ready_count;
        get_next.notify_one();
    }

    void finish() {
        stop = true;
        guard.reset();
    }
};

struct callback {
    context& ctx;
    async::pool<resource>& pool;

    void operator ()(const boost::system::error_code& ec, async::pool<resource>::handle handle) {
        impl(ec, std::move(handle));
        if (!ctx.stop) {
            pool.get_auto_waste(ctx.io_context, *this, ctx.timeout);
        }
        ctx.allow_next();
    }

    void impl(const boost::system::error_code& ec, async::pool<resource>::handle handle) {
        static thread_local std::minstd_rand generator(std::hash<std::thread::id>()(std::this_thread::get_id()));
        static std::uniform_real_distribution<> distrubution(0, 1);
        constexpr const double recycle_probability = 0.5;
        if (!ec) {
            if (handle.empty()) {
                handle.reset(resource {});
            }
            if (distrubution(generator) < recycle_probability) {
                handle.recycle();
            }
        }
    }
};

constexpr std::array<benchmark_args, 17> benchmarks{{
    benchmark_args().sequences(1).threads(1).resources(1).queue_size(0), // 0
    benchmark_args().sequences(2).threads(1).resources(1).queue_size(1), // 1
    benchmark_args().sequences(2).threads(1).resources(2).queue_size(0), // 2
    benchmark_args().sequences(10).threads(1).resources(10).queue_size(0), // 3
    benchmark_args().sequences(10).threads(1).resources(1).queue_size(9), // 4
    benchmark_args().sequences(10).threads(1).resources(5).queue_size(5), // 5
    benchmark_args().sequences(10).threads(1).resources(9).queue_size(1), // 6
    benchmark_args().sequences(10).threads(2).resources(5).queue_size(5), // 7
    benchmark_args().sequences(100).threads(1).resources(100).queue_size(0), // 8
    benchmark_args().sequences(100).threads(1).resources(10).queue_size(90), // 9
    benchmark_args().sequences(100).threads(1).resources(50).queue_size(50), // 10
    benchmark_args().sequences(100).threads(1).resources(90).queue_size(10), // 11
    benchmark_args().sequences(100).threads(2).resources(50).queue_size(50), // 12
    benchmark_args().sequences(1000).threads(1).resources(10).queue_size(990), // 13
    benchmark_args().sequences(1000).threads(2).resources(10).queue_size(990), // 14
    benchmark_args().sequences(10000).threads(1).resources(10).queue_size(9990), // 15
    benchmark_args().sequences(10000).threads(2).resources(10).queue_size(9990), // 16
}};

void get_auto_waste(benchmark::State& state) {
    const auto& args = benchmarks[boost::numeric_cast<std::size_t>(state.range(0))];
    context ctx;
    std::vector<std::thread> workers;
    for (std::size_t i = 0; i < args.threads(); ++i) {
        workers.emplace_back(std::thread([&] { return ctx.io_context.run(); }));
    }
    async::pool<resource> pool(args.resources(), args.queue_size());
    callback cb {ctx, pool};
    for (std::size_t i = 0; i < args.sequences(); ++i) {
        pool.get_auto_waste(ctx.io_context, cb, ctx.timeout);
    }
    while (state.KeepRunning()) {
        ctx.wait_next();
    }
    ctx.finish();
    std::for_each(workers.begin(), workers.end(), [] (auto& v) { v.join(); });
}

struct thread_context {
    context impl;
    std::thread thread;

    thread_context()
        : thread([this] { this->impl.io_context.run(); }) {}
};

void get_auto_waste_io_context_per_thread(benchmark::State& state) {
    const auto& args = benchmarks[boost::numeric_cast<std::size_t>(state.range(0))];
    std::vector<std::unique_ptr<thread_context>> threads;
    for (std::size_t i = 0; i < args.threads(); ++i) {
        threads.emplace_back(std::make_unique<thread_context>());
    }
    async::pool<resource> pool(args.resources(), args.queue_size());
    for (const auto& ctx : threads) {
        callback cb {ctx->impl, pool};
        for (std::size_t i = 0; i < args.sequences(); ++i) {
            pool.get_auto_waste(ctx->impl.io_context, cb, ctx->impl.timeout);
        }
    }
    while (state.KeepRunning()) {
        std::for_each(threads.begin(), threads.end(), [] (const auto& ctx) { ctx->impl.wait_next(); });
    }
    std::for_each(threads.begin(), threads.end(), [] (const auto& ctx) { ctx->impl.finish(); });
    std::for_each(threads.begin(), threads.end(), [] (const auto& ctx) { ctx->thread.join(); });
}

void get_auto_waste_io_context_per_thread_on_coroutines(benchmark::State& state) {
    const auto& args = benchmarks[boost::numeric_cast<std::size_t>(state.range(0))];
    std::vector<std::unique_ptr<thread_context>> threads;
    for (std::size_t i = 0; i < args.threads(); ++i) {
        threads.emplace_back(std::make_unique<thread_context>());
    }
    async::pool<resource> pool(args.resources(), args.queue_size());
    for (const auto& ctx : threads) {
        for (std::size_t i = 0; i < args.sequences(); ++i) {
            boost::asio::spawn(ctx->impl.io_context, [&] (boost::asio::yield_context yield) {
                static thread_local std::minstd_rand generator(std::hash<std::thread::id>()(std::this_thread::get_id()));
                std::uniform_real_distribution<> distrubution(0, 1);
                constexpr const double recycle_probability = 0.5;
                while (!ctx->impl.stop) {
                    boost::system::error_code ec;
                    auto handle = pool.get_auto_waste(ctx->impl.io_context, yield[ec], ctx->impl.timeout);
                    if (!ec) {
                        if (handle.empty()) {
                            handle.reset(resource {});
                        }
                        if (distrubution(generator) < recycle_probability) {
                            handle.recycle();
                        }
                        ctx->impl.allow_next();
                    }
                }
            });
        }
    }
    while (state.KeepRunning()) {
        std::for_each(threads.begin(), threads.end(), [] (const auto& ctx) { ctx->impl.wait_next(); });
    }
    std::for_each(threads.begin(), threads.end(), [] (const auto& ctx) { ctx->impl.finish(); });
    std::for_each(threads.begin(), threads.end(), [] (const auto& ctx) { ctx->thread.join(); });
}

void all_benchmarks(benchmark::internal::Benchmark* b) {
    for (std::size_t n = 0; n < benchmarks.size(); ++n) {
        b->Arg(static_cast<int>(n));
    }
}

}

BENCHMARK(get_auto_waste)->Apply(all_benchmarks);
BENCHMARK(get_auto_waste_io_context_per_thread)->Apply(all_benchmarks);
BENCHMARK(get_auto_waste_io_context_per_thread_on_coroutines)->Apply(all_benchmarks);

BENCHMARK_MAIN();
<commit_msg>Remove unused<commit_after>#include <yamail/resource_pool/async/pool.hpp>

#include <benchmark/benchmark.h>

#include <boost/asio/post.hpp>
#include <boost/numeric/conversion/cast.hpp>

#include <atomic>
#include <condition_variable>
#include <iomanip>
#include <random>
#include <thread>

namespace {

using namespace yamail::resource_pool;

class benchmark_args {
public:
    constexpr benchmark_args sequences(std::size_t value) const {
        auto copy = *this;
        copy.sequences_ = value;
        return copy;
    }

    constexpr std::size_t sequences() const {
        return sequences_;
    }

    constexpr benchmark_args threads(std::size_t value) const {
        auto copy = *this;
        copy.threads_ = value;
        return copy;
    }

    constexpr std::size_t threads() const {
        return threads_;
    }

    constexpr benchmark_args resources(std::size_t value) const {
        auto copy = *this;
        copy.resources_ = value;
        return copy;
    }

    constexpr std::size_t resources() const {
        return resources_;
    }

    constexpr benchmark_args queue_size(std::size_t value) const {
        auto copy = *this;
        copy.queue_size_ = value;
        return copy;
    }

    constexpr std::size_t queue_size() const {
        return queue_size_;
    }

private:
    std::size_t sequences_ = 0;
    std::size_t threads_ = 0;
    std::size_t resources_ = 0;
    std::size_t queue_size_ = 0;
};

struct resource {};

struct context {
    boost::asio::io_context io_context;
    boost::asio::executor_work_guard<boost::asio::io_context::executor_type> guard = boost::asio::make_work_guard(io_context);
    std::atomic_bool stop {false};
    time_traits::duration timeout {std::chrono::milliseconds(100)};
    std::vector<std::chrono::steady_clock::duration> durations;
    std::mutex get_next_mutex;
    std::condition_variable get_next;
    std::unique_lock<std::mutex> get_next_lock {get_next_mutex};
    std::atomic<std::int64_t> ready_count {0};

    void wait_next() {
        if (--ready_count < 0) {
            get_next.wait(get_next_lock);
        }
    }

    void allow_next() {
        ++ready_count;
        get_next.notify_one();
    }

    void finish() {
        stop = true;
        guard.reset();
    }
};

struct callback {
    context& ctx;
    async::pool<resource>& pool;

    void operator ()(const boost::system::error_code& ec, async::pool<resource>::handle handle) {
        impl(ec, std::move(handle));
        if (!ctx.stop) {
            pool.get_auto_waste(ctx.io_context, *this, ctx.timeout);
        }
        ctx.allow_next();
    }

    void impl(const boost::system::error_code& ec, async::pool<resource>::handle handle) {
        static thread_local std::minstd_rand generator(std::hash<std::thread::id>()(std::this_thread::get_id()));
        static std::uniform_real_distribution<> distrubution(0, 1);
        constexpr const double recycle_probability = 0.5;
        if (!ec) {
            if (handle.empty()) {
                handle.reset(resource {});
            }
            if (distrubution(generator) < recycle_probability) {
                handle.recycle();
            }
        }
    }
};

constexpr std::array<benchmark_args, 17> benchmarks{{
    benchmark_args().sequences(1).threads(1).resources(1).queue_size(0), // 0
    benchmark_args().sequences(2).threads(1).resources(1).queue_size(1), // 1
    benchmark_args().sequences(2).threads(1).resources(2).queue_size(0), // 2
    benchmark_args().sequences(10).threads(1).resources(10).queue_size(0), // 3
    benchmark_args().sequences(10).threads(1).resources(1).queue_size(9), // 4
    benchmark_args().sequences(10).threads(1).resources(5).queue_size(5), // 5
    benchmark_args().sequences(10).threads(1).resources(9).queue_size(1), // 6
    benchmark_args().sequences(10).threads(2).resources(5).queue_size(5), // 7
    benchmark_args().sequences(100).threads(1).resources(100).queue_size(0), // 8
    benchmark_args().sequences(100).threads(1).resources(10).queue_size(90), // 9
    benchmark_args().sequences(100).threads(1).resources(50).queue_size(50), // 10
    benchmark_args().sequences(100).threads(1).resources(90).queue_size(10), // 11
    benchmark_args().sequences(100).threads(2).resources(50).queue_size(50), // 12
    benchmark_args().sequences(1000).threads(1).resources(10).queue_size(990), // 13
    benchmark_args().sequences(1000).threads(2).resources(10).queue_size(990), // 14
    benchmark_args().sequences(10000).threads(1).resources(10).queue_size(9990), // 15
    benchmark_args().sequences(10000).threads(2).resources(10).queue_size(9990), // 16
}};

void get_auto_waste(benchmark::State& state) {
    const auto& args = benchmarks[boost::numeric_cast<std::size_t>(state.range(0))];
    context ctx;
    std::vector<std::thread> workers;
    for (std::size_t i = 0; i < args.threads(); ++i) {
        workers.emplace_back(std::thread([&] { return ctx.io_context.run(); }));
    }
    async::pool<resource> pool(args.resources(), args.queue_size());
    callback cb {ctx, pool};
    for (std::size_t i = 0; i < args.sequences(); ++i) {
        pool.get_auto_waste(ctx.io_context, cb, ctx.timeout);
    }
    while (state.KeepRunning()) {
        ctx.wait_next();
    }
    ctx.finish();
    std::for_each(workers.begin(), workers.end(), [] (auto& v) { v.join(); });
}

struct thread_context {
    context impl;
    std::thread thread;

    thread_context()
        : thread([this] { this->impl.io_context.run(); }) {}
};

void get_auto_waste_io_context_per_thread(benchmark::State& state) {
    const auto& args = benchmarks[boost::numeric_cast<std::size_t>(state.range(0))];
    std::vector<std::unique_ptr<thread_context>> threads;
    for (std::size_t i = 0; i < args.threads(); ++i) {
        threads.emplace_back(std::make_unique<thread_context>());
    }
    async::pool<resource> pool(args.resources(), args.queue_size());
    for (const auto& ctx : threads) {
        callback cb {ctx->impl, pool};
        for (std::size_t i = 0; i < args.sequences(); ++i) {
            pool.get_auto_waste(ctx->impl.io_context, cb, ctx->impl.timeout);
        }
    }
    while (state.KeepRunning()) {
        std::for_each(threads.begin(), threads.end(), [] (const auto& ctx) { ctx->impl.wait_next(); });
    }
    std::for_each(threads.begin(), threads.end(), [] (const auto& ctx) { ctx->impl.finish(); });
    std::for_each(threads.begin(), threads.end(), [] (const auto& ctx) { ctx->thread.join(); });
}

void get_auto_waste_io_context_per_thread_on_coroutines(benchmark::State& state) {
    const auto& args = benchmarks[boost::numeric_cast<std::size_t>(state.range(0))];
    std::vector<std::unique_ptr<thread_context>> threads;
    for (std::size_t i = 0; i < args.threads(); ++i) {
        threads.emplace_back(std::make_unique<thread_context>());
    }
    async::pool<resource> pool(args.resources(), args.queue_size());
    for (const auto& ctx : threads) {
        for (std::size_t i = 0; i < args.sequences(); ++i) {
            boost::asio::spawn(ctx->impl.io_context, [&] (boost::asio::yield_context yield) {
                static thread_local std::minstd_rand generator(std::hash<std::thread::id>()(std::this_thread::get_id()));
                std::uniform_real_distribution<> distrubution(0, 1);
                constexpr const double recycle_probability = 0.5;
                while (!ctx->impl.stop) {
                    boost::system::error_code ec;
                    auto handle = pool.get_auto_waste(ctx->impl.io_context, yield[ec], ctx->impl.timeout);
                    if (!ec) {
                        if (handle.empty()) {
                            handle.reset(resource {});
                        }
                        if (distrubution(generator) < recycle_probability) {
                            handle.recycle();
                        }
                        ctx->impl.allow_next();
                    }
                }
            });
        }
    }
    while (state.KeepRunning()) {
        std::for_each(threads.begin(), threads.end(), [] (const auto& ctx) { ctx->impl.wait_next(); });
    }
    std::for_each(threads.begin(), threads.end(), [] (const auto& ctx) { ctx->impl.finish(); });
    std::for_each(threads.begin(), threads.end(), [] (const auto& ctx) { ctx->thread.join(); });
}

void all_benchmarks(benchmark::internal::Benchmark* b) {
    for (std::size_t n = 0; n < benchmarks.size(); ++n) {
        b->Arg(static_cast<int>(n));
    }
}

}

BENCHMARK(get_auto_waste)->Apply(all_benchmarks);
BENCHMARK(get_auto_waste_io_context_per_thread)->Apply(all_benchmarks);
BENCHMARK(get_auto_waste_io_context_per_thread_on_coroutines)->Apply(all_benchmarks);

BENCHMARK_MAIN();
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

#include "pch.h"
#include "App.h"
#include "BrowserPage.h"

using namespace winrt::Windows::ApplicationModel;
using namespace winrt::Windows::ApplicationModel::Activation;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Controls;
using namespace winrt::Windows::UI::Xaml::Navigation;
using namespace winrt::ServoApp;
using namespace winrt::ServoApp::implementation;

App::App() {
  InitializeComponent();
  Suspending({this, &App::OnSuspending});

#if defined _DEBUG &&                                                          \
    !defined DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
  UnhandledException(
      [this](IInspectable const &, UnhandledExceptionEventArgs const &e) {
        if (IsDebuggerPresent()) {
          auto errorMessage = e.Message();
          __debugbreak();
        }
      });
#endif
}

void App::createRootFrame(
    Frame &rootFrame, bool prelaunchActivated,
    winrt::Windows::Foundation::IInspectable const &args) {
  auto content = Window::Current().Content();
  if (content) {
    rootFrame = content.try_as<Frame>();
  }

  if (rootFrame == nullptr) {
    rootFrame = Frame();

    rootFrame.NavigationFailed({this, &App::OnNavigationFailed});

    if (prelaunchActivated == false) {
      if (rootFrame.Content() == nullptr) {
        rootFrame.Navigate(xaml_typename<ServoApp::BrowserPage>(), args);
      }
      Window::Current().Content(rootFrame);
      Window::Current().Activate();
    }
  } else {
    if (prelaunchActivated == false) {
      if (rootFrame.Content() == nullptr) {
        rootFrame.Navigate(xaml_typename<ServoApp::BrowserPage>(), args);
      }
      Window::Current().Activate();
    }
  }
}

void App::OnLaunched(LaunchActivatedEventArgs const &e) {
  Frame rootFrame{nullptr};
  this->createRootFrame(rootFrame, e.PrelaunchActivated(),
                        box_value(e.Arguments()));
}

void App::OnActivated(IActivatedEventArgs const &args) {
  if (args.Kind() == Windows::ApplicationModel::Activation::ActivationKind::
                         CommandLineLaunch) {
    auto cmdLineArgs{args.as<Windows::ApplicationModel::Activation::
                                 CommandLineActivatedEventArgs>()};
    auto cmdLineStr = cmdLineArgs.Operation().Arguments();
    Frame rootFrame{nullptr};
    this->createRootFrame(rootFrame, false, nullptr);
    auto page = rootFrame.Content().try_as<BrowserPage>();
    page->SetArgs(cmdLineStr);
    return;
  }

  if (args.Kind() ==
      Windows::ApplicationModel::Activation::ActivationKind::Protocol) {
    auto protocolActivatedEventArgs{args.as<
        Windows::ApplicationModel::Activation::ProtocolActivatedEventArgs>()};

    Frame rootFrame{nullptr};

    auto content = Window::Current().Content();
    bool isRunning = content != nullptr;
    if (!isRunning) {
      this->createRootFrame(rootFrame, false, nullptr);
    } else {
      rootFrame = content.try_as<Frame>();
    }
    auto page = rootFrame.Content().try_as<BrowserPage>();
    page->LoadServoURI(protocolActivatedEventArgs.Uri());
    // If Servo was opened as a result of clicking on a fxr:// URL,
    // we activate transient mode.
    page->SetTransientMode(!isRunning);
  }
}

void App::OnSuspending(IInspectable const &, SuspendingEventArgs const &) {
  auto content = Window::Current().Content();
  Frame rootFrame = content.try_as<Frame>();
  auto page = rootFrame.Content().try_as<BrowserPage>();
  page->Shutdown();
}

void App::OnNavigationFailed(IInspectable const &,
                             NavigationFailedEventArgs const &e) {
  throw hresult_error(E_FAIL, hstring(L"Failed to load Page ") +
                                  e.SourcePageType().Name);
}
<commit_msg>Auto merge of #26205 - jdm:no-shutdown, r=Manishearth<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

#include "pch.h"
#include "App.h"
#include "BrowserPage.h"

using namespace winrt::Windows::ApplicationModel;
using namespace winrt::Windows::ApplicationModel::Activation;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Controls;
using namespace winrt::Windows::UI::Xaml::Navigation;
using namespace winrt::ServoApp;
using namespace winrt::ServoApp::implementation;

App::App() {
  InitializeComponent();
  Suspending({this, &App::OnSuspending});

#if defined _DEBUG &&                                                          \
    !defined DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
  UnhandledException(
      [this](IInspectable const &, UnhandledExceptionEventArgs const &e) {
        if (IsDebuggerPresent()) {
          auto errorMessage = e.Message();
          __debugbreak();
        }
      });
#endif
}

void App::createRootFrame(
    Frame &rootFrame, bool prelaunchActivated,
    winrt::Windows::Foundation::IInspectable const &args) {
  auto content = Window::Current().Content();
  if (content) {
    rootFrame = content.try_as<Frame>();
  }

  if (rootFrame == nullptr) {
    rootFrame = Frame();

    rootFrame.NavigationFailed({this, &App::OnNavigationFailed});

    if (prelaunchActivated == false) {
      if (rootFrame.Content() == nullptr) {
        rootFrame.Navigate(xaml_typename<ServoApp::BrowserPage>(), args);
      }
      Window::Current().Content(rootFrame);
      Window::Current().Activate();
    }
  } else {
    if (prelaunchActivated == false) {
      if (rootFrame.Content() == nullptr) {
        rootFrame.Navigate(xaml_typename<ServoApp::BrowserPage>(), args);
      }
      Window::Current().Activate();
    }
  }
}

void App::OnLaunched(LaunchActivatedEventArgs const &e) {
  Frame rootFrame{nullptr};
  this->createRootFrame(rootFrame, e.PrelaunchActivated(),
                        box_value(e.Arguments()));
}

void App::OnActivated(IActivatedEventArgs const &args) {
  if (args.Kind() == Windows::ApplicationModel::Activation::ActivationKind::
                         CommandLineLaunch) {
    auto cmdLineArgs{args.as<Windows::ApplicationModel::Activation::
                                 CommandLineActivatedEventArgs>()};
    auto cmdLineStr = cmdLineArgs.Operation().Arguments();
    Frame rootFrame{nullptr};
    this->createRootFrame(rootFrame, false, nullptr);
    auto page = rootFrame.Content().try_as<BrowserPage>();
    page->SetArgs(cmdLineStr);
    return;
  }

  if (args.Kind() ==
      Windows::ApplicationModel::Activation::ActivationKind::Protocol) {
    auto protocolActivatedEventArgs{args.as<
        Windows::ApplicationModel::Activation::ProtocolActivatedEventArgs>()};

    Frame rootFrame{nullptr};

    auto content = Window::Current().Content();
    bool isRunning = content != nullptr;
    if (!isRunning) {
      this->createRootFrame(rootFrame, false, nullptr);
    } else {
      rootFrame = content.try_as<Frame>();
    }
    auto page = rootFrame.Content().try_as<BrowserPage>();
    page->LoadServoURI(protocolActivatedEventArgs.Uri());
    // If Servo was opened as a result of clicking on a fxr:// URL,
    // we activate transient mode.
    page->SetTransientMode(!isRunning);
  }
}

void App::OnSuspending(IInspectable const &, SuspendingEventArgs const &) {
  // FIXME: Apps can be suspended for various reasons, not just closing them.
  //        * Figure out how to save state like the current URL so it can be
  //          restored if necessary.
  //        * Determine if the user has actually closed the app and shutdown.
  /*auto content = Window::Current().Content();
  Frame rootFrame = content.try_as<Frame>();
  auto page = rootFrame.Content().try_as<BrowserPage>();
  page->Shutdown();*/
}

void App::OnNavigationFailed(IInspectable const &,
                             NavigationFailedEventArgs const &e) {
  throw hresult_error(E_FAIL, hstring(L"Failed to load Page ") +
                                  e.SourcePageType().Name);
}
<|endoftext|>