<commit_before>/*
 * Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
 *
 * Licensed under the BSD License, see LICENSE file for details.
 *
 */

#include <cstring>

#include <iostream>
#include <string>

#include "libxtreemfs/client.h"
#include "libxtreemfs/file_handle.h"
#include "libxtreemfs/options.h"
#include "libxtreemfs/volume.h"
#include "libxtreemfs/xtreemfs_exception.h"
#include "pbrpc/RPC.pb.h"  // xtreemfs::pbrpc::UserCredentials
#include "xtreemfs/MRC.pb.h"  // xtreemfs::pbrpc::Stat

using namespace std;

int main(int argc, char* argv[]) {
  // Every operation is executed in the context of a given user and his groups.
  // The UserCredentials object does store this information and is currently
  // (08/2011) *only* evaluated by the MRC (although the protocol requires to
  // send user_credentials to DIR and OSD, too).
  xtreemfs::pbrpc::UserCredentials user_credentials;
  user_credentials.set_username("example_libxtreemfs");
  user_credentials.add_groups("example_libxtreemfs");

  // Class which allows to change options of the library.
  xtreemfs::Options options;

  try {
    options.ParseCommandLine(argc, argv);
  } catch(const xtreemfs::XtreemFSException& e) {
    cout << "Invalid parameters found, error: " << e.what() << endl << endl;
  }

  try {
    // Create a new instance of a client using the DIR service at
    // 'demo.xtreemfs.org' (default port 32638).
    xtreemfs::Client* client = xtreemfs::Client::CreateClient(
        //"demo.xtreemfs.org:32638",
        "localhost:32638",
        user_credentials,
        NULL,  // No SSL options.
        options);

    // Start the client (a connection to the DIR service will be setup).
    client->Start();

    /*
    // Open a volume named 'demo'.
    xtreemfs::Volume *volume = NULL;
    volume = client->OpenVolume(
        "demo",
        NULL,  // No SSL options.
        options);

    // Open a file.
    xtreemfs::FileHandle* file = volume->OpenFile(
        user_credentials,
        "/example_libxtreemfs.txt",
        static_cast<xtreemfs::pbrpc::SYSTEM_V_FCNTL>(
            xtreemfs::pbrpc::SYSTEM_V_FCNTL_H_O_CREAT |
            xtreemfs::pbrpc::SYSTEM_V_FCNTL_H_O_TRUNC |
            xtreemfs::pbrpc::SYSTEM_V_FCNTL_H_O_RDWR),
        511);  // = 777 Octal.

    // Write to file.
    cout << "Writing the string\n"
            "\n"
            "\t\"Accessed XtreemFS through the C++ libxtreemfs.\"\n"
            "\n"
            "to the file example_libxtreemfs.txt..." << endl;
    char write_buf[] = "Accessed XtreemFS through the C++ libxtreemfs.";
    file->Write(user_credentials,
                reinterpret_cast<const char*>(&write_buf),
                sizeof(write_buf),
                0);

    // Get file attributes.
    xtreemfs::pbrpc::Stat stat;
    volume->GetAttr(user_credentials, "/example_libxtreemfs.txt", &stat);
    cout << "\nNew file size of example_libxtreemfs.txt: "
         << stat.size() << " Bytes." << endl;
    // Once again, now hopefully from the Cache.
    volume->GetAttr(user_credentials, "/example_libxtreemfs.txt", &stat);
    cout << "\nFile size of example_libxtreemfs.txt again (this time retrieved"
            " from the enabled metadata cache): " << stat.size() << endl;

    // Read from the file.
    const size_t buffer_size = 128 * 1024;  // 128kB, default object size.
    char read_buf[buffer_size];
    memset(&read_buf, 0, buffer_size);
    file->Read(user_credentials,
               reinterpret_cast<char*>(&read_buf),
               buffer_size,  // Length.
               0);  // Offset.
    cout << "\nReading the content of the file example_libxtreemfs.txt:\n\n"
         << read_buf << endl;

    // Close the file (no need to delete it, see documentation volume.h).
    file->Close();
*/
    sleep(60);
    // Shutdown() does also invoke a volume->Close().
    client->Shutdown();
    delete client;
  } catch(const xtreemfs::XtreemFSException& e) {
    cout << "An error occured:\n" << e.what() << endl;
    return 1;
  }

  return 0;
}
<commit_msg>client: Fixed example_libxtreemfs since a test version was accidentally committed as part of revision 3016.<commit_after>/*
 * Copyright (c) 2011 by Michael Berlin, Zuse Institute Berlin
 *
 * Licensed under the BSD License, see LICENSE file for details.
 *
 */

#include <cstring>

#include <iostream>
#include <string>

#include "libxtreemfs/client.h"
#include "libxtreemfs/file_handle.h"
#include "libxtreemfs/options.h"
#include "libxtreemfs/volume.h"
#include "libxtreemfs/xtreemfs_exception.h"
#include "pbrpc/RPC.pb.h"  // xtreemfs::pbrpc::UserCredentials
#include "xtreemfs/MRC.pb.h"  // xtreemfs::pbrpc::Stat

using namespace std;

