<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: initUNO.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 07:51:22 $
 *
 *  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
 *
 ************************************************************************/

#include "rtl/bootstrap.hxx"
#include "cppuhelper/bootstrap.hxx"
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

using namespace cppu;
using namespace com::sun::star::lang;
using namespace com::sun::star;
using namespace com::sun::star::uno;

Reference< XMultiServiceFactory > InitializeFac( void )
{
        Reference<XComponentContext> xComponentContext = ::cppu::defaultBootstrap_InitialComponentContext();
    Reference<XMultiServiceFactory> xMS(xComponentContext->getServiceManager(), UNO_QUERY);
    return xMS;
}
<commit_msg>INTEGRATION: CWS pchfix02 (1.3.166); FILE MERGED 2006/09/01 17:22:39 kaib 1.3.166.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: initUNO.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 03:15:23 $
 *
 *  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
 *
 ************************************************************************/

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

#include "rtl/bootstrap.hxx"
#include "cppuhelper/bootstrap.hxx"
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

using namespace cppu;
using namespace com::sun::star::lang;
using namespace com::sun::star;
using namespace com::sun::star::uno;

Reference< XMultiServiceFactory > InitializeFac( void )
{
        Reference<XComponentContext> xComponentContext = ::cppu::defaultBootstrap_InitialComponentContext();
    Reference<XMultiServiceFactory> xMS(xComponentContext->getServiceManager(), UNO_QUERY);
    return xMS;
}
<|endoftext|>


<commit_before><commit_msg>fix int wraparound + crash on export of fdo74018-2.docx to doc<commit_after><|endoftext|>


<commit_before>// CStringDemo.cpp : Demonstrates how to compute length of a c-string
//

#include "stdafx.h"
#include <iostream>
#include <cstring>

using namespace std;

int length(char *str) {
	char *ch = str;
	int len = 0;
	while (*ch != '\0') {
		len++;
		ch++;
		//cout << len << endl;

	}
	return len;
}

int _tmain(int argc, _TCHAR* argv[])
{
	char *myStr = "Bob";
	cout << length(myStr) << endl;
	cout << strlen(myStr) << endl;
	cin.ignore();
	return 0;
}

<commit_msg>added date<commit_after>// CStringDemo.cpp : Demonstrates how to compute length of a c-string
// 2/12/16

#include "stdafx.h"
#include <iostream>
#include <cstring>

using namespace std;

int length(char *str) {
	char *ch = str;
	int len = 0;
	while (*ch != '\0') {
		len++;
		ch++;
		//cout << len << endl;

	}
	return len;
}

int _tmain(int argc, _TCHAR* argv[])
{
	char *myStr = "Bob";
	cout << length(myStr) << endl;
	cout << strlen(myStr) << endl;
	cin.ignore();
	return 0;
}

<|endoftext|>


<commit_before>/*
 * Copyright 2015-present Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <folly/detail/ThreadLocalDetail.h>

#include <list>
#include <mutex>

namespace folly { namespace threadlocal_detail {

StaticMetaBase::StaticMetaBase(ThreadEntry* (*threadEntry)(), bool strict)
    : nextId_(1), threadEntry_(threadEntry), strict_(strict) {
  head_.next = head_.prev = &head_;
  int ret = pthread_key_create(&pthreadKey_, &onThreadExit);
  checkPosixError(ret, "pthread_key_create failed");
  PthreadKeyUnregister::registerKey(pthreadKey_);
}

ThreadEntryList* StaticMetaBase::getThreadEntryList() {
#ifdef FOLLY_TLD_USE_FOLLY_TLS
  static FOLLY_TLS ThreadEntryList threadEntryListSingleton;
  return &threadEntryListSingleton;
#else
  static bool init = false;
  static std::mutex lock;
  static pthread_key_t pthreadKey;

  {
    std::lock_guard<std::mutex> guard(lock);
    if (!init) {
      int ret = pthread_key_create(&pthreadKey, nullptr);
      checkPosixError(ret, "pthread_key_create failed");
      PthreadKeyUnregister::registerKey(pthreadKey);
    }
  }

  ThreadEntryList* threadEntryList =
      static_cast<ThreadEntryList*>(pthread_getspecific(pthreadKey));

  if (UNLIKELY(!threadEntryList)) {
    threadEntryList = new ThreadEntryList();
    int ret = pthread_setspecific(pthreadKey, threadEntryList);
    checkPosixError(ret, "pthread_setspecific failed");
  }

  return threadEntryList;
#endif
}

void StaticMetaBase::onThreadExit(void* ptr) {
  auto threadEntry = static_cast<ThreadEntry*>(ptr);

  {
    auto& meta = *threadEntry->meta;

    // Make sure this ThreadEntry is available if ThreadLocal A is accessed in
    // ThreadLocal B destructor.
    pthread_setspecific(meta.pthreadKey_, threadEntry);
    SharedMutex::ReadHolder rlock(nullptr);
    if (meta.strict_) {
      rlock = SharedMutex::ReadHolder(meta.accessAllThreadsLock_);
    }
    {
      std::lock_guard<std::mutex> g(meta.lock_);
      meta.erase(&(*threadEntry));
      // No need to hold the lock any longer; the ThreadEntry is private to this
      // thread now that it's been removed from meta.
    }
    // NOTE: User-provided deleter / object dtor itself may be using ThreadLocal
    // with the same Tag, so dispose() calls below may (re)create some of the
    // elements or even increase elementsCapacity, thus multiple cleanup rounds
    // may be required.
    for (bool shouldRun = true; shouldRun;) {
      shouldRun = false;
      FOR_EACH_RANGE (i, 0, threadEntry->elementsCapacity) {
        if (threadEntry->elements[i].dispose(TLPDestructionMode::THIS_THREAD)) {
          shouldRun = true;
        }
      }
    }
    pthread_setspecific(meta.pthreadKey_, nullptr);
  }

  auto threadEntryList = threadEntry->list;
  DCHECK_GT(threadEntryList->count, 0u);

  --threadEntryList->count;

  if (threadEntryList->count) {
    return;
  }

  // dispose all the elements
  for (bool shouldRunOuter = true; shouldRunOuter;) {
    shouldRunOuter = false;
    auto tmp = threadEntryList->head;
    while (tmp) {
      auto& meta = *tmp->meta;
      pthread_setspecific(meta.pthreadKey_, tmp);
      SharedMutex::ReadHolder rlock(nullptr);
      if (meta.strict_) {
        rlock = SharedMutex::ReadHolder(meta.accessAllThreadsLock_);
      }
      for (bool shouldRunInner = true; shouldRunInner;) {
        shouldRunInner = false;
        FOR_EACH_RANGE (i, 0, tmp->elementsCapacity) {
          if (tmp->elements[i].dispose(TLPDestructionMode::THIS_THREAD)) {
            shouldRunInner = true;
            shouldRunOuter = true;
          }
        }
      }
      pthread_setspecific(meta.pthreadKey_, nullptr);
      tmp = tmp->listNext;
    }
  }

  // free the entry list
  auto head = threadEntryList->head;
  threadEntryList->head = nullptr;
  while (head) {
    auto tmp = head;
    head = head->listNext;
    if (tmp->elements) {
      free(tmp->elements);
      tmp->elements = nullptr;
      tmp->elementsCapacity = 0;
    }

#ifndef FOLLY_TLD_USE_FOLLY_TLS
    delete tmp;
#endif
  }

#ifndef FOLLY_TLD_USE_FOLLY_TLS
  delete threadEntryList;
#endif
}

uint32_t StaticMetaBase::allocate(EntryID* ent) {
  uint32_t id;
  auto& meta = *this;
  std::lock_guard<std::mutex> g(meta.lock_);

  id = ent->value.load();
  if (id != kEntryIDInvalid) {
    return id;
  }

  if (!meta.freeIds_.empty()) {
    id = meta.freeIds_.back();
    meta.freeIds_.pop_back();
  } else {
    id = meta.nextId_++;
  }

  uint32_t old_id = ent->value.exchange(id);
  DCHECK_EQ(old_id, kEntryIDInvalid);
  return id;
}

void StaticMetaBase::destroy(EntryID* ent) {
  try {
    auto& meta = *this;

    // Elements in other threads that use this id.
    std::vector<ElementWrapper> elements;

    {
      SharedMutex::WriteHolder wlock(nullptr);
      if (meta.strict_) {
        /*
         * In strict mode, the logic guarantees per-thread instances are
         * destroyed by the moment ThreadLocal<> dtor returns.
         * In order to achieve that, we should wait until concurrent
         * onThreadExit() calls (that might acquire ownership over per-thread
         * instances in order to destroy them) are finished.
         */
        wlock = SharedMutex::WriteHolder(meta.accessAllThreadsLock_);
      }

      {
        std::lock_guard<std::mutex> g(meta.lock_);
        uint32_t id = ent->value.exchange(kEntryIDInvalid);
        if (id == kEntryIDInvalid) {
          return;
        }

        for (ThreadEntry* e = meta.head_.next; e != &meta.head_; e = e->next) {
          if (id < e->elementsCapacity && e->elements[id].ptr) {
            elements.push_back(e->elements[id]);

            /*
             * Writing another thread's ThreadEntry from here is fine;
             * the only other potential reader is the owning thread --
             * from onThreadExit (which grabs the lock, so is properly
             * synchronized with us) or from get(), which also grabs
             * the lock if it needs to resize the elements vector.
             *
             * We can't conflict with reads for a get(id), because
             * it's illegal to call get on a thread local that's
             * destructing.
             */
            e->elements[id].ptr = nullptr;
            e->elements[id].deleter1 = nullptr;
            e->elements[id].ownsDeleter = false;
          }
        }
        meta.freeIds_.push_back(id);
      }
    }
    // Delete elements outside the locks.
    for (ElementWrapper& elem : elements) {
      elem.dispose(TLPDestructionMode::ALL_THREADS);
    }
  } catch (...) { // Just in case we get a lock error or something anyway...
    LOG(WARNING) << "Destructor discarding an exception that was thrown.";
  }
}

/**
 * Reserve enough space in the ThreadEntry::elements for the item
 * @id to fit in.
 */
void StaticMetaBase::reserve(EntryID* id) {
  auto& meta = *this;
  ThreadEntry* threadEntry = (*threadEntry_)();
  size_t prevCapacity = threadEntry->elementsCapacity;

  uint32_t idval = id->getOrAllocate(meta);
  if (prevCapacity > idval) {
    return;
  }
  // Growth factor < 2, see folly/docs/FBVector.md; + 5 to prevent
  // very slow start.
  size_t newCapacity = static_cast<size_t>((idval + 5) * 1.7);
  assert(newCapacity > prevCapacity);
  ElementWrapper* reallocated = nullptr;

  // Need to grow. Note that we can't call realloc, as elements is
  // still linked in meta, so another thread might access invalid memory
  // after realloc succeeds. We'll copy by hand and update our ThreadEntry
  // under the lock.
  if (usingJEMalloc()) {
    bool success = false;
    size_t newByteSize = nallocx(newCapacity * sizeof(ElementWrapper), 0);

    // Try to grow in place.
    //
    // Note that xallocx(MALLOCX_ZERO) will only zero newly allocated memory,
    // even if a previous allocation allocated more than we requested.
    // This is fine; we always use MALLOCX_ZERO with jemalloc and we
    // always expand our allocation to the real size.
    if (prevCapacity * sizeof(ElementWrapper) >= jemallocMinInPlaceExpandable) {
      success =
          (xallocx(threadEntry->elements, newByteSize, 0, MALLOCX_ZERO) ==
           newByteSize);
    }

    // In-place growth failed.
    if (!success) {
      success =
          ((reallocated = static_cast<ElementWrapper*>(
                mallocx(newByteSize, MALLOCX_ZERO))) != nullptr);
    }

    if (success) {
      // Expand to real size
      assert(newByteSize / sizeof(ElementWrapper) >= newCapacity);
      newCapacity = newByteSize / sizeof(ElementWrapper);
    } else {
      throw std::bad_alloc();
    }
  } else { // no jemalloc
    // calloc() is simpler than malloc() followed by memset(), and
    // potentially faster when dealing with a lot of memory, as it can get
    // already-zeroed pages from the kernel.
    reallocated = static_cast<ElementWrapper*>(
        calloc(newCapacity, sizeof(ElementWrapper)));
    if (!reallocated) {
      throw std::bad_alloc();
    }
  }

  // Success, update the entry
  {
    std::lock_guard<std::mutex> g(meta.lock_);

    if (prevCapacity == 0) {
      meta.push_back(threadEntry);
    }

    if (reallocated) {
      /*
       * Note: we need to hold the meta lock when copying data out of
       * the old vector, because some other thread might be
       * destructing a ThreadLocal and writing to the elements vector
       * of this thread.
       */
      if (prevCapacity != 0) {
        memcpy(
            reallocated,
            threadEntry->elements,
            sizeof(*reallocated) * prevCapacity);
      }
      std::swap(reallocated, threadEntry->elements);
    }
    threadEntry->elementsCapacity = newCapacity;
  }

  free(reallocated);
}

FOLLY_STATIC_CTOR_PRIORITY_MAX
PthreadKeyUnregister PthreadKeyUnregister::instance_;
} // namespace threadlocal_detail
} // namespace folly
<commit_msg>Fix broken Android build<commit_after>/*
 * Copyright 2015-present Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <folly/detail/ThreadLocalDetail.h>
#include <folly/synchronization/CallOnce.h>

#include <list>
#include <mutex>

namespace folly { namespace threadlocal_detail {

StaticMetaBase::StaticMetaBase(ThreadEntry* (*threadEntry)(), bool strict)
    : nextId_(1), threadEntry_(threadEntry), strict_(strict) {
  head_.next = head_.prev = &head_;
  int ret = pthread_key_create(&pthreadKey_, &onThreadExit);
  checkPosixError(ret, "pthread_key_create failed");
  PthreadKeyUnregister::registerKey(pthreadKey_);
}

ThreadEntryList* StaticMetaBase::getThreadEntryList() {
#ifdef FOLLY_TLD_USE_FOLLY_TLS
  static FOLLY_TLS ThreadEntryList threadEntryListSingleton;
  return &threadEntryListSingleton;
#else
  static pthread_key_t pthreadKey;
  static folly::once_flag onceFlag;
  folly::call_once(onceFlag, [&]() {
    int ret = pthread_key_create(&pthreadKey, nullptr);
    checkPosixError(ret, "pthread_key_create failed");
    PthreadKeyUnregister::registerKey(pthreadKey);
  });

  ThreadEntryList* threadEntryList =
      static_cast<ThreadEntryList*>(pthread_getspecific(pthreadKey));

  if (UNLIKELY(!threadEntryList)) {
    threadEntryList = new ThreadEntryList();
    int ret = pthread_setspecific(pthreadKey, threadEntryList);
    checkPosixError(ret, "pthread_setspecific failed");
  }

  return threadEntryList;
#endif
}

void StaticMetaBase::onThreadExit(void* ptr) {
  auto threadEntry = static_cast<ThreadEntry*>(ptr);

  {
    auto& meta = *threadEntry->meta;

    // Make sure this ThreadEntry is available if ThreadLocal A is accessed in
    // ThreadLocal B destructor.
    pthread_setspecific(meta.pthreadKey_, threadEntry);
    SharedMutex::ReadHolder rlock(nullptr);
    if (meta.strict_) {
      rlock = SharedMutex::ReadHolder(meta.accessAllThreadsLock_);
    }
    {
      std::lock_guard<std::mutex> g(meta.lock_);
      meta.erase(&(*threadEntry));
      // No need to hold the lock any longer; the ThreadEntry is private to this
      // thread now that it's been removed from meta.
    }
    // NOTE: User-provided deleter / object dtor itself may be using ThreadLocal
    // with the same Tag, so dispose() calls below may (re)create some of the
    // elements or even increase elementsCapacity, thus multiple cleanup rounds
    // may be required.
    for (bool shouldRun = true; shouldRun;) {
      shouldRun = false;
      FOR_EACH_RANGE (i, 0, threadEntry->elementsCapacity) {
        if (threadEntry->elements[i].dispose(TLPDestructionMode::THIS_THREAD)) {
          shouldRun = true;
        }
      }
    }
    pthread_setspecific(meta.pthreadKey_, nullptr);
  }

  auto threadEntryList = threadEntry->list;
  DCHECK_GT(threadEntryList->count, 0u);

  --threadEntryList->count;

  if (threadEntryList->count) {
    return;
  }

  // dispose all the elements
  for (bool shouldRunOuter = true; shouldRunOuter;) {
    shouldRunOuter = false;
    auto tmp = threadEntryList->head;
    while (tmp) {
      auto& meta = *tmp->meta;
      pthread_setspecific(meta.pthreadKey_, tmp);
      SharedMutex::ReadHolder rlock(nullptr);
      if (meta.strict_) {
        rlock = SharedMutex::ReadHolder(meta.accessAllThreadsLock_);
      }
      for (bool shouldRunInner = true; shouldRunInner;) {
        shouldRunInner = false;
        FOR_EACH_RANGE (i, 0, tmp->elementsCapacity) {
          if (tmp->elements[i].dispose(TLPDestructionMode::THIS_THREAD)) {
            shouldRunInner = true;
            shouldRunOuter = true;
          }
        }
      }
      pthread_setspecific(meta.pthreadKey_, nullptr);
      tmp = tmp->listNext;
    }
  }

  // free the entry list
  auto head = threadEntryList->head;
  threadEntryList->head = nullptr;
  while (head) {
    auto tmp = head;
    head = head->listNext;
    if (tmp->elements) {
      free(tmp->elements);
      tmp->elements = nullptr;
      tmp->elementsCapacity = 0;
    }

#ifndef FOLLY_TLD_USE_FOLLY_TLS
    delete tmp;
#endif
  }

#ifndef FOLLY_TLD_USE_FOLLY_TLS
  delete threadEntryList;
#endif
}

uint32_t StaticMetaBase::allocate(EntryID* ent) {
  uint32_t id;
  auto& meta = *this;
  std::lock_guard<std::mutex> g(meta.lock_);

  id = ent->value.load();
  if (id != kEntryIDInvalid) {
    return id;
  }

  if (!meta.freeIds_.empty()) {
    id = meta.freeIds_.back();
    meta.freeIds_.pop_back();
  } else {
    id = meta.nextId_++;
  }

  uint32_t old_id = ent->value.exchange(id);
  DCHECK_EQ(old_id, kEntryIDInvalid);
  return id;
}

void StaticMetaBase::destroy(EntryID* ent) {
  try {
    auto& meta = *this;

    // Elements in other threads that use this id.
    std::vector<ElementWrapper> elements;

    {
      SharedMutex::WriteHolder wlock(nullptr);
      if (meta.strict_) {
        /*
         * In strict mode, the logic guarantees per-thread instances are
         * destroyed by the moment ThreadLocal<> dtor returns.
         * In order to achieve that, we should wait until concurrent
         * onThreadExit() calls (that might acquire ownership over per-thread
         * instances in order to destroy them) are finished.
         */
        wlock = SharedMutex::WriteHolder(meta.accessAllThreadsLock_);
      }

      {
        std::lock_guard<std::mutex> g(meta.lock_);
        uint32_t id = ent->value.exchange(kEntryIDInvalid);
        if (id == kEntryIDInvalid) {
          return;
        }

        for (ThreadEntry* e = meta.head_.next; e != &meta.head_; e = e->next) {
          if (id < e->elementsCapacity && e->elements[id].ptr) {
            elements.push_back(e->elements[id]);

            /*
             * Writing another thread's ThreadEntry from here is fine;
             * the only other potential reader is the owning thread --
             * from onThreadExit (which grabs the lock, so is properly
             * synchronized with us) or from get(), which also grabs
             * the lock if it needs to resize the elements vector.
             *
             * We can't conflict with reads for a get(id), because
             * it's illegal to call get on a thread local that's
             * destructing.
             */
            e->elements[id].ptr = nullptr;
            e->elements[id].deleter1 = nullptr;
            e->elements[id].ownsDeleter = false;
          }
        }
        meta.freeIds_.push_back(id);
      }
    }
    // Delete elements outside the locks.
    for (ElementWrapper& elem : elements) {
      elem.dispose(TLPDestructionMode::ALL_THREADS);
    }
  } catch (...) { // Just in case we get a lock error or something anyway...
    LOG(WARNING) << "Destructor discarding an exception that was thrown.";
  }
}

/**
 * Reserve enough space in the ThreadEntry::elements for the item
 * @id to fit in.
 */