int main(int argc, char* argv[]) {
  // Every operation is executed in the context of a given user and his groups.
  // The UserCredentials object does store this information and is currently
  // (08/2011) *only* evaluated by the MRC (although the protocol requires to
  // send user_credentials to DIR and OSD, too).
  xtreemfs::pbrpc::UserCredentials user_credentials;
  user_credentials.set_username("example_libxtreemfs");
  user_credentials.add_groups("example_libxtreemfs");

  // Class which allows to change options of the library.
  xtreemfs::Options options;

  try {
    options.ParseCommandLine(argc, argv);
  } catch(const xtreemfs::XtreemFSException& e) {
    cout << "Invalid parameters found, error: " << e.what() << endl << endl;
  }

  try {
    // Create a new instance of a client using the DIR service at
    // 'demo.xtreemfs.org' (default port 32638).
    xtreemfs::Client* client = xtreemfs::Client::CreateClient(
        "demo.xtreemfs.org:32638",
        user_credentials,
        NULL,  // No SSL options.
        options);

    // Start the client (a connection to the DIR service will be setup).
    client->Start();

    // Open a volume named 'demo'.
    xtreemfs::Volume *volume = NULL;
    volume = client->OpenVolume("demo",
                                NULL,  // No SSL options.
                                options);

    // Open a file.
    xtreemfs::FileHandle* file = volume->OpenFile(
        user_credentials,
        "/example_libxtreemfs.txt",
        static_cast<xtreemfs::pbrpc::SYSTEM_V_FCNTL>(
            xtreemfs::pbrpc::SYSTEM_V_FCNTL_H_O_CREAT |
            xtreemfs::pbrpc::SYSTEM_V_FCNTL_H_O_TRUNC |
            xtreemfs::pbrpc::SYSTEM_V_FCNTL_H_O_RDWR),
        511);  // = 777 Octal.

    // Write to file.
    cout << "Writing the string\n"
            "\n"
            "\t\"Accessed XtreemFS through the C++ libxtreemfs.\"\n"
            "\n"
            "to the file example_libxtreemfs.txt..." << endl;
    char write_buf[] = "Accessed XtreemFS through the C++ libxtreemfs.";
    file->Write(user_credentials,
                reinterpret_cast<const char*>(&write_buf),
                sizeof(write_buf),
                0);

    // Get file attributes.
    xtreemfs::pbrpc::Stat stat;
    volume->GetAttr(user_credentials, "/example_libxtreemfs.txt", &stat);
    cout << "\nNew file size of example_libxtreemfs.txt: "
         << stat.size() << " Bytes." << endl;
    // Once again, now hopefully from the Cache.
    volume->GetAttr(user_credentials, "/example_libxtreemfs.txt", &stat);
    cout << "\nFile size of example_libxtreemfs.txt again (this time retrieved"
            " from the enabled metadata cache): " << stat.size() << endl;

    // Read from the file.
    const size_t buffer_size = 128 * 1024;  // 128kB, default object size.
    char read_buf[buffer_size];
    memset(&read_buf, 0, buffer_size);
    file->Read(user_credentials,
               reinterpret_cast<char*>(&read_buf),
               buffer_size,  // Length.
               0);  // Offset.
    cout << "\nReading the content of the file example_libxtreemfs.txt:\n\n"
         << read_buf << endl;

    // Close the file (no need to delete it, see documentation volume.h).
    file->Close();

    // Shutdown() does also invoke a volume->Close().
    client->Shutdown();
    delete client;
  } catch(const xtreemfs::XtreemFSException& e) {
    cout << "An error occured:\n" << e.what() << endl;
    return 1;
  }

  return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: container.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: vg $ $Date: 2005-02-16 15:54:29 $
 *
 *  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 EXPRESS 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 _COMPHELPER_CONTAINER_HXX_
#define _COMPHELPER_CONTAINER_HXX_

#ifndef __SGI_STL_VECTOR
#include <vector>
#endif
#ifndef INCLUDED_COMPHELPERDLLAPI_H
#include "comphelper/comphelperdllapi.h"
#endif

//.........................................................................
namespace comphelper
{
//.........................................................................

#define NOTIFY_LISTENERS(listeners, XIface, method, evt)                \
    if (listeners.getLength())                                          \
    {                                                                   \
        ::cppu::OInterfaceIteratorHelper aIter(listeners);              \
        while (aIter.hasMoreElements())                                 \
            reinterpret_cast< XIface* >(aIter.next())->method(evt);     \
    }

//========================================================================
//= IndexAccessIterator
//========================================================================
/** ein Iterator, der von einem XIndexAccess ausgehend alle Elemente durchiteriert (pre-order)
*/
class COMPHELPER_DLLPUBLIC IndexAccessIterator
{
protected:
    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>    m_xStartingPoint;

    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>    m_xCurrentObject;
        // das aktuelle Objekt
    ::std::vector<sal_Int32>        m_arrChildIndizies;
        // ich bewege mich eigentlich durch einen Baum, dummerweise haben dessen
        // Elemente aber kein GetNextSibling, also muss ich mir merken, wo die Childs
        // innerhalb ihres Parents sitzen (das ist sozusagen der Pfad von der Wurzel
        // zu m_xCurrentObject

    ::rtl::OUString     m_ustrProperty;
        // der Name der gesuchten property

public:
    IndexAccessIterator(::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> xStartingPoint);

    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>    Next();

    virtual void Invalidate() { m_xCurrentObject = NULL; }

protected:
    virtual sal_Bool ShouldHandleElement(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>& rElement) { return sal_True; }
        // damit kann man bestimmte Elemente ausschliessen, die werden dann einfach
        // uebergangen
        // wenn hier sal_True zurueckkommt, wird dieses Element von Next zurueckgeliefert, man kann sich hier also auch
        // gleich ein paar zusaetzliche Angaben zu dem Element holen (deswegen ist die Methode auch nicht const)
    virtual sal_Bool ShouldStepInto(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>& xContainer) const { return sal_True; }
};

//.........................................................................
}   // namespace comphelper
//.........................................................................

#endif // _COMPHELPER_CONTAINER_HXX_

<commit_msg>INTEGRATION: CWS ooo19126 (1.4.56); FILE MERGED 2005/09/05 15:23:39 rt 1.4.56.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: container.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 02:29:14 $
 *
 *  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 _COMPHELPER_CONTAINER_HXX_
#define _COMPHELPER_CONTAINER_HXX_

#ifndef __SGI_STL_VECTOR
#include <vector>
#endif
#ifndef INCLUDED_COMPHELPERDLLAPI_H
#include "comphelper/comphelperdllapi.h"
#endif

//.........................................................................
namespace comphelper
{
//.........................................................................

#define NOTIFY_LISTENERS(listeners, XIface, method, evt)                \
    if (listeners.getLength())                                          \
    {                                                                   \
        ::cppu::OInterfaceIteratorHelper aIter(listeners);              \
        while (aIter.hasMoreElements())                                 \
            reinterpret_cast< XIface* >(aIter.next())->method(evt);     \
    }

//========================================================================
//= IndexAccessIterator
//========================================================================
/** ein Iterator, der von einem XIndexAccess ausgehend alle Elemente durchiteriert (pre-order)
*/
class COMPHELPER_DLLPUBLIC IndexAccessIterator
{
protected:
    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>    m_xStartingPoint;

    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>    m_xCurrentObject;
        // das aktuelle Objekt
    ::std::vector<sal_Int32>        m_arrChildIndizies;
        // ich bewege mich eigentlich durch einen Baum, dummerweise haben dessen
        // Elemente aber kein GetNextSibling, also muss ich mir merken, wo die Childs
        // innerhalb ihres Parents sitzen (das ist sozusagen der Pfad von der Wurzel
        // zu m_xCurrentObject

    ::rtl::OUString     m_ustrProperty;
        // der Name der gesuchten property

public:
    IndexAccessIterator(::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> xStartingPoint);

    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>    Next();

    virtual void Invalidate() { m_xCurrentObject = NULL; }

protected:
    virtual sal_Bool ShouldHandleElement(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>& rElement) { return sal_True; }
        // damit kann man bestimmte Elemente ausschliessen, die werden dann einfach
        // uebergangen
        // wenn hier sal_True zurueckkommt, wird dieses Element von Next zurueckgeliefert, man kann sich hier also auch
        // gleich ein paar zusaetzliche Angaben zu dem Element holen (deswegen ist die Methode auch nicht const)
    virtual sal_Bool ShouldStepInto(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>& xContainer) const { return sal_True; }
};

//.........................................................................
}   // namespace comphelper
//.........................................................................

#endif // _COMPHELPER_CONTAINER_HXX_

<|endoftext|>


<commit_before>#include "ofApp.h"

void ofApp::setup()
{
	std::string cfgfile = ofToDataPath( "cfg/yolo9000.cfg" );
	std::string weightfile = ofToDataPath( "yolo9000.weights" );
	std::string namesfile = ofToDataPath( "cfg/9k.names" );

	darknet.init( cfgfile, weightfile, namesfile );

	video.setDeviceID( 0 );
	video.setDesiredFrameRate( 30 );
	video.initGrabber( 640, 480 );
}

void ofApp::update()
{
	video.update();
}

void ofApp::draw()
{
    // detected objects with confidence < threshold are omitted
	float thresh = ofMap( ofGetMouseX(), 0, ofGetWidth(), 0, 1 );

    // if a detected object overlaps >maxOverlap with another detected
    // object with a higher confidence, it gets omitted
    float maxOverlap = 0.25;

	ofSetColor( 255 );
	video.draw( 0, 0 );

	if( video.isFrameNew() ) {
		std::vector< detected_object > detections = darknet.yolo( video.getPixels(), thresh, maxOverlap );

		ofNoFill();
		for( detected_object d : detections )
		{
			ofSetColor( d.color );
			glLineWidth( ofMap( d.probability, 0, 1, 0, 8 ) );
			ofNoFill();
			ofDrawRectangle( d.rect );
			ofDrawBitmapStringHighlight( d.label + ": " + ofToString(d.probability), d.rect.x, d.rect.y + 20 );
		}
	}
}<commit_msg>add line about feature detection<commit_after>#include "ofApp.h"

void ofApp::setup()
{
	std::string cfgfile = ofToDataPath( "cfg/yolo9000.cfg" );
	std::string weightfile = ofToDataPath( "yolo9000.weights" );
	std::string namesfile = ofToDataPath( "cfg/9k.names" );

	darknet.init( cfgfile, weightfile, namesfile );

	video.setDeviceID( 0 );
	video.setDesiredFrameRate( 30 );
	video.initGrabber( 640, 480 );
}

void ofApp::update()
{
	video.update();
}

void ofApp::draw()
{
    // detected objects with confidence < threshold are omitted
	float thresh = ofMap( ofGetMouseX(), 0, ofGetWidth(), 0, 1 );

    // if a detected object overlaps >maxOverlap with another detected
    // object with a higher confidence, it gets omitted
    float maxOverlap = 0.25;

	ofSetColor( 255 );
	video.draw( 0, 0 );

	if( video.isFrameNew() ) {
		std::vector< detected_object > detections = darknet.yolo( video.getPixels(), thresh, maxOverlap );

		ofNoFill();
		for( detected_object d : detections )
		{
			ofSetColor( d.color );
			glLineWidth( ofMap( d.probability, 0, 1, 0, 8 ) );
			ofNoFill();
			ofDrawRectangle( d.rect );
			ofDrawBitmapStringHighlight( d.label + ": " + ofToString(d.probability), d.rect.x, d.rect.y + 20 );

            // optionally, you can grab the 1024-length feature vector associated
            // with each detected object
            vector<float> & features = d.features;
		}
	}
}<|endoftext|>


<commit_before>#ifndef VIENNAGRID_STORAGE_INSERTER_HPP
#define VIENNAGRID_STORAGE_INSERTER_HPP

#include "viennagrid/storage/reference.hpp"
#include "viennagrid/storage/container_collection.hpp"
#include "viennagrid/storage/container_collection_element.hpp"

namespace viennagrid
{
    namespace storage
    {

        template<typename container_collection_type>
        class inserter_base_t
        {
        public:
            inserter_base_t(container_collection_type & _collection) : collection(_collection) {}

        protected:
            container_collection_type & collection;
        };

        template<typename container_collection_type, typename _container_collection_reference_config, typename _id_generator_type>
        class physical_inserter_t : public inserter_base_t<container_collection_type>
        {
        public:
            typedef inserter_base_t<container_collection_type> base_inserter;
            typedef container_collection_type physical_container_collection_type;
            typedef _id_generator_type id_generator_type;
            typedef _container_collection_reference_config container_collection_reference_config;

            physical_inserter_t(container_collection_type & _collection, id_generator_type & _id_generator) : base_inserter(_collection), id_generator(_id_generator) {}

            template<typename value_type, typename inserter_type>
            std::pair<
                typename viennagrid::storage::reference::reference_type_from_config<
                    //value_type,
                    typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type,
                    container_collection_reference_config
                >::type,
                bool
            >
                    physical_insert( const value_type & element, inserter_type & inserter )
            {
                typedef typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type::iterator iterator;
                typedef typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type container_type;
                typedef typename viennagrid::storage::reference::reference_tag_from_config<container_type, container_collection_reference_config>::type reference_tag;
                typedef typename viennagrid::storage::reference::reference_type_from_config<container_type, container_collection_reference_config>::type reference_type;

                std::pair<iterator, bool> ret = viennagrid::storage::container::insert(viennagrid::storage::container_collection::get< value_type >( base_inserter::collection ), element);

                if (ret.second) viennagrid::storage::container_collection_element::set_id(*ret.first, id_generator( viennameta::tag<value_type>() ) );

                viennagrid::storage::container_collection_element::insert_callback(*ret.first, ret.second, inserter);

                reference_type ref = viennagrid::storage::reference::iterator_to_reference(ret.first, reference_tag());
                inserter.reference_insert( ref );

                return std::make_pair(ref, ret.second);
            }

            template<typename reference_type>
            void reference_insert( reference_type ref )
            {}

            template<typename value_type>
            std::pair<
                typename viennagrid::storage::reference::reference_type_from_config<
                    //value_type,
                    typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type,
                    container_collection_reference_config
                >::type,
                bool
            >
                operator()( const value_type & element )
            {
                return physical_insert( element, *this );
            }

        private:
            id_generator_type & id_generator;
        };

        template<typename container_collection_type, typename dependend_inserter_type>
        class recursive_inserter_t : public inserter_base_t<container_collection_type>, dependend_inserter_type
        {
        public:
            typedef inserter_base_t<container_collection_type> base_inserter;
            typedef dependend_inserter_type base;

            recursive_inserter_t(container_collection_type & _collection, const dependend_inserter_type & dependend_inserter) :
                base_inserter(_collection), dependend_inserter_type(dependend_inserter) {}

            template<typename reference_type>
            void reference_insert( reference_type ref )
            {
                typedef typename viennagrid::storage::reference::value_type_from_reference_type<reference_type>::type value_type;

                if (!viennameta::_equal<
                        typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type,
                        viennameta::null_type
                    >::value)
                {
                    viennagrid::storage::container_collection::insert_or_ignore( base_inserter::collection, *ref );
                }

                base::reference_insert( ref );
            }

            typedef typename base::physical_container_collection_type physical_container_collection_type;
            typedef typename base::container_collection_reference_config container_collection_reference_config;

            template<typename value_type, typename inserter_type>
            std::pair<
                typename viennagrid::storage::reference::reference_type_from_config<
                    //value_type,
                    typename viennagrid::storage::result_of::container_of<physical_container_collection_type, value_type>::type,
                    container_collection_reference_config
                >::type,
                bool
            >
                physical_insert( const value_type & element, inserter_type & inserter )
            {
                return base::physical_insert( element, inserter );
            }

            template<typename value_type>
            std::pair<
                typename viennagrid::storage::reference::reference_type_from_config<
                    //value_type,
                    typename viennagrid::storage::result_of::container_of<physical_container_collection_type, value_type>::type,
                    container_collection_reference_config
                >::type,
                bool
            >
                operator()( const value_type & element )
            {
                return physical_insert( element, *this );
            }
        };

        namespace inserter
        {
            typedef VIENNAMETA_MAKE_TYPEMAP_1( viennagrid::storage::default_tag, viennagrid::storage::pointer_reference_tag ) pointer_reference_config;
            typedef VIENNAMETA_MAKE_TYPEMAP_1( viennagrid::storage::default_tag, viennagrid::storage::iterator_reference_tag ) iterator_reference_config;

            template<typename dependend_inserter_type, typename container_collection_type>
            recursive_inserter_t<container_collection_type, dependend_inserter_type> get_recursive( const dependend_inserter_type & inserter, container_collection_type & collection )
            {
                return recursive_inserter_t<container_collection_type, dependend_inserter_type>(inserter, collection);
            }
        }

        namespace result_of
        {
            template<typename container_collection_type, typename dependend_inserter_type>
            struct recursive_inserter
            {
                typedef recursive_inserter_t<container_collection_type, dependend_inserter_type> type;
            };

            template<typename container_collection_type, typename container_collection_reference_config, typename id_generator_type>
            struct physical_inserter
            {
                typedef physical_inserter_t<container_collection_type, container_collection_reference_config, id_generator_type> type;
            };
        }

    }
}

#endif<commit_msg>removed comment<commit_after>#ifndef VIENNAGRID_STORAGE_INSERTER_HPP
#define VIENNAGRID_STORAGE_INSERTER_HPP

#include "viennagrid/storage/reference.hpp"
#include "viennagrid/storage/container_collection.hpp"
#include "viennagrid/storage/container_collection_element.hpp"

namespace viennagrid
{
    namespace storage
    {

        template<typename container_collection_type>
        class inserter_base_t
        {
        public:
            inserter_base_t(container_collection_type & _collection) : collection(_collection) {}

        protected:
            container_collection_type & collection;
        };

        template<typename container_collection_type, typename _container_collection_reference_config, typename _id_generator_type>
        class physical_inserter_t : public inserter_base_t<container_collection_type>
        {
        public:
            typedef inserter_base_t<container_collection_type> base_inserter;
            typedef container_collection_type physical_container_collection_type;
            typedef _id_generator_type id_generator_type;
            typedef _container_collection_reference_config container_collection_reference_config;

            physical_inserter_t(container_collection_type & _collection, id_generator_type & _id_generator) : base_inserter(_collection), id_generator(_id_generator) {}

            template<typename value_type, typename inserter_type>
            std::pair<
                typename viennagrid::storage::reference::reference_type_from_config<
                    typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type,
                    container_collection_reference_config
                >::type,
                bool
            >
                    physical_insert( const value_type & element, inserter_type & inserter )
            {
                typedef typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type::iterator iterator;
                typedef typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type container_type;
                typedef typename viennagrid::storage::reference::reference_tag_from_config<container_type, container_collection_reference_config>::type reference_tag;
                typedef typename viennagrid::storage::reference::reference_type_from_config<container_type, container_collection_reference_config>::type reference_type;

                std::pair<iterator, bool> ret = viennagrid::storage::container::insert(viennagrid::storage::container_collection::get< value_type >( base_inserter::collection ), element);

                if (ret.second) viennagrid::storage::container_collection_element::set_id(*ret.first, id_generator( viennameta::tag<value_type>() ) );

                viennagrid::storage::container_collection_element::insert_callback(*ret.first, ret.second, inserter);

                reference_type ref = viennagrid::storage::reference::iterator_to_reference(ret.first, reference_tag());
                inserter.reference_insert( ref );

                return std::make_pair(ref, ret.second);
            }

            template<typename reference_type>
            void reference_insert( reference_type ref )
            {}

            template<typename value_type>
            std::pair<
                typename viennagrid::storage::reference::reference_type_from_config<
                    //value_type,
                    typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type,
                    container_collection_reference_config
                >::type,
                bool
            >
                operator()( const value_type & element )
            {
                return physical_insert( element, *this );
            }

        private:
            id_generator_type & id_generator;
        };

        template<typename container_collection_type, typename dependend_inserter_type>
        class recursive_inserter_t : public inserter_base_t<container_collection_type>, dependend_inserter_type
        {
        public:
            typedef inserter_base_t<container_collection_type> base_inserter;
            typedef dependend_inserter_type base;

            recursive_inserter_t(container_collection_type & _collection, const dependend_inserter_type & dependend_inserter) :
                base_inserter(_collection), dependend_inserter_type(dependend_inserter) {}

            template<typename reference_type>
            void reference_insert( reference_type ref )
            {
                typedef typename viennagrid::storage::reference::value_type_from_reference_type<reference_type>::type value_type;

                if (!viennameta::_equal<
                        typename viennagrid::storage::result_of::container_of<container_collection_type, value_type>::type,
                        viennameta::null_type
                    >::value)
                {
                    viennagrid::storage::container_collection::insert_or_ignore( base_inserter::collection, *ref );
                }

                base::reference_insert( ref );
            }

            typedef typename base::physical_container_collection_type physical_container_collection_type;
            typedef typename base::container_collection_reference_config container_collection_reference_config;

            template<typename value_type, typename inserter_type>
            std::pair<
                typename viennagrid::storage::reference::reference_type_from_config<
                    //value_type,
                    typename viennagrid::storage::result_of::container_of<physical_container_collection_type, value_type>::type,
                    container_collection_reference_config
                >::type,
                bool
            >
                physical_insert( const value_type & element, inserter_type & inserter )
            {
                return base::physical_insert( element, inserter );
            }

            template<typename value_type>
            std::pair<
                typename viennagrid::storage::reference::reference_type_from_config<
                    //value_type,
                    typename viennagrid::storage::result_of::container_of<physical_container_collection_type, value_type>::type,
                    container_collection_reference_config
                >::type,
                bool
            >
                operator()( const value_type & element )
            {
                return physical_insert( element, *this );
            }
        };

        namespace inserter
        {
            typedef VIENNAMETA_MAKE_TYPEMAP_1( viennagrid::storage::default_tag, viennagrid::storage::pointer_reference_tag ) pointer_reference_config;
            typedef VIENNAMETA_MAKE_TYPEMAP_1( viennagrid::storage::default_tag, viennagrid::storage::iterator_reference_tag ) iterator_reference_config;

            template<typename dependend_inserter_type, typename container_collection_type>
            recursive_inserter_t<container_collection_type, dependend_inserter_type> get_recursive( const dependend_inserter_type & inserter, container_collection_type & collection )
            {
                return recursive_inserter_t<container_collection_type, dependend_inserter_type>(inserter, collection);
            }
        }

        namespace result_of
        {
            template<typename container_collection_type, typename dependend_inserter_type>
            struct recursive_inserter
            {
                typedef recursive_inserter_t<container_collection_type, dependend_inserter_type> type;
            };

            template<typename container_collection_type, typename container_collection_reference_config, typename id_generator_type>
            struct physical_inserter
            {
                typedef physical_inserter_t<container_collection_type, container_collection_reference_config, id_generator_type> type;
            };
        }

    }
}

#endif<|endoftext|>


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

// Make sure that winmm.lib is added to the linker's input.
#pragma comment(lib, "winmm.lib")
#include "native_client/src/include/portability.h"
#include <mmsystem.h>
#include <windows.h>

#include "native_client/src/include/checked_cast.h"
#include "native_client/src/shared/platform/win/time.h"
#include "native_client/src/shared/platform/win/lock.h"

namespace {

// From MSDN, FILETIME "Contains a 64-bit value representing the number of
// 100-nanosecond intervals since January 1, 1601 (UTC)."
int64_t FileTimeToMicroseconds(const FILETIME& ft) {
  // Need to nacl_bit_cast to fix alignment, then divide by 10 to convert
  // 100-nanoseconds to milliseconds. This only works on little-endian
  // machines.
  return nacl_bit_cast<int64_t, FILETIME>(ft) / 10;
}

void MicrosecondsToFileTime(int64_t us, FILETIME* ft) {
/*  DCHECK(us >= 0) << "Time is less than 0, negative values are not "
 *      "representable in FILETIME";
 */

  // Multiply by 10 to convert milliseconds to 100-nanoseconds. Nacl_bit_cast
  // will handle alignment problems. This only works on little-endian machines.
  *ft = nacl_bit_cast<FILETIME, int64_t>(us * 10);
}

}  // namespace

// Time -----------------------------------------------------------------------

// The internal representation of Time uses FILETIME, whose epoch is 1601-01-01
// 00:00:00 UTC.  ((1970-1601)*365+89)*24*60*60*1000*1000, where 89 is the
// number of leap year days between 1601 and 1970: (1970-1601)/4 excluding
// 1700, 1800, and 1900.
// static
const int64_t NaCl::Time::kTimeTToMicrosecondsOffset =
    GG_INT64_C(11644473600000000);

// static
int64_t NaCl::Time::CurrentWallclockMicroseconds() {
  FILETIME ft;
  ::GetSystemTimeAsFileTime(&ft);
  return FileTimeToMicroseconds(ft);
}

// static
NaCl::Time NaCl::Time::FromFileTime(FILETIME ft) {
  return Time(FileTimeToMicroseconds(ft));
}

FILETIME NaCl::Time::ToFileTime() const {
  FILETIME utc_ft;
  MicrosecondsToFileTime(us_, &utc_ft);
  return utc_ft;
}

// static
NaCl::Time NaCl::Time::FromExploded(bool is_local, const Exploded& exploded) {
  // Create the system struct representing our exploded time. It will either be
  // in local time or UTC.
  SYSTEMTIME st;
  st.wYear = nacl::assert_cast<WORD>(exploded.year);
  st.wMonth = nacl::assert_cast<WORD>(exploded.month);
  st.wDayOfWeek = nacl::assert_cast<WORD>(exploded.day_of_week);
  st.wDay = nacl::assert_cast<WORD>(exploded.day_of_month);
  st.wHour = nacl::assert_cast<WORD>(exploded.hour);
  st.wMinute = nacl::assert_cast<WORD>(exploded.minute);
  st.wSecond = nacl::assert_cast<WORD>(exploded.second);
  st.wMilliseconds = nacl::assert_cast<WORD>(exploded.millisecond);

  // Convert to FILETIME.
  FILETIME ft;
  if (!SystemTimeToFileTime(&st, &ft)) {
    // NOTREACHED() << "Unable to convert time";
    return Time(0);
  }

  // Ensure that it's in UTC.
  if (is_local) {
    FILETIME utc_ft;
    LocalFileTimeToFileTime(&ft, &utc_ft);
    return Time(FileTimeToMicroseconds(utc_ft));
  }
  return Time(FileTimeToMicroseconds(ft));
}

void NaCl::Time::Explode(bool is_local, Exploded* exploded) const {
  // FILETIME in UTC.
  FILETIME utc_ft;
  MicrosecondsToFileTime(us_, &utc_ft);

  // FILETIME in local time if necessary.
  BOOL success = TRUE;
  FILETIME ft;
  if (is_local)
    success = FileTimeToLocalFileTime(&utc_ft, &ft);
  else
    ft = utc_ft;

  // FILETIME in SYSTEMTIME (exploded).
  SYSTEMTIME st;
  if (!success || !FileTimeToSystemTime(&ft, &st)) {
    // NOTREACHED() << "Unable to convert time, don't know why";
    ZeroMemory(exploded, sizeof(exploded));
    return;
  }

  exploded->year = st.wYear;
  exploded->month = st.wMonth;
  exploded->day_of_week = st.wDayOfWeek;
  exploded->day_of_month = st.wDay;
  exploded->hour = st.wHour;
  exploded->minute = st.wMinute;
  exploded->second = st.wSecond;
  exploded->millisecond = st.wMilliseconds;
}

// TimeTicks ------------------------------------------------------------------
NaCl::TimeTicks::TickFunction NaCl::TimeTicks::tick_function_=
    reinterpret_cast<TickFunction>(&timeGetTime);

// static
NaCl::TimeTicks NaCl::TimeTicks::Now() {
  // Uses the multimedia timers on Windows to get a higher resolution clock.
  // timeGetTime() provides a resolution which is variable depending on
  // hardware and system configuration.  It can also be changed by other
  // apps.  This class does not attempt to change the resolution of the
  // timer, because we don't want to affect other applications.

  // timeGetTime() should at least be accurate to ~5ms on all systems.
  // timeGetTime() returns a 32-bit millisecond counter which has rollovers
  // every ~49 days.
  static DWORD last_tick_count = 0;
  static int64_t tick_rollover_accum = 0;
  static Lock* tick_lock = NULL;  // To protect during rollover periods.

  // Lazily create the lock we use.
  if (!tick_lock) {
    Lock* new_lock = new Lock;
    if (InterlockedCompareExchangePointer(
        reinterpret_cast<PVOID*>(&tick_lock), new_lock, NULL)) {
      delete new_lock;
    }
  }

  // Atomically protect the low and high 32bit values for time.
  // In the future we may be able to optimize with
  // InterlockedCompareExchange64, but that doesn't work on XP.
  DWORD tick_count;
  int64_t rollover_count;
  /* lint complains about this, ignore */{
    AutoLock lock(*tick_lock);
    tick_count = tick_function_();
    if (tick_count < last_tick_count)
      tick_rollover_accum += GG_INT64_C(0x100000000);

    last_tick_count = tick_count;
    rollover_count = tick_rollover_accum;
  }

  // GetTickCount returns milliseconds, we want microseconds.
  return TimeTicks((tick_count + rollover_count) *
                   Time::kMicrosecondsPerMillisecond);
}

// Overview of time counters:
// (1) CPU cycle counter. (Retrieved via RDTSC)
// The CPU counter provides the highest resolution time stamp and is the least
// expensive to retrieve. However, the CPU counter is unreliable and should not
// be used in production. Its biggest issue is that it is per processor and it
// is not synchronized between processors. Also, on some computers, the counters
// will change frequency due to thermal and power changes, and stop in some
// states.
//
// (2) QueryPerformanceCounter (QPC). The QPC counter provides a high-
// resolution (100 nanoseconds) time stamp but is comparatively more expensive
// to retrieve. What QueryPerformanceCounter actually does is up to the HAL.
// (with some help from ACPI).
// According to http://blogs.msdn.com/oldnewthing/archive/2005/09/02/459952.aspx
// in the worst case, it gets the counter from the rollover interrupt on the
// programmable interrupt timer. In best cases, the HAL may conclude that the
// RDTSC counter runs at a constant frequency, then it uses that instead. On
// multiprocessor machines, it will try to verify the values returned from
// RDTSC on each processor are consistent with each other, and apply a handful
// of workarounds for known buggy hardware. In other words, QPC is supposed to
// give consistent result on a multiprocessor computer, but it is unreliable in
// reality due to bugs in BIOS or HAL on some, especially old computers.
// With recent updates on HAL and newer BIOS, QPC is getting more reliable but
// it should be used with caution.
//
// (3) System time. The system time provides a low-resolution (typically 10ms
// to 55 milliseconds) time stamp but is comparatively less expensive to
// retrieve and more reliable.

// static
NaCl::TimeTicks NaCl::TimeTicks::UnreliableHighResNow() {
  // Cached clock frequency -> microseconds. This assumes that the clock
  // frequency is faster than one microsecond (which is 1MHz, should be OK).
  static int64_t ticks_per_microsecond = 0;

  if (ticks_per_microsecond == 0) {
    LARGE_INTEGER ticks_per_sec = { 0, 0 };
    if (!QueryPerformanceFrequency(&ticks_per_sec))
      return TimeTicks(0);  // Broken, we don't guarantee this function works.
    ticks_per_microsecond =
        ticks_per_sec.QuadPart / Time::kMicrosecondsPerSecond;
  }

  LARGE_INTEGER now;
  QueryPerformanceCounter(&now);
  return TimeTicks(now.QuadPart / ticks_per_microsecond);
}
<commit_msg>Missing * in sizeof expression.  Thanks to Nico for finding this at  http://codereview.chromium.org/7057021/ BUG=http://code.google.com/p/chromium/issues/detail?id=83236 TEST=none Review URL: http://codereview.chromium.org/7062009<commit_after>/*
 * Copyright (c) 2011 The Native Client Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

// Make sure that winmm.lib is added to the linker's input.
#pragma comment(lib, "winmm.lib")
#include "native_client/src/include/portability.h"
#include <mmsystem.h>
#include <windows.h>

#include "native_client/src/include/checked_cast.h"
#include "native_client/src/shared/platform/win/time.h"
#include "native_client/src/shared/platform/win/lock.h"

namespace {

// From MSDN, FILETIME "Contains a 64-bit value representing the number of
// 100-nanosecond intervals since January 1, 1601 (UTC)."
int64_t FileTimeToMicroseconds(const FILETIME& ft) {
  // Need to nacl_bit_cast to fix alignment, then divide by 10 to convert
  // 100-nanoseconds to milliseconds. This only works on little-endian
  // machines.
  return nacl_bit_cast<int64_t, FILETIME>(ft) / 10;
}

void MicrosecondsToFileTime(int64_t us, FILETIME* ft) {
/*  DCHECK(us >= 0) << "Time is less than 0, negative values are not "
 *      "representable in FILETIME";
 */

  // Multiply by 10 to convert milliseconds to 100-nanoseconds. Nacl_bit_cast
  // will handle alignment problems. This only works on little-endian machines.
  *ft = nacl_bit_cast<FILETIME, int64_t>(us * 10);
}

}  // namespace

// Time -----------------------------------------------------------------------

// The internal representation of Time uses FILETIME, whose epoch is 1601-01-01
// 00:00:00 UTC.  ((1970-1601)*365+89)*24*60*60*1000*1000, where 89 is the
// number of leap year days between 1601 and 1970: (1970-1601)/4 excluding
// 1700, 1800, and 1900.
// static
const int64_t NaCl::Time::kTimeTToMicrosecondsOffset =
    GG_INT64_C(11644473600000000);

// static
int64_t NaCl::Time::CurrentWallclockMicroseconds() {
  FILETIME ft;
  ::GetSystemTimeAsFileTime(&ft);
  return FileTimeToMicroseconds(ft);
}

// static
NaCl::Time NaCl::Time::FromFileTime(FILETIME ft) {
  return Time(FileTimeToMicroseconds(ft));
}

FILETIME NaCl::Time::ToFileTime() const {
  FILETIME utc_ft;
  MicrosecondsToFileTime(us_, &utc_ft);
  return utc_ft;
}

// static
NaCl::Time NaCl::Time::FromExploded(bool is_local, const Exploded& exploded) {
  // Create the system struct representing our exploded time. It will either be
  // in local time or UTC.
  SYSTEMTIME st;
  st.wYear = nacl::assert_cast<WORD>(exploded.year);
  st.wMonth = nacl::assert_cast<WORD>(exploded.month);
  st.wDayOfWeek = nacl::assert_cast<WORD>(exploded.day_of_week);
  st.wDay = nacl::assert_cast<WORD>(exploded.day_of_month);
  st.wHour = nacl::assert_cast<WORD>(exploded.hour);
  st.wMinute = nacl::assert_cast<WORD>(exploded.minute);
  st.wSecond = nacl::assert_cast<WORD>(exploded.second);
  st.wMilliseconds = nacl::assert_cast<WORD>(exploded.millisecond);

  // Convert to FILETIME.
  FILETIME ft;
  if (!SystemTimeToFileTime(&st, &ft)) {
    // NOTREACHED() << "Unable to convert time";
    return Time(0);
  }

  // Ensure that it's in UTC.
  if (is_local) {
    FILETIME utc_ft;
    LocalFileTimeToFileTime(&ft, &utc_ft);
    return Time(FileTimeToMicroseconds(utc_ft));
  }
  return Time(FileTimeToMicroseconds(ft));
}

void NaCl::Time::Explode(bool is_local, Exploded* exploded) const {
  // FILETIME in UTC.
  FILETIME utc_ft;
  MicrosecondsToFileTime(us_, &utc_ft);

  // FILETIME in local time if necessary.
  BOOL success = TRUE;
  FILETIME ft;
  if (is_local)
    success = FileTimeToLocalFileTime(&utc_ft, &ft);
  else
    ft = utc_ft;

  // FILETIME in SYSTEMTIME (exploded).
  SYSTEMTIME st;
  if (!success || !FileTimeToSystemTime(&ft, &st)) {
    // NOTREACHED() << "Unable to convert time, don't know why";
    ZeroMemory(exploded, sizeof(*exploded));
    return;
  }

  exploded->year = st.wYear;
  exploded->month = st.wMonth;
  exploded->day_of_week = st.wDayOfWeek;
  exploded->day_of_month = st.wDay;
  exploded->hour = st.wHour;
  exploded->minute = st.wMinute;
  exploded->second = st.wSecond;
  exploded->millisecond = st.wMilliseconds;
}

// TimeTicks ------------------------------------------------------------------
NaCl::TimeTicks::TickFunction NaCl::TimeTicks::tick_function_=
    reinterpret_cast<TickFunction>(&timeGetTime);

// static
NaCl::TimeTicks NaCl::TimeTicks::Now() {
  // Uses the multimedia timers on Windows to get a higher resolution clock.
  // timeGetTime() provides a resolution which is variable depending on
  // hardware and system configuration.  It can also be changed by other
  // apps.  This class does not attempt to change the resolution of the
  // timer, because we don't want to affect other applications.

  // timeGetTime() should at least be accurate to ~5ms on all systems.
  // timeGetTime() returns a 32-bit millisecond counter which has rollovers
  // every ~49 days.
  static DWORD last_tick_count = 0;
  static int64_t tick_rollover_accum = 0;
  static Lock* tick_lock = NULL;  // To protect during rollover periods.

  // Lazily create the lock we use.
  if (!tick_lock) {
    Lock* new_lock = new Lock;
    if (InterlockedCompareExchangePointer(
        reinterpret_cast<PVOID*>(&tick_lock), new_lock, NULL)) {
      delete new_lock;
    }
  }

  // Atomically protect the low and high 32bit values for time.
  // In the future we may be able to optimize with
  // InterlockedCompareExchange64, but that doesn't work on XP.
  DWORD tick_count;
  int64_t rollover_count;
  /* lint complains about this, ignore */{
    AutoLock lock(*tick_lock);
    tick_count = tick_function_();
    if (tick_count < last_tick_count)
      tick_rollover_accum += GG_INT64_C(0x100000000);

    last_tick_count = tick_count;
    rollover_count = tick_rollover_accum;
  }

  // GetTickCount returns milliseconds, we want microseconds.
  return TimeTicks((tick_count + rollover_count) *
                   Time::kMicrosecondsPerMillisecond);
}

// Overview of time counters:
// (1) CPU cycle counter. (Retrieved via RDTSC)
// The CPU counter provides the highest resolution time stamp and is the least
// expensive to retrieve. However, the CPU counter is unreliable and should not
// be used in production. Its biggest issue is that it is per processor and it
// is not synchronized between processors. Also, on some computers, the counters
// will change frequency due to thermal and power changes, and stop in some
// states.
//
// (2) QueryPerformanceCounter (QPC). The QPC counter provides a high-
// resolution (100 nanoseconds) time stamp but is comparatively more expensive
// to retrieve. What QueryPerformanceCounter actually does is up to the HAL.
// (with some help from ACPI).
// According to http://blogs.msdn.com/oldnewthing/archive/2005/09/02/459952.aspx
// in the worst case, it gets the counter from the rollover interrupt on the
// programmable interrupt timer. In best cases, the HAL may conclude that the
// RDTSC counter runs at a constant frequency, then it uses that instead. On
// multiprocessor machines, it will try to verify the values returned from
// RDTSC on each processor are consistent with each other, and apply a handful
// of workarounds for known buggy hardware. In other words, QPC is supposed to
// give consistent result on a multiprocessor computer, but it is unreliable in
// reality due to bugs in BIOS or HAL on some, especially old computers.
// With recent updates on HAL and newer BIOS, QPC is getting more reliable but
// it should be used with caution.
//
// (3) System time. The system time provides a low-resolution (typically 10ms
// to 55 milliseconds) time stamp but is comparatively less expensive to
// retrieve and more reliable.

// static
NaCl::TimeTicks NaCl::TimeTicks::UnreliableHighResNow() {
  // Cached clock frequency -> microseconds. This assumes that the clock
  // frequency is faster than one microsecond (which is 1MHz, should be OK).
  static int64_t ticks_per_microsecond = 0;

  if (ticks_per_microsecond == 0) {
    LARGE_INTEGER ticks_per_sec = { 0, 0 };
    if (!QueryPerformanceFrequency(&ticks_per_sec))
      return TimeTicks(0);  // Broken, we don't guarantee this function works.
    ticks_per_microsecond =
        ticks_per_sec.QuadPart / Time::kMicrosecondsPerSecond;
  }

  LARGE_INTEGER now;
  QueryPerformanceCounter(&now);
  return TimeTicks(now.QuadPart / ticks_per_microsecond);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: property.cxx,v $
 * $Revision: 1.12 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_comphelper.hxx"

#include <comphelper/property.hxx>
#include <comphelper/sequence.hxx>
#include <comphelper/types.hxx>
#include <osl/diagnose.h>

#if OSL_DEBUG_LEVEL > 0
    #include <rtl/strbuf.hxx>
    #include <cppuhelper/exc_hlp.hxx>
    #include <osl/thread.h>
    #include <com/sun/star/lang/XServiceInfo.hpp>
    #include <typeinfo.h>
#endif
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/uno/genfunc.h>

#include <algorithm>
#include <boost/bind.hpp>

//.........................................................................
namespace comphelper
{

    /** === begin UNO using === **/
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::beans::XPropertySet;
    using ::com::sun::star::beans::XPropertySetInfo;
    using ::com::sun::star::beans::Property;
    using ::com::sun::star::uno::Sequence;
    using ::com::sun::star::uno::Exception;
    using ::com::sun::star::uno::Any;
    using ::com::sun::star::uno::Type;
    using ::com::sun::star::uno::cpp_queryInterface;
    using ::com::sun::star::uno::cpp_acquire;
    using ::com::sun::star::uno::cpp_release;
    using ::com::sun::star::lang::XServiceInfo;
    using ::com::sun::star::uno::UNO_QUERY;
    /** === end UNO using === **/
    namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute;

//------------------------------------------------------------------
void copyProperties(const Reference<XPropertySet>& _rxSource,
                    const Reference<XPropertySet>& _rxDest)
{
    if (!_rxSource.is() || !_rxDest.is())
    {
        OSL_ENSURE(sal_False, "copyProperties: invalid arguments !");
        return;
    }

    Reference< XPropertySetInfo > xSourceProps = _rxSource->getPropertySetInfo();
    Reference< XPropertySetInfo > xDestProps = _rxDest->getPropertySetInfo();

    Sequence< Property > aSourceProps = xSourceProps->getProperties();
    const Property* pSourceProps = aSourceProps.getConstArray();
    Property aDestProp;
    for (sal_Int32 i=0; i<aSourceProps.getLength(); ++i, ++pSourceProps)
    {
        if ( xDestProps->hasPropertyByName(pSourceProps->Name) )
        {
            try
            {
                aDestProp = xDestProps->getPropertyByName(pSourceProps->Name);
                if (0 == (aDestProp.Attributes & PropertyAttribute::READONLY) )
                {
                    const Any aSourceValue = _rxSource->getPropertyValue(pSourceProps->Name);
                    if ( 0 != (aDestProp.Attributes & PropertyAttribute::MAYBEVOID) || aSourceValue.hasValue() )
                        _rxDest->setPropertyValue(pSourceProps->Name, aSourceValue);
                }
            }
            catch (Exception&)
            {
#if OSL_DEBUG_LEVEL > 0
                ::rtl::OStringBuffer aBuffer;
                aBuffer.append( "::comphelper::copyProperties: could not copy property '" );
                aBuffer.append( ::rtl::OString( pSourceProps->Name.getStr(), pSourceProps->Name.getLength(), RTL_TEXTENCODING_ASCII_US ) );
                aBuffer.append( "' to the destination set (a '" );

                Reference< XServiceInfo > xSI( _rxDest, UNO_QUERY );
                if ( xSI.is() )
                {
                    aBuffer.append( ::rtl::OUStringToOString( xSI->getImplementationName(), osl_getThreadTextEncoding() ) );
                }
                else
                {
                    aBuffer.append( typeid( *_rxDest.get() ).name() );
                }
                aBuffer.append( "' implementation).\n" );

                Any aException( ::cppu::getCaughtException() );
                aBuffer.append( "Caught an exception of type '" );
                ::rtl::OUString sExceptionType( aException.getValueTypeName() );
                aBuffer.append( ::rtl::OString( sExceptionType.getStr(), sExceptionType.getLength(), RTL_TEXTENCODING_ASCII_US ) );
                aBuffer.append( "'" );

                Exception aBaseException;
                if ( ( aException >>= aBaseException ) && aBaseException.Message.getLength() )
                {
                    aBuffer.append( ", saying '" );
                    aBuffer.append( ::rtl::OString( aBaseException.Message.getStr(), aBaseException.Message.getLength(), osl_getThreadTextEncoding() ) );
                    aBuffer.append( "'" );
                }
                aBuffer.append( "." );

                OSL_ENSURE( sal_False, aBuffer.getStr() );
#endif
            }
        }
    }
}

//------------------------------------------------------------------
sal_Bool hasProperty(const rtl::OUString& _rName, const Reference<XPropertySet>& _rxSet)
{
    if (_rxSet.is())
    {
        //  XPropertySetInfoRef xInfo(rxSet->getPropertySetInfo());
        return _rxSet->getPropertySetInfo()->hasPropertyByName(_rName);
    }
    return sal_False;
}

//------------------------------------------------------------------
bool findProperty(Property&              o_rProp,
                  Sequence<Property>&    i_seqProps,
                  const ::rtl::OUString& i_rPropName)
{
    const Property* pAry(i_seqProps.getConstArray());
    const sal_Int32 nLen(i_seqProps.getLength());
    const Property* pRes(
        std::find_if(pAry,pAry+nLen,
                     boost::bind(PropertyStringEqualFunctor(),
                                 _1,
                                 boost::cref(i_rPropName))));
    if( pRes == pAry+nLen )
        return false;

    o_rProp = *pRes;
    return true;
}

//------------------------------------------------------------------
void RemoveProperty(Sequence<Property>& _rProps, const rtl::OUString& _rPropName)
{
    sal_Int32 nLen = _rProps.getLength();

    // binaere Suche
    const Property* pProperties = _rProps.getConstArray();
    const Property* pResult = ::std::lower_bound(pProperties, pProperties + nLen, _rPropName,PropertyStringLessFunctor());

    // gefunden ?
    if ( pResult && (pResult != pProperties + nLen) && (pResult->Name == _rPropName) )
    {
        OSL_ENSURE(pResult->Name.equals(_rPropName), "::RemoveProperty Properties nicht sortiert");
        removeElementAt(_rProps, pResult - pProperties);
    }
}

//------------------------------------------------------------------
void ModifyPropertyAttributes(Sequence<Property>& seqProps, const ::rtl::OUString& sPropName, sal_Int16 nAddAttrib, sal_Int16 nRemoveAttrib)
{
    sal_Int32 nLen = seqProps.getLength();

    // binaere Suche
    Property* pProperties = seqProps.getArray();
    Property* pResult = ::std::lower_bound(pProperties, pProperties + nLen,sPropName, PropertyStringLessFunctor());

    // gefunden ?
    if ( pResult && (pResult != pProperties + nLen) && (pResult->Name == sPropName) )
    {
        pResult->Attributes |= nAddAttrib;
        pResult->Attributes &= ~nRemoveAttrib;
    }
}

//------------------------------------------------------------------
sal_Bool tryPropertyValue(Any& _rConvertedValue, Any& _rOldValue, const Any& _rValueToSet, const Any& _rCurrentValue, const Type& _rExpectedType)
{
    sal_Bool bModified(sal_False);
    if (_rCurrentValue.getValue() != _rValueToSet.getValue())
    {
        if ( _rValueToSet.hasValue() && ( !_rExpectedType.equals( _rValueToSet.getValueType() ) ) )
        {
            _rConvertedValue = Any( NULL, _rExpectedType.getTypeLibType() );

            if  ( !uno_type_assignData(
                    const_cast< void* >( _rConvertedValue.getValue() ), _rConvertedValue.getValueType().getTypeLibType(),
                    const_cast< void* >( _rValueToSet.getValue() ), _rValueToSet.getValueType().getTypeLibType(),
                    reinterpret_cast< uno_QueryInterfaceFunc >(
                        cpp_queryInterface),
                    reinterpret_cast< uno_AcquireFunc >(cpp_acquire),
                    reinterpret_cast< uno_ReleaseFunc >(cpp_release)
                  )
                )
                throw starlang::IllegalArgumentException();
        }
        else
            _rConvertedValue = _rValueToSet;

        if ( _rCurrentValue != _rConvertedValue )
        {
            _rOldValue = _rCurrentValue;
            bModified = sal_True;
        }
    }
    return bModified;
}

//.........................................................................
}
//.........................................................................

<commit_msg>#i10000#<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: property.cxx,v $
 * $Revision: 1.12 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_comphelper.hxx"

#include <comphelper/property.hxx>
#include <comphelper/sequence.hxx>
#include <comphelper/types.hxx>
#include <osl/diagnose.h>

#if OSL_DEBUG_LEVEL > 0
    #include <rtl/strbuf.hxx>
    #include <cppuhelper/exc_hlp.hxx>
    #include <osl/thread.h>
    #include <com/sun/star/lang/XServiceInfo.hpp>
    #include <typeinfo.h>
#endif
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/uno/genfunc.h>

#include <algorithm>
#include <boost/bind.hpp>

//.........................................................................
namespace comphelper
{

    /** === begin UNO using === **/
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::beans::XPropertySet;
    using ::com::sun::star::beans::XPropertySetInfo;
    using ::com::sun::star::beans::Property;
    using ::com::sun::star::uno::Sequence;
    using ::com::sun::star::uno::Exception;
    using ::com::sun::star::uno::Any;
    using ::com::sun::star::uno::Type;
    using ::com::sun::star::uno::cpp_queryInterface;
    using ::com::sun::star::uno::cpp_acquire;
    using ::com::sun::star::uno::cpp_release;
#if OSL_DEBUG_LEVEL > 0
    using ::com::sun::star::lang::XServiceInfo;
#endif
    using ::com::sun::star::uno::UNO_QUERY;
    /** === end UNO using === **/
    namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute;

//------------------------------------------------------------------
void copyProperties(const Reference<XPropertySet>& _rxSource,
                    const Reference<XPropertySet>& _rxDest)
{
    if (!_rxSource.is() || !_rxDest.is())
    {
        OSL_ENSURE(sal_False, "copyProperties: invalid arguments !");
        return;
    }

    Reference< XPropertySetInfo > xSourceProps = _rxSource->getPropertySetInfo();
    Reference< XPropertySetInfo > xDestProps = _rxDest->getPropertySetInfo();

    Sequence< Property > aSourceProps = xSourceProps->getProperties();
    const Property* pSourceProps = aSourceProps.getConstArray();
    Property aDestProp;
    for (sal_Int32 i=0; i<aSourceProps.getLength(); ++i, ++pSourceProps)
    {
        if ( xDestProps->hasPropertyByName(pSourceProps->Name) )
        {
            try
            {
                aDestProp = xDestProps->getPropertyByName(pSourceProps->Name);
                if (0 == (aDestProp.Attributes & PropertyAttribute::READONLY) )
                {
                    const Any aSourceValue = _rxSource->getPropertyValue(pSourceProps->Name);
                    if ( 0 != (aDestProp.Attributes & PropertyAttribute::MAYBEVOID) || aSourceValue.hasValue() )
                        _rxDest->setPropertyValue(pSourceProps->Name, aSourceValue);
                }
            }
            catch (Exception&)
            {
#if OSL_DEBUG_LEVEL > 0
                ::rtl::OStringBuffer aBuffer;
                aBuffer.append( "::comphelper::copyProperties: could not copy property '" );
                aBuffer.append( ::rtl::OString( pSourceProps->Name.getStr(), pSourceProps->Name.getLength(), RTL_TEXTENCODING_ASCII_US ) );
                aBuffer.append( "' to the destination set (a '" );

                Reference< XServiceInfo > xSI( _rxDest, UNO_QUERY );
                if ( xSI.is() )
                {
                    aBuffer.append( ::rtl::OUStringToOString( xSI->getImplementationName(), osl_getThreadTextEncoding() ) );
                }
                else
                {
                    aBuffer.append( typeid( *_rxDest.get() ).name() );
                }
                aBuffer.append( "' implementation).\n" );

                Any aException( ::cppu::getCaughtException() );
                aBuffer.append( "Caught an exception of type '" );
                ::rtl::OUString sExceptionType( aException.getValueTypeName() );
                aBuffer.append( ::rtl::OString( sExceptionType.getStr(), sExceptionType.getLength(), RTL_TEXTENCODING_ASCII_US ) );
                aBuffer.append( "'" );

                Exception aBaseException;
                if ( ( aException >>= aBaseException ) && aBaseException.Message.getLength() )
                {
                    aBuffer.append( ", saying '" );
                    aBuffer.append( ::rtl::OString( aBaseException.Message.getStr(), aBaseException.Message.getLength(), osl_getThreadTextEncoding() ) );
                    aBuffer.append( "'" );
                }
                aBuffer.append( "." );

                OSL_ENSURE( sal_False, aBuffer.getStr() );
#endif
            }
        }
    }
}

//------------------------------------------------------------------
sal_Bool hasProperty(const rtl::OUString& _rName, const Reference<XPropertySet>& _rxSet)
{
    if (_rxSet.is())
    {
        //  XPropertySetInfoRef xInfo(rxSet->getPropertySetInfo());
        return _rxSet->getPropertySetInfo()->hasPropertyByName(_rName);
    }
    return sal_False;
}

//------------------------------------------------------------------
bool findProperty(Property&              o_rProp,
                  Sequence<Property>&    i_seqProps,
                  const ::rtl::OUString& i_rPropName)
{
    const Property* pAry(i_seqProps.getConstArray());
    const sal_Int32 nLen(i_seqProps.getLength());
    const Property* pRes(
        std::find_if(pAry,pAry+nLen,
                     boost::bind(PropertyStringEqualFunctor(),
                                 _1,
                                 boost::cref(i_rPropName))));
    if( pRes == pAry+nLen )
        return false;

    o_rProp = *pRes;
    return true;
}

//------------------------------------------------------------------
void RemoveProperty(Sequence<Property>& _rProps, const rtl::OUString& _rPropName)
{
    sal_Int32 nLen = _rProps.getLength();

    // binaere Suche
    const Property* pProperties = _rProps.getConstArray();
    const Property* pResult = ::std::lower_bound(pProperties, pProperties + nLen, _rPropName,PropertyStringLessFunctor());

    // gefunden ?
    if ( pResult && (pResult != pProperties + nLen) && (pResult->Name == _rPropName) )
    {
        OSL_ENSURE(pResult->Name.equals(_rPropName), "::RemoveProperty Properties nicht sortiert");
        removeElementAt(_rProps, pResult - pProperties);
    }
}

//------------------------------------------------------------------
void ModifyPropertyAttributes(Sequence<Property>& seqProps, const ::rtl::OUString& sPropName, sal_Int16 nAddAttrib, sal_Int16 nRemoveAttrib)
{
    sal_Int32 nLen = seqProps.getLength();

    // binaere Suche
    Property* pProperties = seqProps.getArray();
    Property* pResult = ::std::lower_bound(pProperties, pProperties + nLen,sPropName, PropertyStringLessFunctor());

    // gefunden ?
    if ( pResult && (pResult != pProperties + nLen) && (pResult->Name == sPropName) )
    {
        pResult->Attributes |= nAddAttrib;
        pResult->Attributes &= ~nRemoveAttrib;
    }
}

//------------------------------------------------------------------
sal_Bool tryPropertyValue(Any& _rConvertedValue, Any& _rOldValue, const Any& _rValueToSet, const Any& _rCurrentValue, const Type& _rExpectedType)
{
    sal_Bool bModified(sal_False);
    if (_rCurrentValue.getValue() != _rValueToSet.getValue())
    {
        if ( _rValueToSet.hasValue() && ( !_rExpectedType.equals( _rValueToSet.getValueType() ) ) )
        {
            _rConvertedValue = Any( NULL, _rExpectedType.getTypeLibType() );

            if  ( !uno_type_assignData(
                    const_cast< void* >( _rConvertedValue.getValue() ), _rConvertedValue.getValueType().getTypeLibType(),
                    const_cast< void* >( _rValueToSet.getValue() ), _rValueToSet.getValueType().getTypeLibType(),
                    reinterpret_cast< uno_QueryInterfaceFunc >(
                        cpp_queryInterface),
                    reinterpret_cast< uno_AcquireFunc >(cpp_acquire),
                    reinterpret_cast< uno_ReleaseFunc >(cpp_release)
                  )
                )
                throw starlang::IllegalArgumentException();
        }
        else
            _rConvertedValue = _rValueToSet;

        if ( _rCurrentValue != _rConvertedValue )
        {
            _rOldValue = _rCurrentValue;
            bModified = sal_True;
        }
    }
    return bModified;
}

//.........................................................................
}
//.........................................................................

<|endoftext|>


<commit_before>#include "../SDP_Solver.hxx"

// Create and initialize an SDPSolver for the given SDP and
// SDP_Solver_Parameters
SDP_Solver::SDP_Solver(const std::vector<boost::filesystem::path> &sdp_files,
                       const SDP_Solver_Parameters &parameters)
    : sdp(sdp_files), parameters(parameters),
      x(sdp.primal_objective_c.size(), 0),
      x_elemental(sdp.schur_block_dims(), 1), X(sdp.psd_matrix_block_dims()),
      y(sdp.dual_objective_b_elemental.Height(), 0),
      y_elemental(sdp.dual_objective_b_elemental.Height(), 1), Y(X),
      primal_residues(X), dual_residues(x),
      // FIXME: Maybe we can use schur_block_dims() instead of making a copy?
      dual_residues_elemental(x_elemental)
{
  Zero(y_elemental);

  // X = \Omega_p I
  X.add_diagonal(parameters.initial_matrix_scale_primal);
  X.add_diagonal(parameters.initial_matrix_scale_primal_elemental);
  // Y = \Omega_d I
  Y.add_diagonal(parameters.initial_matrix_scale_dual);
  Y.add_diagonal(parameters.initial_matrix_scale_dual_elemental);
}
<commit_msg>Explicitly initialize X and Y to zero<commit_after>#include "../SDP_Solver.hxx"

// Create and initialize an SDPSolver for the given SDP and
// SDP_Solver_Parameters
SDP_Solver::SDP_Solver(const std::vector<boost::filesystem::path> &sdp_files,
                       const SDP_Solver_Parameters &parameters)
    : sdp(sdp_files), parameters(parameters),
      x(sdp.primal_objective_c.size(), 0),
      x_elemental(sdp.schur_block_dims(), 1), X(sdp.psd_matrix_block_dims()),
      y(sdp.dual_objective_b_elemental.Height(), 0),
      y_elemental(sdp.dual_objective_b_elemental.Height(), 1), Y(X),
      primal_residues(X), dual_residues(x),
      // FIXME: Maybe we can use schur_block_dims() instead of making a copy?
      dual_residues_elemental(x_elemental)
{
  X.set_zero();
  Y.set_zero();
  Zero(y_elemental);

  // X = \Omega_p I
  X.add_diagonal(parameters.initial_matrix_scale_primal);
  X.add_diagonal(parameters.initial_matrix_scale_primal_elemental);
  // Y = \Omega_d I
  Y.add_diagonal(parameters.initial_matrix_scale_dual);
  Y.add_diagonal(parameters.initial_matrix_scale_dual_elemental);
}
<|endoftext|>


<commit_before>/*******************************************************************************
  fsm11 - A C++11-compliant framework for finite state machines

  Copyright (c) 2015, Manuel Freiberger
  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.

  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 HOLDER 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.
*******************************************************************************/

#ifndef FSM11_THREADPOOL_HPP
#define FSM11_THREADPOOL_HPP

#include "statemachine_fwd.hpp"
#include "error.hpp"
#include "detail/threadedstatebase.hpp"

#ifdef FSM11_USE_WEOS
#include <boost/container/static_vector.hpp>
#include <weos/condition_variable.hpp>
#include <weos/future.hpp>
#include <weos/mutex.hpp>
#include <weos/thread.hpp>
#include <weos/tuple.hpp>
#include <weos/utility.hpp>
#else
#include <condition_variable>
#include <future>
#include <mutex>
#include <thread>
#include <utility>
#include <vector>
#endif // FSM11_USE_WEOS

namespace fsm11
{
namespace fsm11_detail
{

template <bool... TValues>
struct all : FSM11STD::true_type
{
};

template <bool THead, bool... TTail>
struct all<THead, TTail...> : FSM11STD::conditional<THead,
                                                    all<TTail...>,
                                                    FSM11STD::false_type>::type
{
};

} // namespace fsm11_detail

template <std::size_t TSize>
class ThreadPool
{
    static_assert(TSize > 0, "The thread pool must be non-empty.");

    struct Task
    {
        Task(fsm11_detail::ThreadedStateBase& s)
            : state(s)
        {
        }

        Task(Task&& other)
            : promise(FSM11STD::move(other.promise)),
              state(other.state)
        {
        }

        Task(const Task&) = delete;
        Task& operator=(const Task&) = delete;

        FSM11STD::promise<void> promise;
        fsm11_detail::ThreadedStateBase& state;
    };

    struct Handle
    {
        explicit Handle(ThreadPool* pool, int id);

        Handle(const Handle&) = delete;
        Handle& operator=(const Handle&) = delete;

        bool hasChanged(ThreadPool* current) const
        {
            return m_pool != current;
        }

        ThreadPool* change(ThreadPool* current, int id);

        ThreadPool* m_pool;
        Handle* m_next{nullptr};
    };

public:
#ifdef FSM11_USE_WEOS
    template <typename... TAttributes>
    explicit ThreadPool(const FSM11STD::thread::attributes& attr,
                        const TAttributes&... attributes);
#else
    //! Constructs a thread pool.
    ThreadPool();
#endif // FSM11_USE_WEOS

    ThreadPool(const ThreadPool&) = delete;

    //! Move-constructs a thread pool from the \p other pool.
    ThreadPool(ThreadPool&& other);

    //! Destroys the thread pool.
    ~ThreadPool();

    ThreadPool& operator=(const ThreadPool&) = delete;

    //! Move-assigns the \p other pool to this one.
    ThreadPool& operator=(ThreadPool&& other);

    FSM11STD::future<void> enqueue(fsm11_detail::ThreadedStateBase& state);

private:
    FSM11STD::mutex m_poolMutex;

    FSM11STD::mutex m_workerMutex; // TODO: rethink the locking policy
    FSM11STD::condition_variable m_workerCv;
    FSM11STD::condition_variable m_assignmentCv;
    unsigned m_assignedWorkers{0};
    int m_idleWorkers{TSize};
    Handle* m_handles{nullptr};
#ifdef FSM11_USE_WEOS
    boost::container::static_vector<Task, TSize> m_tasks;
#else
    FSM11STD::vector<Task> m_tasks;
#endif

    void moveTo(FSM11STD::unique_lock<FSM11STD::mutex>&& lock,
                ThreadPool* newPool);

    static void work(ThreadPool* pool, int id);

#ifdef FSM11_USE_WEOS
    template <typename TAttributes, std::size_t... TIndices>
    void construct(TAttributes&& attributes,
                   FSM11STD::integer_sequence<std::size_t, TIndices...>)
    {
        using namespace FSM11STD;

        unsigned workers = 0;
        try
        {
            call(constructOne(get<TIndices>(attributes), TIndices, workers)...);
            unique_lock<mutex> lock(m_workerMutex);
            m_assignmentCv.wait(lock,
                                [&]{ return m_assignedWorkers == workers; });
        }
        catch (...)
        {
            unique_lock<mutex> lock(m_workerMutex);
            m_assignmentCv.wait(lock,
                                [&]{ return m_assignedWorkers == workers; });
            moveTo(move(lock), nullptr);
            throw;
        }
    }

    int constructOne(const FSM11STD::thread::attributes& attr,
                     std::size_t idx, unsigned& workers)
    {
        FSM11STD::thread(attr, &ThreadPool::work, this, idx).detach();
        workers |= 1 << idx;
        return 0;
    }

    template <typename... T>
    void call(T...)
    {
    }
#endif
};

#ifdef FSM11_USE_WEOS
template <std::size_t TSize>
template <typename... TAttributes>
ThreadPool<TSize>::ThreadPool(const FSM11STD::thread::attributes& attr,
                              const TAttributes&... attributes)
{
    using namespace FSM11STD;

    static_assert(fsm11_detail::all<
                      is_same<TAttributes, thread::attributes>::value...
                  >::value,
                  "All arguments have to be thread attributes");
    static_assert(1 + sizeof...(TAttributes) == TSize,
                  "The number of thread attributes must equal the pool size.");

    construct(forward_as_tuple(attr, attributes...),
              make_index_sequence<1 + sizeof...(attributes)>());
}
#else
template <std::size_t TSize>
ThreadPool<TSize>::ThreadPool()
{
    using namespace FSM11STD;

    unsigned workers = 0;
    try
    {
        for (std::size_t idx = 0; idx < TSize; ++idx)
        {
            thread(&ThreadPool::work, this, idx).detach();
            workers |= 1 << idx;
        }

        unique_lock<mutex> lock(m_workerMutex);
        m_assignmentCv.wait(lock, [&]{ return m_assignedWorkers == workers; });
    }
    catch (...)
    {
        unique_lock<mutex> lock(m_workerMutex);
        m_assignmentCv.wait(lock, [&]{ return m_assignedWorkers == workers; });
        moveTo(move(lock), nullptr);
        throw;
    }
}
#endif // FSM11_USE_WEOS

template <std::size_t TSize>
ThreadPool<TSize>::ThreadPool(ThreadPool&& other)
{
    using namespace FSM11STD;

    lock_guard<mutex> otherPoolLock(m_poolMutex);

    unique_lock<mutex> otherWorkerLock(other.m_workerMutex);
    unsigned workers = other.m_assignedWorkers;
    m_handles = other.m_handles;
    other.moveTo(move(otherWorkerLock), this);

    unique_lock<mutex> thisWorkerLock(m_workerMutex);
    m_assignmentCv.wait(thisWorkerLock,
                        [&]{ return m_assignedWorkers == workers; });
}

template <std::size_t TSize>
ThreadPool<TSize>::~ThreadPool()
{
    moveTo(FSM11STD::unique_lock<FSM11STD::mutex>(m_workerMutex), nullptr);
}

template <std::size_t TSize>
auto ThreadPool<TSize>::operator=(ThreadPool&& other) -> ThreadPool&
{
    using namespace FSM11STD;

    if (this == &other)
        return *this;

    // It is important to use a dead-lock avoiding algorithm for the
    // two pool mutexes here or we dead-lock the application.
    lock(m_poolMutex, other.m_poolMutex);
    lock_guard<mutex> thisPoolLock(m_poolMutex, adopt_lock);
    lock_guard<mutex> otherPoolLock(other.m_poolMutex, adopt_lock);

    moveTo(unique_lock<mutex>(m_workerMutex), nullptr);

    unique_lock<mutex> otherWorkerLock(other.m_workerMutex);
    unsigned workers = other.m_assignedWorkers;
    m_handles = other.m_handles;
    other.moveTo(move(otherWorkerLock), this);

    unique_lock<mutex> thisWorkerLock(m_workerMutex);
    m_assignmentCv.wait(thisWorkerLock,
                        [&]{ return m_assignedWorkers == workers; });

    return *this;
}

template <std::size_t TSize>
FSM11STD::future<void>
ThreadPool<TSize>::enqueue(fsm11_detail::ThreadedStateBase& state)
{
    using namespace FSM11STD;

    lock_guard<mutex> lock(m_workerMutex);
    if (m_idleWorkers == 0)
        throw FSM11_EXCEPTION(Error(ErrorCode::ThreadPoolUnderflow));
    --m_idleWorkers;

    m_tasks.emplace_back(state);
    m_workerCv.notify_one();
    return m_tasks.back().promise.get_future();
}

template <std::size_t TSize>
void ThreadPool<TSize>::moveTo(FSM11STD::unique_lock<FSM11STD::mutex>&& lock,
                               ThreadPool* newPool)
{
    for (Handle* iter = m_handles; iter != nullptr; iter = iter->m_next)
        iter->m_pool = newPool;
    m_workerCv.notify_all();
    m_assignmentCv.wait(lock, [this]{ return m_assignedWorkers == 0; });
    m_handles = nullptr;
}

template <std::size_t TSize>
void ThreadPool<TSize>::work(ThreadPool* pool, int id)
{
    using namespace FSM11STD;

    Handle handle(pool, id);
    while (pool)
    {
        unique_lock<mutex> lock(pool->m_workerMutex);
        pool->m_workerCv.wait(
                    lock,
                    [&](){ return handle.hasChanged(pool)
                                  || !pool->m_tasks.empty(); });
        if (!pool->m_tasks.empty())
        {
            Task task = move(pool->m_tasks.back());
            pool->m_tasks.pop_back();
            lock.unlock();
            try
            {
                task.state.invoke(task.state.m_exitRequest);
                task.promise.set_value();
            }
            catch (...)
            {
                task.promise.set_exception(current_exception());
            }
            lock.lock();
            ++pool->m_idleWorkers;
        }
        else if (handle.hasChanged(pool))
        {
            pool = handle.change(pool, id);
        }
    }
}

template <std::size_t TSize>
ThreadPool<TSize>::Handle::Handle(ThreadPool* pool, int id)
    : m_pool(pool)
{
    pool->m_workerMutex.lock();
    if (!pool->m_handles)
    {
        pool->m_handles = this;
    }
    else
    {
        Handle* iter = pool->m_handles;
        while (iter->m_next)
            iter = iter->m_next;
        iter->m_next = this;
    }
    pool->m_assignedWorkers |= 1 << id;
    pool->m_workerMutex.unlock();
    pool->m_assignmentCv.notify_one();
}

template <std::size_t TSize>
auto ThreadPool<TSize>::Handle::change(ThreadPool* current, int id)
    -> ThreadPool*
{
    current->m_assignedWorkers &= ~(1 << id);
    current->m_assignmentCv.notify_one();

    if (m_pool)
    {
        m_pool->m_workerMutex.lock();
        m_pool->m_assignedWorkers |= 1 << id;
        m_pool->m_workerMutex.unlock();
        m_pool->m_assignmentCv.notify_one();
    }

    return m_pool;
}

} // namespace fsm11

#endif // FSM11_THREADPOOL_HPP
<commit_msg>promote int to std::size_t for 64 bit platforms compatibility<commit_after>/*******************************************************************************
  fsm11 - A C++11-compliant framework for finite state machines

  Copyright (c) 2015, Manuel Freiberger
  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.

  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 HOLDER 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.
*******************************************************************************/

#ifndef FSM11_THREADPOOL_HPP
#define FSM11_THREADPOOL_HPP

#include "statemachine_fwd.hpp"
#include "error.hpp"
#include "detail/threadedstatebase.hpp"

#ifdef FSM11_USE_WEOS
#include <boost/container/static_vector.hpp>
#include <weos/condition_variable.hpp>
#include <weos/future.hpp>
#include <weos/mutex.hpp>
#include <weos/thread.hpp>
#include <weos/tuple.hpp>
#include <weos/utility.hpp>
#else
#include <condition_variable>
#include <future>
#include <mutex>
#include <thread>
#include <utility>
#include <vector>
#endif // FSM11_USE_WEOS

namespace fsm11
{
namespace fsm11_detail
{

template <bool... TValues>
struct all : FSM11STD::true_type
{
};

template <bool THead, bool... TTail>
struct all<THead, TTail...> : FSM11STD::conditional<THead,
                                                    all<TTail...>,
                                                    FSM11STD::false_type>::type
{
};

} // namespace fsm11_detail

template <std::size_t TSize>
class ThreadPool
{
    static_assert(TSize > 0, "The thread pool must be non-empty.");

    struct Task
    {
        Task(fsm11_detail::ThreadedStateBase& s)
            : state(s)
        {
        }

        Task(Task&& other)
            : promise(FSM11STD::move(other.promise)),
              state(other.state)
        {
        }

        Task(const Task&) = delete;
        Task& operator=(const Task&) = delete;

        FSM11STD::promise<void> promise;
        fsm11_detail::ThreadedStateBase& state;
    };

    struct Handle
    {
        explicit Handle(ThreadPool* pool, std::size_t id);

        Handle(const Handle&) = delete;
        Handle& operator=(const Handle&) = delete;

        bool hasChanged(ThreadPool* current) const
        {
            return m_pool != current;
        }

        ThreadPool* change(ThreadPool* current, std::size_t id);

        ThreadPool* m_pool;
        Handle* m_next{nullptr};
    };

public:
#ifdef FSM11_USE_WEOS
    template <typename... TAttributes>
    explicit ThreadPool(const FSM11STD::thread::attributes& attr,
                        const TAttributes&... attributes);
#else
    //! Constructs a thread pool.
    ThreadPool();
#endif // FSM11_USE_WEOS

    ThreadPool(const ThreadPool&) = delete;

    //! Move-constructs a thread pool from the \p other pool.
    ThreadPool(ThreadPool&& other);

    //! Destroys the thread pool.
    ~ThreadPool();

    ThreadPool& operator=(const ThreadPool&) = delete;

    //! Move-assigns the \p other pool to this one.
    ThreadPool& operator=(ThreadPool&& other);

    FSM11STD::future<void> enqueue(fsm11_detail::ThreadedStateBase& state);

private:
    FSM11STD::mutex m_poolMutex;

    FSM11STD::mutex m_workerMutex; // TODO: rethink the locking policy
    FSM11STD::condition_variable m_workerCv;
    FSM11STD::condition_variable m_assignmentCv;
    unsigned m_assignedWorkers{0};
    std::size_t m_idleWorkers{TSize};
    Handle* m_handles{nullptr};
#ifdef FSM11_USE_WEOS
    boost::container::static_vector<Task, TSize> m_tasks;
#else
    FSM11STD::vector<Task> m_tasks;
#endif

    void moveTo(FSM11STD::unique_lock<FSM11STD::mutex>&& lock,
                ThreadPool* newPool);

    static void work(ThreadPool* pool, std::size_t id);

#ifdef FSM11_USE_WEOS
    template <typename TAttributes, std::size_t... TIndices>
    void construct(TAttributes&& attributes,
                   FSM11STD::integer_sequence<std::size_t, TIndices...>)
    {
        using namespace FSM11STD;

        unsigned workers = 0;
        try
        {
            call(constructOne(get<TIndices>(attributes), TIndices, workers)...);
            unique_lock<mutex> lock(m_workerMutex);
            m_assignmentCv.wait(lock,
                                [&]{ return m_assignedWorkers == workers; });
        }
        catch (...)
        {
            unique_lock<mutex> lock(m_workerMutex);
            m_assignmentCv.wait(lock,
                                [&]{ return m_assignedWorkers == workers; });
            moveTo(move(lock), nullptr);
            throw;
        }
    }

    int constructOne(const FSM11STD::thread::attributes& attr,
                     std::size_t idx, unsigned& workers)
    {
        FSM11STD::thread(attr, &ThreadPool::work, this, idx).detach();
        workers |= 1 << idx;
        return 0;
    }

    template <typename... T>
    void call(T...)
    {
    }
#endif
};

#ifdef FSM11_USE_WEOS
template <std::size_t TSize>
template <typename... TAttributes>
ThreadPool<TSize>::ThreadPool(const FSM11STD::thread::attributes& attr,
                              const TAttributes&... attributes)
{
    using namespace FSM11STD;

    static_assert(fsm11_detail::all<
                      is_same<TAttributes, thread::attributes>::value...
                  >::value,
                  "All arguments have to be thread attributes");
    static_assert(1 + sizeof...(TAttributes) == TSize,
                  "The number of thread attributes must equal the pool size.");

    construct(forward_as_tuple(attr, attributes...),
              make_index_sequence<1 + sizeof...(attributes)>());
}
#else
template <std::size_t TSize>
ThreadPool<TSize>::ThreadPool()
{
    using namespace FSM11STD;

    unsigned workers = 0;
    try
    {
        for (std::size_t idx = 0; idx < TSize; ++idx)
        {
            thread(&ThreadPool::work, this, idx).detach();
            workers |= 1 << idx;
        }

        unique_lock<mutex> lock(m_workerMutex);
        m_assignmentCv.wait(lock, [&]{ return m_assignedWorkers == workers; });
    }
    catch (...)
    {
        unique_lock<mutex> lock(m_workerMutex);
        m_assignmentCv.wait(lock, [&]{ return m_assignedWorkers == workers; });
        moveTo(move(lock), nullptr);
        throw;
    }
}
#endif // FSM11_USE_WEOS

template <std::size_t TSize>
ThreadPool<TSize>::ThreadPool(ThreadPool&& other)
{
    using namespace FSM11STD;

    lock_guard<mutex> otherPoolLock(m_poolMutex);

    unique_lock<mutex> otherWorkerLock(other.m_workerMutex);
    unsigned workers = other.m_assignedWorkers;
    m_handles = other.m_handles;
    other.moveTo(move(otherWorkerLock), this);

    unique_lock<mutex> thisWorkerLock(m_workerMutex);
    m_assignmentCv.wait(thisWorkerLock,
                        [&]{ return m_assignedWorkers == workers; });
}

template <std::size_t TSize>
ThreadPool<TSize>::~ThreadPool()
{
    moveTo(FSM11STD::unique_lock<FSM11STD::mutex>(m_workerMutex), nullptr);
}

template <std::size_t TSize>
auto ThreadPool<TSize>::operator=(ThreadPool&& other) -> ThreadPool&
{
    using namespace FSM11STD;

    if (this == &other)
        return *this;

    // It is important to use a dead-lock avoiding algorithm for the
    // two pool mutexes here or we dead-lock the application.
    lock(m_poolMutex, other.m_poolMutex);
    lock_guard<mutex> thisPoolLock(m_poolMutex, adopt_lock);
    lock_guard<mutex> otherPoolLock(other.m_poolMutex, adopt_lock);

    moveTo(unique_lock<mutex>(m_workerMutex), nullptr);

    unique_lock<mutex> otherWorkerLock(other.m_workerMutex);
    unsigned workers = other.m_assignedWorkers;
    m_handles = other.m_handles;
    other.moveTo(move(otherWorkerLock), this);

    unique_lock<mutex> thisWorkerLock(m_workerMutex);
    m_assignmentCv.wait(thisWorkerLock,
                        [&]{ return m_assignedWorkers == workers; });

    return *this;
}

template <std::size_t TSize>
FSM11STD::future<void>
ThreadPool<TSize>::enqueue(fsm11_detail::ThreadedStateBase& state)
{
    using namespace FSM11STD;

    lock_guard<mutex> lock(m_workerMutex);
    if (m_idleWorkers == 0)
        throw FSM11_EXCEPTION(Error(ErrorCode::ThreadPoolUnderflow));
    --m_idleWorkers;

    m_tasks.emplace_back(state);
    m_workerCv.notify_one();
    return m_tasks.back().promise.get_future();
}

template <std::size_t TSize>
void ThreadPool<TSize>::moveTo(FSM11STD::unique_lock<FSM11STD::mutex>&& lock,
                               ThreadPool* newPool)
{
    for (Handle* iter = m_handles; iter != nullptr; iter = iter->m_next)
        iter->m_pool = newPool;
    m_workerCv.notify_all();
    m_assignmentCv.wait(lock, [this]{ return m_assignedWorkers == 0; });
    m_handles = nullptr;
}

template <std::size_t TSize>
void ThreadPool<TSize>::work(ThreadPool* pool, std::size_t id)
{
    using namespace FSM11STD;

    Handle handle(pool, id);
    while (pool)
    {
        unique_lock<mutex> lock(pool->m_workerMutex);
        pool->m_workerCv.wait(
                    lock,
                    [&](){ return handle.hasChanged(pool)
                                  || !pool->m_tasks.empty(); });
        if (!pool->m_tasks.empty())
        {
            Task task = move(pool->m_tasks.back());
            pool->m_tasks.pop_back();
            lock.unlock();
            try
            {
                task.state.invoke(task.state.m_exitRequest);
                task.promise.set_value();
            }
            catch (...)
            {
                task.promise.set_exception(current_exception());
            }
            lock.lock();
            ++pool->m_idleWorkers;
        }
        else if (handle.hasChanged(pool))
        {
            pool = handle.change(pool, id);
        }
    }
}

template <std::size_t TSize>
ThreadPool<TSize>::Handle::Handle(ThreadPool* pool, std::size_t id)
    : m_pool(pool)
{
    pool->m_workerMutex.lock();
    if (!pool->m_handles)
    {
        pool->m_handles = this;
    }
    else
    {
        Handle* iter = pool->m_handles;
        while (iter->m_next)
            iter = iter->m_next;
        iter->m_next = this;
    }
    pool->m_assignedWorkers |= 1 << id;
    pool->m_workerMutex.unlock();
    pool->m_assignmentCv.notify_one();
}

template <std::size_t TSize>
auto ThreadPool<TSize>::Handle::change(ThreadPool* current, std::size_t id)
    -> ThreadPool*
{
    current->m_assignedWorkers &= ~(1 << id);
    current->m_assignmentCv.notify_one();

    if (m_pool)
    {
        m_pool->m_workerMutex.lock();
        m_pool->m_assignedWorkers |= 1 << id;
        m_pool->m_workerMutex.unlock();
        m_pool->m_assignmentCv.notify_one();
    }

    return m_pool;
}

} // namespace fsm11

#endif // FSM11_THREADPOOL_HPP
<|endoftext|>