void StaticMetaBase::reserve(EntryID* id) {
  auto& meta = *this;
  ThreadEntry* threadEntry = (*threadEntry_)();
  size_t prevCapacity = threadEntry->elementsCapacity;

  uint32_t idval = id->getOrAllocate(meta);
  if (prevCapacity > idval) {
    return;
  }
  // Growth factor < 2, see folly/docs/FBVector.md; + 5 to prevent
  // very slow start.
  size_t newCapacity = static_cast<size_t>((idval + 5) * 1.7);
  assert(newCapacity > prevCapacity);
  ElementWrapper* reallocated = nullptr;

  // Need to grow. Note that we can't call realloc, as elements is
  // still linked in meta, so another thread might access invalid memory
  // after realloc succeeds. We'll copy by hand and update our ThreadEntry
  // under the lock.
  if (usingJEMalloc()) {
    bool success = false;
    size_t newByteSize = nallocx(newCapacity * sizeof(ElementWrapper), 0);

    // Try to grow in place.
    //
    // Note that xallocx(MALLOCX_ZERO) will only zero newly allocated memory,
    // even if a previous allocation allocated more than we requested.
    // This is fine; we always use MALLOCX_ZERO with jemalloc and we
    // always expand our allocation to the real size.
    if (prevCapacity * sizeof(ElementWrapper) >= jemallocMinInPlaceExpandable) {
      success =
          (xallocx(threadEntry->elements, newByteSize, 0, MALLOCX_ZERO) ==
           newByteSize);
    }

    // In-place growth failed.
    if (!success) {
      success =
          ((reallocated = static_cast<ElementWrapper*>(
                mallocx(newByteSize, MALLOCX_ZERO))) != nullptr);
    }

    if (success) {
      // Expand to real size
      assert(newByteSize / sizeof(ElementWrapper) >= newCapacity);
      newCapacity = newByteSize / sizeof(ElementWrapper);
    } else {
      throw std::bad_alloc();
    }
  } else { // no jemalloc
    // calloc() is simpler than malloc() followed by memset(), and
    // potentially faster when dealing with a lot of memory, as it can get
    // already-zeroed pages from the kernel.
    reallocated = static_cast<ElementWrapper*>(
        calloc(newCapacity, sizeof(ElementWrapper)));
    if (!reallocated) {
      throw std::bad_alloc();
    }
  }

  // Success, update the entry
  {
    std::lock_guard<std::mutex> g(meta.lock_);

    if (prevCapacity == 0) {
      meta.push_back(threadEntry);
    }

    if (reallocated) {
      /*
       * Note: we need to hold the meta lock when copying data out of
       * the old vector, because some other thread might be
       * destructing a ThreadLocal and writing to the elements vector
       * of this thread.
       */
      if (prevCapacity != 0) {
        memcpy(
            reallocated,
            threadEntry->elements,
            sizeof(*reallocated) * prevCapacity);
      }
      std::swap(reallocated, threadEntry->elements);
    }
    threadEntry->elementsCapacity = newCapacity;
  }

  free(reallocated);
}

FOLLY_STATIC_CTOR_PRIORITY_MAX
PthreadKeyUnregister PthreadKeyUnregister::instance_;
} // namespace threadlocal_detail
} // namespace folly
<|endoftext|>


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

#include "content/shell/app/shell_main_delegate.h"

#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "cc/base/switches.h"
#include "content/public/browser/browser_main_runner.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/layouttest_support.h"
#include "content/shell/app/shell_breakpad_client.h"
#include "content/shell/app/webkit_test_platform_support.h"
#include "content/shell/browser/shell_browser_main.h"
#include "content/shell/browser/shell_content_browser_client.h"
#include "content/shell/common/shell_switches.h"
#include "content/shell/renderer/shell_content_renderer_client.h"
#include "net/cookies/cookie_monster.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h"
#include "ui/base/ui_base_switches.h"
#include "ui/events/event_switches.h"
#include "ui/gfx/switches.h"
#include "ui/gl/gl_switches.h"

#include "ipc/ipc_message.h"  // For IPC_MESSAGE_LOG_ENABLED.

#if defined(IPC_MESSAGE_LOG_ENABLED)
#define IPC_MESSAGE_MACROS_LOG_ENABLED
#include "content/public/common/content_ipc_logging.h"
#define IPC_LOG_TABLE_ADD_ENTRY(msg_id, logger) \
    content::RegisterIPCLogger(msg_id, logger)
#include "content/shell/common/shell_messages.h"
#endif

#if defined(OS_ANDROID)
#include "base/posix/global_descriptors.h"
#include "content/shell/android/shell_descriptors.h"
#endif

#if defined(OS_MACOSX)
#include "base/mac/os_crash_dumps.h"
#include "components/breakpad/app/breakpad_mac.h"
#include "content/shell/app/paths_mac.h"
#include "content/shell/app/shell_main_delegate_mac.h"
#endif  // OS_MACOSX

#if defined(OS_WIN)
#include <initguid.h>
#include <windows.h>
#include "base/logging_win.h"
#include "components/breakpad/app/breakpad_win.h"
#endif

#if defined(OS_POSIX) && !defined(OS_MACOSX)
#include "components/breakpad/app/breakpad_linux.h"
#endif

namespace {

base::LazyInstance<content::ShellBreakpadClient>::Leaky
    g_shell_breakpad_client = LAZY_INSTANCE_INITIALIZER;

#if defined(OS_WIN)
// If "Content Shell" doesn't show up in your list of trace providers in
// Sawbuck, add these registry entries to your machine (NOTE the optional
// Wow6432Node key for x64 machines):
// 1. Find:  HKLM\SOFTWARE\[Wow6432Node\]Google\Sawbuck\Providers
// 2. Add a subkey with the name "{6A3E50A4-7E15-4099-8413-EC94D8C2A4B6}"
// 3. Add these values:
//    "default_flags"=dword:00000001
//    "default_level"=dword:00000004
//    @="Content Shell"

// {6A3E50A4-7E15-4099-8413-EC94D8C2A4B6}
const GUID kContentShellProviderName = {
    0x6a3e50a4, 0x7e15, 0x4099,
        { 0x84, 0x13, 0xec, 0x94, 0xd8, 0xc2, 0xa4, 0xb6 } };
#endif

void InitLogging() {
  base::FilePath log_filename;
  PathService::Get(base::DIR_EXE, &log_filename);
  log_filename = log_filename.AppendASCII("content_shell.log");
  logging::LoggingSettings settings;
  settings.logging_dest = logging::LOG_TO_ALL;
  settings.log_file = log_filename.value().c_str();
  settings.delete_old = logging::DELETE_OLD_LOG_FILE;
  logging::InitLogging(settings);
  logging::SetLogItems(true, true, true, true);
}

}  // namespace

namespace content {

ShellMainDelegate::ShellMainDelegate() {
}

ShellMainDelegate::~ShellMainDelegate() {
}

bool ShellMainDelegate::BasicStartupComplete(int* exit_code) {
#if defined(OS_WIN)
  // Enable trace control and transport through event tracing for Windows.
  logging::LogEventProvider::Initialize(kContentShellProviderName);
#endif
#if defined(OS_MACOSX)
  // Needs to happen before InitializeResourceBundle() and before
  // WebKitTestPlatformInitialize() are called.
  OverrideFrameworkBundlePath();
  OverrideChildProcessPath();
  EnsureCorrectResolutionSettings();
#endif  // OS_MACOSX

  InitLogging();
  CommandLine& command_line = *CommandLine::ForCurrentProcess();
  if (command_line.HasSwitch(switches::kCheckLayoutTestSysDeps)) {
    if (!CheckLayoutSystemDeps()) {
      if (exit_code)
        *exit_code = 1;
      return true;
    }
  }

  if (command_line.HasSwitch(switches::kDumpRenderTree)) {
    EnableBrowserLayoutTestMode();

    command_line.AppendSwitch(switches::kProcessPerTab);
    command_line.AppendSwitch(switches::kEnableLogging);
    command_line.AppendSwitch(switches::kAllowFileAccessFromFiles);
#if !defined(OS_ANDROID)
    // OSMesa is not yet available for Android. http://crbug.com/248925
    command_line.AppendSwitchASCII(
        switches::kUseGL, gfx::kGLImplementationOSMesaName);
#endif
    command_line.AppendSwitch(switches::kSkipGpuDataLoading);
    command_line.AppendSwitchASCII(switches::kTouchEvents,
                                   switches::kTouchEventsEnabled);
    command_line.AppendSwitch(switches::kEnableGestureTapHighlight);
    command_line.AppendSwitchASCII(switches::kForceDeviceScaleFactor, "1.0");
#if defined(OS_ANDROID)
    command_line.AppendSwitch(
        switches::kDisableGestureRequirementForMediaPlayback);
    // Capturing pixel results does not yet work when implementation-side
    // painting is enabled. See http://crbug.com/250777
    command_line.AppendSwitch(cc::switches::kDisableImplSidePainting);
#endif

    if (!command_line.HasSwitch(switches::kStableReleaseMode)) {
      command_line.AppendSwitch(
        switches::kEnableExperimentalWebPlatformFeatures);
    }

    if (!command_line.HasSwitch(switches::kEnableThreadedCompositing)) {
      command_line.AppendSwitch(switches::kDisableThreadedCompositing);
      command_line.AppendSwitch(cc::switches::kDisableThreadedAnimation);
    }

    command_line.AppendSwitch(switches::kEnableInbandTextTracks);
    command_line.AppendSwitch(switches::kMuteAudio);

#if defined(USE_AURA)
    // TODO: crbug.com/311404 Make layout tests work w/ delegated renderer.
    command_line.AppendSwitch(switches::kDisableDelegatedRenderer);
#endif

    command_line.AppendSwitch(switches::kEnableFileCookies);

    // Unless/until WebM files are added to the media layout tests, we need to
    // avoid removing MP4/H264/AAC so that layout tests can run on Android.
#if !defined(OS_ANDROID)
    net::RemoveProprietaryMediaTypesAndCodecsForTests();
#endif

    if (!WebKitTestPlatformInitialize()) {
      if (exit_code)
        *exit_code = 1;
      return true;
    }
  }
  SetContentClient(&content_client_);
  return false;
}

void ShellMainDelegate::PreSandboxStartup() {
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableCrashReporter)) {
    std::string process_type =
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            switches::kProcessType);
    breakpad::SetBreakpadClient(g_shell_breakpad_client.Pointer());
#if defined(OS_MACOSX)
    base::mac::DisableOSCrashDumps();
    breakpad::InitCrashReporter(process_type);
    breakpad::InitCrashProcessInfo(process_type);
#elif defined(OS_POSIX) && !defined(OS_MACOSX)
    if (process_type != switches::kZygoteProcess) {
#if defined(OS_ANDROID)
      if (process_type.empty())
        breakpad::InitCrashReporter(process_type);
      else
        breakpad::InitNonBrowserCrashReporterForAndroid(process_type);
#else
      breakpad::InitCrashReporter(process_type);
#endif
    }
#elif defined(OS_WIN)
    UINT new_flags =
        SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX;
    UINT existing_flags = SetErrorMode(new_flags);
    SetErrorMode(existing_flags | new_flags);
    breakpad::InitCrashReporter(process_type);
#endif
  }

  InitializeResourceBundle();
}

int ShellMainDelegate::RunProcess(
    const std::string& process_type,
    const MainFunctionParams& main_function_params) {
  if (!process_type.empty())
    return -1;

#if !defined(OS_ANDROID)
  // Android stores the BrowserMainRunner instance as a scoped member pointer
  // on the ShellMainDelegate class because of different object lifetime.
  scoped_ptr<BrowserMainRunner> browser_runner_;
#endif

  browser_runner_.reset(BrowserMainRunner::Create());
  return ShellBrowserMain(main_function_params, browser_runner_);
}

#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
void ShellMainDelegate::ZygoteForked() {
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableCrashReporter)) {
    std::string process_type =
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            switches::kProcessType);
    breakpad::InitCrashReporter(process_type);
  }
}
#endif

void ShellMainDelegate::InitializeResourceBundle() {
#if defined(OS_ANDROID)
  // In the Android case, the renderer runs with a different UID and can never
  // access the file system.  So we are passed a file descriptor to the
  // ResourceBundle pak at launch time.
  int pak_fd =
      base::GlobalDescriptors::GetInstance()->MaybeGet(kShellPakDescriptor);
  if (pak_fd != base::kInvalidPlatformFileValue) {
    ui::ResourceBundle::InitSharedInstanceWithPakFile(base::File(pak_fd),
                                                      false);
    ResourceBundle::GetSharedInstance().AddDataPackFromFile(
        base::File(pak_fd), ui::SCALE_FACTOR_100P);
    return;
  }
#endif

  base::FilePath pak_file;
#if defined(OS_MACOSX)
  pak_file = GetResourcesPakFilePath();
#else
  base::FilePath pak_dir;

#if defined(OS_ANDROID)
  bool got_path = PathService::Get(base::DIR_ANDROID_APP_DATA, &pak_dir);
  DCHECK(got_path);
  pak_dir = pak_dir.Append(FILE_PATH_LITERAL("paks"));
#else
  PathService::Get(base::DIR_MODULE, &pak_dir);
#endif

  pak_file = pak_dir.Append(FILE_PATH_LITERAL("content_shell.pak"));
#endif
  ui::ResourceBundle::InitSharedInstanceWithPakPath(pak_file);
}

ContentBrowserClient* ShellMainDelegate::CreateContentBrowserClient() {
  browser_client_.reset(new ShellContentBrowserClient);
  return browser_client_.get();
}

ContentRendererClient* ShellMainDelegate::CreateContentRendererClient() {
  renderer_client_.reset(new ShellContentRendererClient);
  return renderer_client_.get();
}

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

#include "content/shell/app/shell_main_delegate.h"

#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "cc/base/switches.h"
#include "content/public/browser/browser_main_runner.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/layouttest_support.h"
#include "content/shell/app/shell_breakpad_client.h"
#include "content/shell/app/webkit_test_platform_support.h"
#include "content/shell/browser/shell_browser_main.h"
#include "content/shell/browser/shell_content_browser_client.h"
#include "content/shell/common/shell_switches.h"
#include "content/shell/renderer/shell_content_renderer_client.h"
#include "net/cookies/cookie_monster.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h"
#include "ui/base/ui_base_switches.h"
#include "ui/events/event_switches.h"
#include "ui/gfx/switches.h"
#include "ui/gl/gl_switches.h"

#include "ipc/ipc_message.h"  // For IPC_MESSAGE_LOG_ENABLED.

#if defined(IPC_MESSAGE_LOG_ENABLED)
#define IPC_MESSAGE_MACROS_LOG_ENABLED
#include "content/public/common/content_ipc_logging.h"
#define IPC_LOG_TABLE_ADD_ENTRY(msg_id, logger) \
    content::RegisterIPCLogger(msg_id, logger)
#include "content/shell/common/shell_messages.h"
#endif

#if defined(OS_ANDROID)
#include "base/posix/global_descriptors.h"
#include "content/shell/android/shell_descriptors.h"
#endif

#if defined(OS_MACOSX)
#include "base/mac/os_crash_dumps.h"
#include "components/breakpad/app/breakpad_mac.h"
#include "content/shell/app/paths_mac.h"
#include "content/shell/app/shell_main_delegate_mac.h"
#endif  // OS_MACOSX

#if defined(OS_WIN)
#include <initguid.h>
#include <windows.h>
#include "base/logging_win.h"
#include "components/breakpad/app/breakpad_win.h"
#endif

#if defined(OS_POSIX) && !defined(OS_MACOSX)
#include "components/breakpad/app/breakpad_linux.h"
#endif

namespace {

base::LazyInstance<content::ShellBreakpadClient>::Leaky
    g_shell_breakpad_client = LAZY_INSTANCE_INITIALIZER;

#if defined(OS_WIN)
// If "Content Shell" doesn't show up in your list of trace providers in
// Sawbuck, add these registry entries to your machine (NOTE the optional
// Wow6432Node key for x64 machines):
// 1. Find:  HKLM\SOFTWARE\[Wow6432Node\]Google\Sawbuck\Providers
// 2. Add a subkey with the name "{6A3E50A4-7E15-4099-8413-EC94D8C2A4B6}"
// 3. Add these values:
//    "default_flags"=dword:00000001
//    "default_level"=dword:00000004
//    @="Content Shell"

// {6A3E50A4-7E15-4099-8413-EC94D8C2A4B6}
const GUID kContentShellProviderName = {
    0x6a3e50a4, 0x7e15, 0x4099,
        { 0x84, 0x13, 0xec, 0x94, 0xd8, 0xc2, 0xa4, 0xb6 } };
#endif

void InitLogging() {
  base::FilePath log_filename;
  PathService::Get(base::DIR_EXE, &log_filename);
  log_filename = log_filename.AppendASCII("content_shell.log");
  logging::LoggingSettings settings;
  settings.logging_dest = logging::LOG_TO_ALL;
  settings.log_file = log_filename.value().c_str();
  settings.delete_old = logging::DELETE_OLD_LOG_FILE;
  logging::InitLogging(settings);
  logging::SetLogItems(true, true, true, true);
}

}  // namespace

namespace content {

ShellMainDelegate::ShellMainDelegate() {
}

ShellMainDelegate::~ShellMainDelegate() {
}

bool ShellMainDelegate::BasicStartupComplete(int* exit_code) {
#if defined(OS_WIN)
  // Enable trace control and transport through event tracing for Windows.
  logging::LogEventProvider::Initialize(kContentShellProviderName);
#endif
#if defined(OS_MACOSX)
  // Needs to happen before InitializeResourceBundle() and before
  // WebKitTestPlatformInitialize() are called.
  OverrideFrameworkBundlePath();
  OverrideChildProcessPath();
  EnsureCorrectResolutionSettings();
#endif  // OS_MACOSX

  InitLogging();
  CommandLine& command_line = *CommandLine::ForCurrentProcess();
  if (command_line.HasSwitch(switches::kCheckLayoutTestSysDeps)) {
    if (!CheckLayoutSystemDeps()) {
      if (exit_code)
        *exit_code = 1;
      return true;
    }
  }

  if (command_line.HasSwitch(switches::kDumpRenderTree)) {
    EnableBrowserLayoutTestMode();

    command_line.AppendSwitch(switches::kProcessPerTab);
    command_line.AppendSwitch(switches::kEnableLogging);
    command_line.AppendSwitch(switches::kAllowFileAccessFromFiles);
#if !defined(OS_ANDROID)
    // OSMesa is not yet available for Android. http://crbug.com/248925
    command_line.AppendSwitchASCII(
        switches::kUseGL, gfx::kGLImplementationOSMesaName);
#endif
    command_line.AppendSwitch(switches::kSkipGpuDataLoading);
    command_line.AppendSwitchASCII(switches::kTouchEvents,
                                   switches::kTouchEventsEnabled);
    command_line.AppendSwitch(switches::kEnableGestureTapHighlight);
    command_line.AppendSwitchASCII(switches::kForceDeviceScaleFactor, "1.0");
#if defined(OS_ANDROID)
    command_line.AppendSwitch(
        switches::kDisableGestureRequirementForMediaPlayback);
    // Capturing pixel results does not yet work when implementation-side
    // painting is enabled. See http://crbug.com/250777
    command_line.AppendSwitch(cc::switches::kDisableImplSidePainting);
#endif

    if (!command_line.HasSwitch(switches::kStableReleaseMode)) {
      command_line.AppendSwitch(
        switches::kEnableExperimentalWebPlatformFeatures);
    }

    if (!command_line.HasSwitch(switches::kEnableThreadedCompositing)) {
      command_line.AppendSwitch(switches::kDisableThreadedCompositing);
      command_line.AppendSwitch(cc::switches::kDisableThreadedAnimation);
    }

    command_line.AppendSwitch(switches::kEnableInbandTextTracks);
    command_line.AppendSwitch(switches::kMuteAudio);

#if defined(USE_AURA)
    // TODO: crbug.com/311404 Make layout tests work w/ delegated renderer.
    command_line.AppendSwitch(switches::kDisableDelegatedRenderer);
#endif

    command_line.AppendSwitch(switches::kEnableFileCookies);

    // Unless/until WebM files are added to the media layout tests, we need to
    // avoid removing MP4/H264/AAC so that layout tests can run on Android.
#if !defined(OS_ANDROID)
    net::RemoveProprietaryMediaTypesAndCodecsForTests();
#endif

    if (!WebKitTestPlatformInitialize()) {
      if (exit_code)
        *exit_code = 1;
      return true;
    }
  }
  SetContentClient(&content_client_);
  return false;
}

void ShellMainDelegate::PreSandboxStartup() {
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableCrashReporter)) {
    std::string process_type =
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            switches::kProcessType);
    breakpad::SetBreakpadClient(g_shell_breakpad_client.Pointer());
#if defined(OS_MACOSX)
    base::mac::DisableOSCrashDumps();
    breakpad::InitCrashReporter(process_type);
    breakpad::InitCrashProcessInfo(process_type);
#elif defined(OS_POSIX) && !defined(OS_MACOSX)
    if (process_type != switches::kZygoteProcess) {
#if defined(OS_ANDROID)
      if (process_type.empty())
        breakpad::InitCrashReporter(process_type);
      else
        breakpad::InitNonBrowserCrashReporterForAndroid(process_type);
#else
      breakpad::InitCrashReporter(process_type);
#endif
    }
#elif defined(OS_WIN)
    UINT new_flags =
        SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX;
    UINT existing_flags = SetErrorMode(new_flags);
    SetErrorMode(existing_flags | new_flags);
    breakpad::InitCrashReporter(process_type);
#endif
  }

  InitializeResourceBundle();
}

int ShellMainDelegate::RunProcess(
    const std::string& process_type,
    const MainFunctionParams& main_function_params) {
  if (!process_type.empty())
    return -1;

#if !defined(OS_ANDROID)
  // Android stores the BrowserMainRunner instance as a scoped member pointer
  // on the ShellMainDelegate class because of different object lifetime.
  scoped_ptr<BrowserMainRunner> browser_runner_;
#endif

  browser_runner_.reset(BrowserMainRunner::Create());
  return ShellBrowserMain(main_function_params, browser_runner_);
}

#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
void ShellMainDelegate::ZygoteForked() {
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableCrashReporter)) {
    std::string process_type =
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            switches::kProcessType);
    breakpad::InitCrashReporter(process_type);
  }
}
#endif

void ShellMainDelegate::InitializeResourceBundle() {
#if defined(OS_ANDROID)
  // In the Android case, the renderer runs with a different UID and can never
  // access the file system.  So we are passed a file descriptor to the
  // ResourceBundle pak at launch time.
  int pak_fd =
      base::GlobalDescriptors::GetInstance()->MaybeGet(kShellPakDescriptor);
  if (pak_fd != base::kInvalidPlatformFileValue) {
    ui::ResourceBundle::InitSharedInstanceWithPakFile(base::File(pak_fd),
                                                      false);
    ResourceBundle::GetSharedInstance().AddDataPackFromFile(
        base::File(pak_fd), ui::SCALE_FACTOR_100P);
    return;
  }
#endif

  base::FilePath pak_file;
#if defined(OS_MACOSX)
  pak_file = GetResourcesPakFilePath();
#else
  base::FilePath pak_dir;

#if defined(OS_ANDROID)
  bool got_path = PathService::Get(base::DIR_ANDROID_APP_DATA, &pak_dir);
  DCHECK(got_path);
  pak_dir = pak_dir.Append(FILE_PATH_LITERAL("paks"));
#else
  PathService::Get(base::DIR_MODULE, &pak_dir);
#endif

  pak_file = pak_dir.Append(FILE_PATH_LITERAL("content_shell.pak"));
#endif
  ui::ResourceBundle::InitSharedInstanceWithPakPath(pak_file);
}

ContentBrowserClient* ShellMainDelegate::CreateContentBrowserClient() {
  browser_client_.reset(new ShellContentBrowserClient);
  return browser_client_.get();
}

ContentRendererClient* ShellMainDelegate::CreateContentRendererClient() {
  renderer_client_.reset(new ShellContentRendererClient);
  return renderer_client_.get();
}

}  // namespace content
<|endoftext|>


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

#ifndef DUNE_GDT_OPERATORS_OSWALD_HH
#define DUNE_GDT_OPERATORS_OSWALD_HH

#include <vector>
#include <set>
#include <limits>

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

#include <dune/stuff/aliases.hh>
#include <dune/stuff/common/vector.hh>
#include <dune/stuff/common/float_cmp.hh>
#include <dune/stuff/common/print.hh>
#include <dune/stuff/common/ranges.hh>
#include <dune/stuff/grid/walker.hh>

#include <dune/gdt/discretefunction/default.hh>
#include <dune/gdt/playground/spaces/dg/fem.hh>
#include <dune/gdt/playground/spaces/block.hh>

#include "interfaces.hh"

namespace Dune {
namespace GDT {
namespace Operators {

// forward
template <class GridViewImp, class FieldImp = double>
class OswaldInterpolation;

namespace internal {

template <class GridViewImp, class FieldImp>
class OswaldInterpolationTraits
{
public:
  typedef OswaldInterpolation<GridViewImp, FieldImp> derived_type;
  typedef GridViewImp GridViewType;
  typedef FieldImp FieldType;
};

} // namespace internal

template <class GridViewImp, class FieldImp>
class OswaldInterpolation : public OperatorInterface<internal::OswaldInterpolationTraits<GridViewImp, FieldImp>>
{
public:
  typedef internal::OswaldInterpolationTraits<GridViewImp, FieldImp> Traits;
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::FieldType FieldType;
  static const size_t dimDomain = GridViewType::dimension;

  OswaldInterpolation(const GridViewType& grd_vw, const bool zero_boundary = true)
    : grid_view_(grd_vw)
    , zero_boundary_(zero_boundary)
  {
  }

  template <class SGP, class SV, class RGP, class RV>
  void apply(const ConstDiscreteFunction<Spaces::DG::FemBased<SGP, 1, FieldType, 1, 1>, SV>& source,
             DiscreteFunction<Spaces::DG::FemBased<RGP, 1, FieldType, 1, 1>, RV>& range) const
  {
    apply_dg_fem(source, range);
  }

  template <class SGP, class SV, class RGP, class RV>
  void apply(const ConstDiscreteFunction<Spaces::Block<Spaces::DG::FemBased<SGP, 1, FieldType, 1, 1>>, SV>& source,
             DiscreteFunction<Spaces::Block<Spaces::DG::FemBased<RGP, 1, FieldType, 1, 1>>, RV>& range) const
  {
    apply_dg_fem(source, range);
  }

private:
  template <class SourceType, class RangeType>
  void apply_dg_fem(const SourceType& source, RangeType& range) const
  {
    // data structures we need
    // * a map from a global vertex index to global DoF indices
    //   given a vertex, one obtains a set of all global DoF ids, which are associated with this vertex
    std::map<size_t, std::set<size_t>> global_vertex_id_to_global_DoF_id_map;
    // * a map from a global DoF index to the global index of its associated vertex
    std::vector<size_t> global_DoF_id_to_global_vertex_id_map(source.space().mapper().size());
    // * a set to hold the global id of all boundary vertices
    std::set<size_t> boundary_vertices;

    const auto entity_it_end = grid_view_.template end<0>();
    // walk the grid to create the maps explained above and to find the boundary vertices
    for (auto entity_it = grid_view_.template begin<0>(); entity_it != entity_it_end; ++entity_it) {
      const auto& entity        = *entity_it;
      const size_t num_vertices = boost::numeric_cast<size_t>(entity.template count<dimDomain>());
      const auto basis = source.space().base_function_set(entity);
      if (basis.size() != num_vertices)
        DUNE_THROW(Dune::Stuff::Exceptions::internal_error, "basis.size() = " << basis.size());

      // loop over all vertices of the entitity, to find their associated global DoF indices
      for (size_t local_vertex_id = 0; local_vertex_id < num_vertices; ++local_vertex_id) {
        const auto vertex_ptr       = entity.template subEntity<dimDomain>(boost::numeric_cast<int>(local_vertex_id));
        const auto global_vertex_id = grid_view_.indexSet().index(*vertex_ptr);
        const auto vertex           = vertex_ptr->geometry().center();
        // find the local basis function which corresponds to this vertex
        const auto basis_values = basis.evaluate(entity.geometry().local(vertex));
        if (basis_values.size() != num_vertices)
          DUNE_THROW(Dune::Stuff::Exceptions::internal_error, "basis_values.size() = " << basis_values.size());
        size_t ones            = 0;
        size_t zeros           = 0;
        size_t failures        = 0;
        size_t local_DoF_index = 0;
        for (size_t ii = 0; ii < basis.size(); ++ii) {
          if (std::abs(basis_values[ii][0] - 1.0) < 1e-14) {
            local_DoF_index = ii;
            ++ones;
          } else if (std::abs(basis_values[ii][0] - 0.0) < 1e-14)
            ++zeros;
          else
            ++failures;
        }
        if (ones != 1 || zeros != (basis.size() - 1) || failures > 0) {
          std::stringstream ss;
          ss << "ones = " << ones << ", zeros = " << zeros << ", failures = " << failures
             << ", num_vertices = " << num_vertices << ", entity " << grid_view_.indexSet().index(entity) << ", vertex "
             << local_vertex_id << ": [ " << vertex << "], ";
          Stuff::Common::print(basis_values, "basis_values", ss);
          DUNE_THROW(Dune::Stuff::Exceptions::internal_error, ss.str());
        }
        // now we know that the local DoF index of this vertex is ii
        const size_t global_DoF_index                           = source.space().mapper().mapToGlobal(entity, local_DoF_index);
        global_DoF_id_to_global_vertex_id_map[global_DoF_index] = global_vertex_id;
        global_vertex_id_to_global_DoF_id_map[global_vertex_id].insert(global_DoF_index);
      } // loop over all vertices

      if (zero_boundary_) {
        // in order to determine the boundary vertices, we need to
        // loop over all intersections
        const auto intersectionEndIt = grid_view_.iend(entity);
        for (auto intersectionIt = grid_view_.ibegin(entity); intersectionIt != intersectionEndIt; ++intersectionIt) {
          const auto& intersection = *intersectionIt;
          if (intersection.boundary() && !intersection.neighbor()) {
            const auto& intersection_geometry = intersection.geometry();
            for (auto local_intersection_corner_id : DSC::valueRange(intersection_geometry.corners())) {
              const auto global_intersection_corner = intersection_geometry.corner(local_intersection_corner_id);
              // now, we need to find the entity's vertex this intersection's corner point equals to, so we
              // loop over all vertices of the entity
              for (size_t local_vertex_id = 0; local_vertex_id < num_vertices; ++local_vertex_id) {
                const auto vertex_ptr       = entity.template subEntity<dimDomain>(boost::numeric_cast<int>(local_vertex_id));
                const auto global_vertex_id = grid_view_.indexSet().index(*vertex_ptr);
                const auto vertex = vertex_ptr->geometry().center();
                if (Stuff::Common::FloatCmp::eq(global_intersection_corner, vertex))
                  boundary_vertices.insert(global_vertex_id);
              } // loop over all vertices of the entity
            } // loop over all intersection corners
          } // if (intersection.boundary() && !intersection.neighbor())
        } // loop over all intersections
      } // if(zero_boundary)
    } // walk the grid for the first time

    // walk the grid for the second time
    for (auto entity_it = grid_view_.template begin<0>(); entity_it != entity_it_end; ++entity_it) {
      const auto& entity      = *entity_it;
      const auto num_vertices = boost::numeric_cast<size_t>(entity.template count<dimDomain>());
      // get the local functions
      const auto local_source             = source.local_discrete_function(entity);
      const auto& local_source_DoF_vector = local_source->vector();

      // * loop over all local DoFs
      for (size_t local_DoF_id = 0; local_DoF_id < num_vertices; ++local_DoF_id) {
        const size_t global_DoF_index = source.space().mapper().mapToGlobal(entity, local_DoF_id);
        const size_t global_vertex_id = global_DoF_id_to_global_vertex_id_map[global_DoF_index];
        // if we are on the domain boundary
        if (zero_boundary_ && boundary_vertices.count(global_vertex_id)) {
          // set the dof to zero (we have dirichlet zero)
          range.vector().set_entry(global_DoF_index, FieldType(0));
        } else {
          // do the oswald projection
          const size_t num_DoFS_per_vertex = global_vertex_id_to_global_DoF_id_map[global_vertex_id].size();
          // * get the source DoF
          const FieldType source_DoF_value = local_source_DoF_vector.get(local_DoF_id);
          // * and add it to all target DoFs
          for (size_t target_global_DoF_id : global_vertex_id_to_global_DoF_id_map[global_vertex_id])
            range.vector().add_to_entry(target_global_DoF_id, source_DoF_value / num_DoFS_per_vertex);
        } // if (boundary_vertices.find(global_vertex_id))
      } // loop over all local DoFs
    } // walk the grid for the second time
  } // ... apply(...)

  const GridViewType& grid_view_;
  const bool zero_boundary_;
}; // class OswaldInterpolation

} // namespace Operators
} // namespace GDT
} // namespace Dune

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

#ifndef DUNE_GDT_OPERATORS_OSWALD_HH
#define DUNE_GDT_OPERATORS_OSWALD_HH

#include <vector>
#include <set>
#include <limits>

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

#include <dune/stuff/aliases.hh>
#include <dune/stuff/common/vector.hh>
#include <dune/stuff/common/float_cmp.hh>
#include <dune/stuff/common/print.hh>
#include <dune/stuff/common/ranges.hh>
#include <dune/stuff/grid/walker.hh>

#include <dune/gdt/discretefunction/default.hh>
#include <dune/gdt/playground/spaces/dg/fem.hh>
#include <dune/gdt/playground/spaces/block.hh>

#include "interfaces.hh"

namespace Dune {
namespace GDT {
namespace Operators {

// forward
template <class GridViewImp, class FieldImp = double>
class OswaldInterpolation;

namespace internal {

template <class GridViewImp, class FieldImp>
class OswaldInterpolationTraits
{
public:
  typedef OswaldInterpolation<GridViewImp, FieldImp> derived_type;
  typedef GridViewImp GridViewType;
  typedef FieldImp FieldType;
};

} // namespace internal

template <class GridViewImp, class FieldImp>
class OswaldInterpolation : public OperatorInterface<internal::OswaldInterpolationTraits<GridViewImp, FieldImp>>
{
public:
  typedef internal::OswaldInterpolationTraits<GridViewImp, FieldImp> Traits;
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::FieldType FieldType;
  static const size_t dimDomain = GridViewType::dimension;

  OswaldInterpolation(const GridViewType& grd_vw, const bool zero_boundary = true)
    : grid_view_(grd_vw)
    , zero_boundary_(zero_boundary)
  {
  }

  template <class SGP, class SV, class RGP, class RV>
  void apply(const ConstDiscreteFunction<Spaces::DG::FemBased<SGP, 1, FieldType, 1, 1>, SV>& source,
             DiscreteFunction<Spaces::DG::FemBased<RGP, 1, FieldType, 1, 1>, RV>& range) const
  {
    apply_dg_fem(source, range);
  }

  template <class SGP, class SV, class RGP, class RV>
  void apply(const ConstDiscreteFunction<Spaces::Block<Spaces::DG::FemBased<SGP, 1, FieldType, 1, 1>>, SV>& source,
             DiscreteFunction<Spaces::Block<Spaces::DG::FemBased<RGP, 1, FieldType, 1, 1>>, RV>& range) const
  {
    apply_dg_fem(source, range);
  }

private:
  template <class SourceType, class RangeType>
  void apply_dg_fem(const SourceType& source, RangeType& range) const
  {
    // data structures we need
    // * a map from a global vertex index to global DoF indices
    //   given a vertex, one obtains a set of all global DoF ids, which are associated with this vertex
    std::map<size_t, std::set<size_t>> global_vertex_id_to_global_DoF_id_map;
    // * a map from a global DoF index to the global index of its associated vertex
    std::vector<size_t> global_DoF_id_to_global_vertex_id_map(source.space().mapper().size());
    // * a set to hold the global id of all boundary vertices
    std::set<size_t> boundary_vertices;

    const auto entity_it_end = grid_view_.template end<0>();
    // walk the grid to create the maps explained above and to find the boundary vertices
    for (auto entity_it = grid_view_.template begin<0>(); entity_it != entity_it_end; ++entity_it) {
      const auto& entity        = *entity_it;
      const size_t num_vertices = boost::numeric_cast<size_t>(entity.template count<dimDomain>());
      const auto basis = source.space().base_function_set(entity);
      if (basis.size() != num_vertices)
        DUNE_THROW(Dune::Stuff::Exceptions::internal_error, "basis.size() = " << basis.size());

      // loop over all vertices of the entitity, to find their associated global DoF indices
      for (size_t local_vertex_id = 0; local_vertex_id < num_vertices; ++local_vertex_id) {
        const auto vertex_ptr       = entity.template subEntity<dimDomain>(boost::numeric_cast<int>(local_vertex_id));
        const auto global_vertex_id = grid_view_.indexSet().index(*vertex_ptr);
        const auto vertex           = vertex_ptr->geometry().center();
        // find the local basis function which corresponds to this vertex
        const auto basis_values = basis.evaluate(entity.geometry().local(vertex));
        if (basis_values.size() != num_vertices)
          DUNE_THROW(Dune::Stuff::Exceptions::internal_error, "basis_values.size() = " << basis_values.size());
        size_t ones            = 0;
        size_t zeros           = 0;
        size_t failures        = 0;
        size_t local_DoF_index = 0;
        for (size_t ii = 0; ii < basis.size(); ++ii) {
          if (std::abs(basis_values[ii][0] - 1.0) < 1e-14) {
            local_DoF_index = ii;
            ++ones;
          } else if (std::abs(basis_values[ii][0] - 0.0) < 1e-14)
            ++zeros;
          else
            ++failures;
        }
        if (ones != 1 || zeros != (basis.size() - 1) || failures > 0) {
          std::stringstream ss;
          ss << "ones = " << ones << ", zeros = " << zeros << ", failures = " << failures
             << ", num_vertices = " << num_vertices << ", entity " << grid_view_.indexSet().index(entity) << ", vertex "
             << local_vertex_id << ": [ " << vertex << "], ";
          Stuff::Common::print(basis_values, "basis_values", ss);
          DUNE_THROW(Dune::Stuff::Exceptions::internal_error, ss.str());
        }
        // now we know that the local DoF index of this vertex is ii
        const size_t global_DoF_index                           = source.space().mapper().mapToGlobal(entity, local_DoF_index);
        global_DoF_id_to_global_vertex_id_map[global_DoF_index] = global_vertex_id;
        global_vertex_id_to_global_DoF_id_map[global_vertex_id].insert(global_DoF_index);
      } // loop over all vertices

      if (zero_boundary_) {
        // in order to determine the boundary vertices, we need to
        // loop over all intersections
        const auto intersectionEndIt = grid_view_.iend(entity);
        for (auto intersectionIt = grid_view_.ibegin(entity); intersectionIt != intersectionEndIt; ++intersectionIt) {
          const auto& intersection = *intersectionIt;
          if (intersection.boundary() && !intersection.neighbor()) {
            const auto& intersection_geometry = intersection.geometry();
            for (auto local_intersection_corner_id : DSC::valueRange(intersection_geometry.corners())) {
              const auto global_intersection_corner = intersection_geometry.corner(local_intersection_corner_id);
              // now, we need to find the entity's vertex this intersection's corner point equals to, so we
              // loop over all vertices of the entity
              for (size_t local_vertex_id = 0; local_vertex_id < num_vertices; ++local_vertex_id) {
                const auto vertex_ptr       = entity.template subEntity<dimDomain>(boost::numeric_cast<int>(local_vertex_id));
                const auto global_vertex_id = grid_view_.indexSet().index(*vertex_ptr);
                const auto vertex = vertex_ptr->geometry().center();
                if (Stuff::Common::FloatCmp::eq(global_intersection_corner, vertex))
                  boundary_vertices.insert(global_vertex_id);
              } // loop over all vertices of the entity
            } // loop over all intersection corners
          } // if (intersection.boundary() && !intersection.neighbor())
        } // loop over all intersections
      } // if(zero_boundary)
    } // walk the grid for the first time

    // walk the grid for the second time
    for (auto entity_it = grid_view_.template begin<0>(); entity_it != entity_it_end; ++entity_it) {
      const auto& entity      = *entity_it;
      const auto num_vertices = boost::numeric_cast<size_t>(entity.template count<dimDomain>());
      // get the local functions
      const auto local_source             = source.local_discrete_function(entity);
      const auto& local_source_DoF_vector = local_source->vector();

      // * loop over all local DoFs
      for (size_t local_DoF_id = 0; local_DoF_id < num_vertices; ++local_DoF_id) {
        const size_t global_DoF_index = source.space().mapper().mapToGlobal(entity, local_DoF_id);
        const size_t global_vertex_id = global_DoF_id_to_global_vertex_id_map[global_DoF_index];
        // if we are on the domain boundary
        if (zero_boundary_ && boundary_vertices.count(global_vertex_id)) {
          // set the dof to zero (we have dirichlet zero)
          range.vector().set_entry(global_DoF_index, FieldType(0));
        } else {
          // do the oswald projection
          const size_t num_DoFS_per_vertex = global_vertex_id_to_global_DoF_id_map[global_vertex_id].size();
          // * get the source DoF
          const FieldType source_DoF_value = local_source_DoF_vector.get(local_DoF_id);
          // * and add it to all target DoFs
          for (size_t target_global_DoF_id : global_vertex_id_to_global_DoF_id_map[global_vertex_id])
            range.vector().add_to_entry(target_global_DoF_id, source_DoF_value / num_DoFS_per_vertex);
        } // if (boundary_vertices.find(global_vertex_id))
      } // loop over all local DoFs
    } // walk the grid for the second time
  } // ... apply_dg_fem(...)

  const GridViewType& grid_view_;
  const bool zero_boundary_;
}; // class OswaldInterpolation

} // namespace Operators
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_OPERATORS_OSWALD_HH
<|endoftext|>


<commit_before>#ifndef _CALCULATOR_
#define _CALCULATOR_
#include <iostream>
#include <string>
#include <stack>
using namespace std;

class Calculator {
public:
	Calculator();
	Calculator(const string& expression);
	string infixToPostfix(string &infix);
	string getExpression();
	double postfixCalculate(string &postfix);
	double Calculate(string &infix);
	double getResult();
	bool isBrackMatching(string &expression);
	bool isExistingOtherSymbol(string &expression);
	bool checkExpress(string &expression);
public:
	string expression;
	double result;
};

#endif //_CALCULATOR_<commit_msg>Delete Calculator.hpp<commit_after><|endoftext|>


<commit_before>#pragma once
#ifndef DELEGATE_HPP
# define DELEGATE_HPP

#include <cassert>

#include <cstdlib>

#include <atomic>

#include <memory>

#include <new>

#include <type_traits>

#include <utility>

#include "lightptr.hpp"

namespace
{
  template <typename T, typename A = unsigned>
  struct static_store
  {
    static constexpr auto const max_instances = 8 * sizeof(A);

    using memory_map_type = A;

    static void cleanup() { delete [] store_; }

#ifdef __GNUC__
    template <typename U>
    static int ffz(U const v)
    {
      return __builtin_ctzll(~v);
    }
#elif _MSC_VER && !__INTEL_COMPILER
    template <typename U>
    static int ffz(U const v)
    {
      return 8 * sizeof(v) - __lzcnt64(v & -v);
    }
#elif __INTEL_COMPILER
    template <typename U>
    static int ffz(U const v)
    {
      return _bit_scan_forward(~v);
    }
#else
    template <typename U>
    static int ffz(U v)
    {
      decltype(ffz()) b{};

      for (; (v & 1); ++b)
      {
        v >>= 1;
      }

      return b;
    }
#endif

    static ::std::atomic_flag lock_;

    static A memory_map_;

    static typename ::std::aligned_storage<sizeof(T),
      alignof(T)>::type* store_;
  };

  template <typename T, typename A>
  ::std::atomic_flag static_store<T, A>::lock_;

  template <typename T, typename A>
  A static_store<T, A>::memory_map_;

  template <typename T, typename A>
  typename ::std::aligned_storage<sizeof(T), alignof(T)>::type*
    static_store<T, A>::store_{(::std::atexit(static_store<T>::cleanup),
      new typename ::std::aligned_storage<sizeof(T),
        alignof(T)>::type[static_store<T>::max_instances])};

  template <typename T, typename ...A>
  inline T* static_new(A&& ...args)
  {
    using static_store = static_store<T>;

    while (static_store::lock_.test_and_set(::std::memory_order_acquire));

    auto const i(static_store::ffz(static_store::memory_map_));

    auto p(new (&static_store::store_[i]) T(::std::forward<A>(args)...));

    static_store::memory_map_ |= 1 << i;

    static_store::lock_.clear(::std::memory_order_release);

    return p;
  }

  template <typename T>
  inline void static_delete(T const* const p)
  {
    using static_store = static_store<T>;

    auto const i(p - static_cast<T const*>(static_cast<void const*>(
      static_store::store_)));
    //assert(!as_const(static_store::memory_map_)[i]);

    while (static_store::lock_.test_and_set(::std::memory_order_acquire));

    static_store::memory_map_ &= ~(1 << i);

    static_cast<T const*>(static_cast<void const*>(
      &static_store::store_[i]))->~T();

    static_store::lock_.clear(::std::memory_order_release);
  }
}

template <typename T> class delegate;

template<class R, class ...A>
class delegate<R (A...)>
{
  using stub_ptr_type = R (*)(void*, A&&...);

  delegate(void* const o, stub_ptr_type const m) noexcept
    : object_ptr_(o),
      stub_ptr_(m)
  {
  }

public:
  delegate() = default;

  delegate(delegate const&) = default;

  delegate(delegate&&) = default;

  delegate(::std::nullptr_t const) noexcept : delegate() { }

  template <class C, typename =
    typename ::std::enable_if<::std::is_class<C>{}>::type>
  explicit delegate(C const* const o) noexcept
    : object_ptr_(const_cast<C*>(o))
  {
  }

  template <class C, typename =
    typename ::std::enable_if<::std::is_class<C>{}>::type>
  explicit delegate(C const& o) noexcept
    : object_ptr_(const_cast<C*>(&o))
  {
  }

  template <class C>
  delegate(C* const object_ptr, R (C::* const method_ptr)(A...))
  {
    *this = from(object_ptr, method_ptr);
  }

  template <class C>
  delegate(C* const object_ptr, R (C::* const method_ptr)(A...) const)
  {
    *this = from(object_ptr, method_ptr);
  }

  template <class C>
  delegate(C& object, R (C::* const method_ptr)(A...))
  {
    *this = from(object, method_ptr);
  }

  template <class C>
  delegate(C const& object, R (C::* const method_ptr)(A...) const)
  {
    *this = from(object, method_ptr);
  }

  template <
    typename T,
    typename = typename ::std::enable_if<
      !::std::is_same<delegate, typename ::std::decay<T>::type>{}
    >::type
  >
  delegate(T&& f) :
    store_(static_new<typename ::std::decay<T>::type>(::std::forward<T>(f)),
      functor_deleter<typename ::std::decay<T>::type>)
  {
    using functor_type = typename ::std::decay<T>::type;

    object_ptr_ = store_.get();

    stub_ptr_ = functor_stub<functor_type>;
  }

  delegate& operator=(delegate const&) = default;

  delegate& operator=(delegate&& rhs) = default;

  template <class C>
  delegate& operator=(R (C::* const rhs)(A...))
  {
    return *this = from(static_cast<C*>(object_ptr_), rhs);
  }

  template <class C>
  delegate& operator=(R (C::* const rhs)(A...) const)
  {
    return *this = from(static_cast<C const*>(object_ptr_), rhs);
  }

  template <
    typename T,
    typename = typename ::std::enable_if<
      !::std::is_same<delegate, typename ::std::decay<T>::type>{}
    >::type
  >
  delegate& operator=(T&& f)
  {
    using functor_type = typename ::std::decay<T>::type;

    store_.reset(static_new<functor_type>(::std::forward<T>(f)),
      functor_deleter<functor_type>);

    object_ptr_ = store_.get();

    stub_ptr_ = functor_stub<functor_type>;

    return *this;
  }

  template <R (* const function_ptr)(A...)>
  static delegate from() noexcept
  {
    return { nullptr, function_stub<function_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...)>
  static delegate from(C* const object_ptr) noexcept
  {
    return { object_ptr, method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...) const>
  static delegate from(C const* const object_ptr) noexcept
  {
    return { const_cast<C*>(object_ptr), const_method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...)>
  static delegate from(C& object) noexcept
  {
    return { &object, method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...) const>
  static delegate from(C const& object) noexcept
  {
    return { const_cast<C*>(&object), const_method_stub<C, method_ptr> };
  }

  template <typename T>
  static delegate from(T&& f)
  {
    return ::std::forward<T>(f);
  }

  static delegate from(R (* const function_ptr)(A...))
  {
    return function_ptr;
  }

  template <class C>
  using member_pair =
    ::std::pair<C* const, R (C::* const)(A...)>;

  template <class C>
  using const_member_pair =
    ::std::pair<C const* const, R (C::* const)(A...) const>;

  template <class C>
  static delegate from(C* const object_ptr,
    R (C::* const method_ptr)(A...))
  {
    return member_pair<C>(object_ptr, method_ptr);
  }

  template <class C>
  static delegate from(C const* const object_ptr,
    R (C::* const method_ptr)(A...) const)
  {
    return const_member_pair<C>(object_ptr, method_ptr);
  }

  template <class C>
  static delegate from(C& object, R (C::* const method_ptr)(A...))
  {
    return member_pair<C>(&object, method_ptr);
  }

  template <class C>
  static delegate from(C const& object,
    R (C::* const method_ptr)(A...) const)
  {
    return const_member_pair<C>(&object, method_ptr);
  }

  void reset() { stub_ptr_ = nullptr; store_.reset(); }

  void reset_stub() noexcept { stub_ptr_ = nullptr; }

  void swap(delegate& other) noexcept { ::std::swap(*this, other); }

  bool operator==(delegate const& rhs) const noexcept
  {
    return (object_ptr_ == rhs.object_ptr_) && (stub_ptr_ == rhs.stub_ptr_);
  }

  bool operator!=(delegate const& rhs) const noexcept
  {
    return !operator==(rhs);
  }

  bool operator<(delegate const& rhs) const noexcept
  {
    return (object_ptr_ < rhs.object_ptr_) ||
      ((object_ptr_ == rhs.object_ptr_) && (stub_ptr_ < rhs.stub_ptr_));
  }

  bool operator==(::std::nullptr_t const) const noexcept
  {
    return !stub_ptr_;
  }

  bool operator!=(::std::nullptr_t const) const noexcept
  {
    return stub_ptr_;
  }

  explicit operator bool() const noexcept { return stub_ptr_; }

  R operator()(A... args) const
  {
//  assert(stub_ptr);
    return stub_ptr_(object_ptr_, ::std::forward<A>(args)...);
  }

private:
  friend class ::std::hash<delegate>;

  void* object_ptr_;
  stub_ptr_type stub_ptr_{};

  light_ptr<void> store_;

  template <class T>
  static void functor_deleter(void* const p)
  {
    static_delete(static_cast<T const*>(p));
  }

  template <R (*function_ptr)(A...)>
  static R function_stub(void* const, A&&... args)
  {
    return function_ptr(::std::forward<A>(args)...);
  }

  template <class C, R (C::*method_ptr)(A...)>
  static R method_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<C*>(object_ptr)->*method_ptr)(
      ::std::forward<A>(args)...);
  }

  template <class C, R (C::*method_ptr)(A...) const>
  static R const_method_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<C const*>(object_ptr)->*method_ptr)(
      ::std::forward<A>(args)...);
  }

  template <typename>
  struct is_member_pair : std::false_type { };

  template <class C>
  struct is_member_pair<::std::pair<C* const,
    R (C::* const)(A...)> > : std::true_type
  {
  };

  template <typename>
  struct is_const_member_pair : std::false_type { };

  template <class C>
  struct is_const_member_pair<::std::pair<C const* const,
    R (C::* const)(A...) const> > : std::true_type
  {
  };

  template <typename T>
  static typename ::std::enable_if<
    !(is_member_pair<T>{} ||
    is_const_member_pair<T>{}),
    R
  >::type
  functor_stub(void* const object_ptr, A&&... args)
  {
    return (*static_cast<T*>(object_ptr))(::std::forward<A>(args)...);
  }

  template <typename T>
  static typename ::std::enable_if<
    is_member_pair<T>{} ||
    is_const_member_pair<T>{},
    R
  >::type
  functor_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<T*>(object_ptr)->first->*
      static_cast<T*>(object_ptr)->second)(::std::forward<A>(args)...);
  }
};

namespace std
{
  template <typename R, typename ...A>
  struct hash<delegate<R (A...)> >
  {
    size_t operator()(delegate<R (A...)> const& d) const noexcept
    {
      auto const seed(hash<void*>()(d.object_ptr_));

      return hash<typename delegate<R (A...)>::stub_ptr_type>()(d.stub_ptr_) +
        0x9e3779b9 + (seed << 6) + (seed >> 2);
    }
  };
}

#endif // DELEGATE_HPP
<commit_msg>some fixes<commit_after>#pragma once
#ifndef DELEGATE_HPP
# define DELEGATE_HPP

#include <cassert>

#include <cstdlib>

#include <atomic>

#include <memory>

#include <new>

#include <type_traits>

#include <utility>

#include "lightptr.hpp"

namespace
{
  template <typename T, typename A = unsigned>
  struct static_store
  {
    static constexpr auto const max_instances = 8 * sizeof(A);

    using memory_map_type = A;

    static void cleanup() { delete [] store_; }

#ifdef __GNUC__
    template <typename U>
    static int ffz(U const v)
    {
      return __builtin_ctzll(~v);
    }
#elif _MSC_VER && !__INTEL_COMPILER
    template <typename U>
    static int ffz(U const v)
    {
      return 8 * sizeof(v) - __lzcnt64(v & -v);
    }
#elif __INTEL_COMPILER
    template <typename U>
    static int ffz(U const v)
    {
      return _bit_scan_forward(~v);
    }
#else
    template <typename U>
    static int ffz(U v)
    {
      decltype(ffz()) b{};

      for (; (v & 1); ++b)
      {
        v >>= 1;
      }

      return b;
    }
#endif

    static ::std::atomic_flag lock_;

    static A memory_map_;

    static typename ::std::aligned_storage<sizeof(T),
      alignof(T)>::type* store_;
  };

  template <typename T, typename A>
  ::std::atomic_flag static_store<T, A>::lock_;

  template <typename T, typename A>
  A static_store<T, A>::memory_map_;

  template <typename T, typename A>
  typename ::std::aligned_storage<sizeof(T), alignof(T)>::type*
    static_store<T, A>::store_{(::std::atexit(static_store<T>::cleanup),
      new typename ::std::aligned_storage<sizeof(T),
        alignof(T)>::type[static_store<T>::max_instances])};

  template <typename T, typename ...A>
  inline T* static_new(A&& ...args)
  {
    using static_store = static_store<T>;

    while (static_store::lock_.test_and_set(::std::memory_order_acquire));

    auto const i(static_store::ffz(static_store::memory_map_));

    auto p(new (&static_store::store_[i]) T(::std::forward<A>(args)...));

    static_store::memory_map_ |= 1 << i;

    static_store::lock_.clear(::std::memory_order_release);

    return p;
  }

  template <typename T>
  inline void static_delete(T* const p)
  {
    using static_store = static_store<T>;

    auto const i(p - static_cast<T*>(static_cast<void*>(
      static_store::store_)));
    //assert(!as_const(static_store::memory_map_)[i]);

    while (static_store::lock_.test_and_set(::std::memory_order_acquire));

    static_store::memory_map_ &= ~(1 << i);

    static_cast<T*>(static_cast<void*>(&static_store::store_[i]))->~T();

    static_store::lock_.clear(::std::memory_order_release);
  }
}

template <typename T> class delegate;

template<class R, class ...A>
class delegate<R (A...)>
{
  using stub_ptr_type = R (*)(void*, A&&...);

  delegate(void* const o, stub_ptr_type const m) noexcept
    : object_ptr_(o),
      stub_ptr_(m)
  {
  }

public:
  delegate() = default;

  delegate(delegate const&) = default;

  delegate(delegate&&) = default;

  delegate(::std::nullptr_t const) noexcept : delegate() { }

  template <class C, typename =
    typename ::std::enable_if<::std::is_class<C>{}>::type>
  explicit delegate(C const* const o) noexcept
    : object_ptr_(const_cast<C*>(o))
  {
  }

  template <class C, typename =
    typename ::std::enable_if<::std::is_class<C>{}>::type>
  explicit delegate(C const& o) noexcept
    : object_ptr_(const_cast<C*>(&o))
  {
  }

  template <class C>
  delegate(C* const object_ptr, R (C::* const method_ptr)(A...))
  {
    *this = from(object_ptr, method_ptr);
  }

  template <class C>
  delegate(C* const object_ptr, R (C::* const method_ptr)(A...) const)
  {
    *this = from(object_ptr, method_ptr);
  }

  template <class C>
  delegate(C& object, R (C::* const method_ptr)(A...))
  {
    *this = from(object, method_ptr);
  }

  template <class C>
  delegate(C const& object, R (C::* const method_ptr)(A...) const)
  {
    *this = from(object, method_ptr);
  }

  template <
    typename T,
    typename = typename ::std::enable_if<
      !::std::is_same<delegate, typename ::std::decay<T>::type>{}
    >::type
  >
  delegate(T&& f) :
    store_(static_new<typename ::std::decay<T>::type>(::std::forward<T>(f)),
      functor_deleter<typename ::std::decay<T>::type>)
  {
    using functor_type = typename ::std::decay<T>::type;

    object_ptr_ = store_.get();

    stub_ptr_ = functor_stub<functor_type>;
  }

  delegate& operator=(delegate const&) = default;

  delegate& operator=(delegate&& rhs) = default;

  template <class C>
  delegate& operator=(R (C::* const rhs)(A...))
  {
    return *this = from(static_cast<C*>(object_ptr_), rhs);
  }

  template <class C>
  delegate& operator=(R (C::* const rhs)(A...) const)
  {
    return *this = from(static_cast<C const*>(object_ptr_), rhs);
  }

  template <
    typename T,
    typename = typename ::std::enable_if<
      !::std::is_same<delegate, typename ::std::decay<T>::type>{}
    >::type
  >
  delegate& operator=(T&& f)
  {
    using functor_type = typename ::std::decay<T>::type;

    store_.reset(static_new<functor_type>(::std::forward<T>(f)),
      functor_deleter<functor_type>);

    object_ptr_ = store_.get();

    stub_ptr_ = functor_stub<functor_type>;

    return *this;
  }

  template <R (* const function_ptr)(A...)>
  static delegate from() noexcept
  {
    return { nullptr, function_stub<function_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...)>
  static delegate from(C* const object_ptr) noexcept
  {
    return { object_ptr, method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...) const>
  static delegate from(C const* const object_ptr) noexcept
  {
    return { const_cast<C*>(object_ptr), const_method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...)>
  static delegate from(C& object) noexcept
  {
    return { &object, method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...) const>
  static delegate from(C const& object) noexcept
  {
    return { const_cast<C*>(&object), const_method_stub<C, method_ptr> };
  }

  template <typename T>
  static delegate from(T&& f)
  {
    return ::std::forward<T>(f);
  }

  static delegate from(R (* const function_ptr)(A...))
  {
    return function_ptr;
  }

  template <class C>
  using member_pair =
    ::std::pair<C* const, R (C::* const)(A...)>;

  template <class C>
  using const_member_pair =
    ::std::pair<C const* const, R (C::* const)(A...) const>;

  template <class C>
  static delegate from(C* const object_ptr,
    R (C::* const method_ptr)(A...))
  {
    return member_pair<C>(object_ptr, method_ptr);
  }

  template <class C>
  static delegate from(C const* const object_ptr,
    R (C::* const method_ptr)(A...) const)
  {
    return const_member_pair<C>(object_ptr, method_ptr);
  }

  template <class C>
  static delegate from(C& object, R (C::* const method_ptr)(A...))
  {
    return member_pair<C>(&object, method_ptr);
  }

  template <class C>
  static delegate from(C const& object,
    R (C::* const method_ptr)(A...) const)
  {
    return const_member_pair<C>(&object, method_ptr);
  }

  void reset() { stub_ptr_ = nullptr; store_.reset(); }

  void reset_stub() noexcept { stub_ptr_ = nullptr; }

  void swap(delegate& other) noexcept { ::std::swap(*this, other); }

  bool operator==(delegate const& rhs) const noexcept
  {
    return (object_ptr_ == rhs.object_ptr_) && (stub_ptr_ == rhs.stub_ptr_);
  }

  bool operator!=(delegate const& rhs) const noexcept
  {
    return !operator==(rhs);
  }

  bool operator<(delegate const& rhs) const noexcept
  {
    return (object_ptr_ < rhs.object_ptr_) ||
      ((object_ptr_ == rhs.object_ptr_) && (stub_ptr_ < rhs.stub_ptr_));
  }

  bool operator==(::std::nullptr_t const) const noexcept
  {
    return !stub_ptr_;
  }

  bool operator!=(::std::nullptr_t const) const noexcept
  {
    return stub_ptr_;
  }

  explicit operator bool() const noexcept { return stub_ptr_; }

  R operator()(A... args) const
  {
//  assert(stub_ptr);
    return stub_ptr_(object_ptr_, ::std::forward<A>(args)...);
  }

private:
  friend class ::std::hash<delegate>;

  void* object_ptr_;
  stub_ptr_type stub_ptr_{};

  light_ptr<void> store_;

  template <class T>
  static void functor_deleter(void* const p)
  {
    static_delete(static_cast<T*>(p));
  }

  template <R (*function_ptr)(A...)>
  static R function_stub(void* const, A&&... args)
  {
    return function_ptr(::std::forward<A>(args)...);
  }

  template <class C, R (C::*method_ptr)(A...)>
  static R method_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<C*>(object_ptr)->*method_ptr)(
      ::std::forward<A>(args)...);
  }

  template <class C, R (C::*method_ptr)(A...) const>
  static R const_method_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<C const*>(object_ptr)->*method_ptr)(
      ::std::forward<A>(args)...);
  }

  template <typename>
  struct is_member_pair : std::false_type { };

  template <class C>
  struct is_member_pair<::std::pair<C* const,
    R (C::* const)(A...)> > : std::true_type
  {
  };

  template <typename>
  struct is_const_member_pair : std::false_type { };

  template <class C>
  struct is_const_member_pair<::std::pair<C const* const,
    R (C::* const)(A...) const> > : std::true_type
  {
  };

  template <typename T>
  static typename ::std::enable_if<
    !(is_member_pair<T>{} ||
    is_const_member_pair<T>{}),
    R
  >::type
  functor_stub(void* const object_ptr, A&&... args)
  {
    return (*static_cast<T*>(object_ptr))(::std::forward<A>(args)...);
  }

  template <typename T>
  static typename ::std::enable_if<
    is_member_pair<T>{} ||
    is_const_member_pair<T>{},
    R
  >::type
  functor_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<T*>(object_ptr)->first->*
      static_cast<T*>(object_ptr)->second)(::std::forward<A>(args)...);
  }
};

namespace std
{
  template <typename R, typename ...A>
  struct hash<delegate<R (A...)> >
  {
    size_t operator()(delegate<R (A...)> const& d) const noexcept
    {
      auto const seed(hash<void*>()(d.object_ptr_));

      return hash<typename delegate<R (A...)>::stub_ptr_type>()(d.stub_ptr_) +
        0x9e3779b9 + (seed << 6) + (seed >> 2);
    }
  };
}

#endif // DELEGATE_HPP
<|endoftext|>