text:
/*
 * LikelihoodBasedTopPairReconstruction.cpp
 *
 *  Created on: 25 Aug 2011
 *      Author: kreczko
 */

#include "../../interface/ReconstructionModules/LikelihoodBasedTopPairReconstruction.h"
#include <boost/lexical_cast.hpp>

using namespace std;

namespace BAT {

LikelihoodBasedTopPairReconstruction::LikelihoodBasedTopPairReconstruction(const LeptonPointer lepton, const METPointer met, const JetCollection jets, const JetCollection bjets):
		solutions(),
		alreadyReconstructed(false),
		met(met),
		jets(jets),
		bjets(bjets),
		leptonFromW(lepton) {
}

bool LikelihoodBasedTopPairReconstruction::meetsInitialCriteria() const {
	return met != 0 && leptonFromW != 0 && jets.size() >= 4;
}

std::string LikelihoodBasedTopPairReconstruction::getDetailsOnFailure() const {
	std::string msg = "Initial Criteria not met: \n";
	if (leptonFromW == 0)
		msg += "Electron from W: not filled \n";
	else
		msg += "Electron from W: filled \n";

	if (met == 0)
		msg += "Missing transverse energy: not filled \n";
	else
		msg += "Missing transverse energy: filled \n";
	std::string nJets(boost::lexical_cast<std::string>(jets.size()));
	if (jets.size() < 4)
		msg += "Number of jets is too small:" + nJets + ", should be >= 4 \n";
	else
		msg += "Number of jets is OK:" + nJets + "\n";

	return msg;
}

LikelihoodBasedTopPairReconstruction::~LikelihoodBasedTopPairReconstruction() {
}

TtbarHypothesisCollection LikelihoodBasedTopPairReconstruction::getAllSolutions(){
	if(!alreadyReconstructed)
		reconstruct();

	SmallerDiscriminatorIsBetter solutionComparator = SmallerDiscriminatorIsBetter();
	std::sort(solutions.begin(), solutions.end(), solutionComparator);
	return solutions;
}

const TtbarHypothesisPointer LikelihoodBasedTopPairReconstruction::getBestSolution() {
	const TtbarHypothesisPointer bestSolution = getAllSolutions().front();//sorted by quality, front == best
	return bestSolution;
}

void LikelihoodBasedTopPairReconstruction::reconstruct() {
	typedef unsigned short ushort;

	// Loop b jets to get hadronic b candidate
	for (ushort hadBindex = 0; hadBindex < bjets.size(); ++hadBindex) {
		JetPointer hadBJet = bjets[hadBindex];
		LeptonPointer signallepton = leptonFromW;
		METPointer MET = met;

		if (!meetsHadronicBJetRequirement(hadBJet))
			continue;
		// Loop b jets to get leptonic b candidate
		for (ushort lepBindex = 0; lepBindex < bjets.size(); ++lepBindex) {
			JetPointer lepBJet = bjets[lepBindex];
			if (lepBindex == hadBindex || !meetsLeptonicBJetRequirement(lepBJet))
				continue;

			// Loop light jets to get jets from W

			for ( ushort jet1Index=0; jet1Index < (jets.size()-1); ++jet1Index ) {
				for ( ushort jet2Index=jet1Index+1; jet2Index < jets.size(); ++jet2Index ) {

			// for (ushort jet1Index = 0; jet1Index < jets.size(); ++jet1Index) {
			// 	for (ushort jet2Index = 0; jet2Index < jets.size(); ++jet2Index) {
					JetPointer jet1FromW = jets[jet1Index];
					JetPointer jet2FromW = jets[jet2Index];

					if (jet2Index == jet1Index || !meetsJetFromWRequirement(jet1FromW, jet2FromW))
						continue;

					// Put all particles together
					TtbarHypothesisPointer solution(new TtbarHypothesis());
					//leptons
					solution->leptonFromW = leptonFromW;
					double nuChi2 = -1;
					solution->neutrinoFromW = getNeutrinoSolution( lepBJet, signallepton, MET, nuChi2 );
					solution->neutrinoChi2 = nuChi2;

					//jets
					solution->hadronicBJet = hadBJet;
					solution->leptonicBjet = lepBJet;
					solution->jet1FromW = jet1FromW;
					solution->jet2FromW = jet2FromW;

					//combine reconstructed objects
					solution->combineReconstructedObjects();

					// Get discrimnant for this solution
					solution->discriminator = getDiscriminator(solution);

					// Store if event is physical (checks masses of tops and Ws > 0 )
					if (meetsGlobalRequirement(solution)){
						solutions.push_back(solution);
					}

					else
						continue;
				}
			}
		}
	}
	alreadyReconstructed = true;
}

ParticlePointer LikelihoodBasedTopPairReconstruction::getNeutrinoSolution(JetPointer BJet, LeptonPointer Lepton, METPointer met, double& neutrinoChi2) {
	// Do the neutrino reconstruction
	NeutrinoSolver neutrinoSolver( &(Lepton->getFourVector()), &(BJet->getFourVector()), 80, 173 );
	double test = -1;
	FourVector neutrino = neutrinoSolver.GetBest(met->getFourVector().Px(), met->getFourVector().Py(), 25., 25., 0., test );
	neutrinoChi2 = test;

	return ParticlePointer (new Particle(neutrino.Energy(), neutrino.Px(), neutrino.Py(), neutrino.Pz()));
}

bool LikelihoodBasedTopPairReconstruction::meetsHadronicBJetRequirement(JetPointer hadBJet){
	return true;
}

bool LikelihoodBasedTopPairReconstruction::meetsLeptonicBJetRequirement(JetPointer lepBJet){
	return true;
}

bool LikelihoodBasedTopPairReconstruction::meetsJetFromWRequirement(JetPointer jet1, JetPointer jet2){
	return true;
}

bool LikelihoodBasedTopPairReconstruction::meetsGlobalRequirement(const TtbarHypothesisPointer solution){
	return solution->isPhysical();
}

double LikelihoodBasedTopPairReconstruction::getDiscriminator(const TtbarHypothesisPointer solution) const{
	// Given all the info for this solution/permutation, calculate the discriminant
	// cout << "------------------------------------------------------" << endl;

	// Print csv of hadronic b jet and probablitity from correct b histogram
	JetPointer hadBJet = solution->hadronicBJet;
	JetPointer lepBJet = solution->leptonicBjet;
	ParticlePointer hadTop = solution->hadronicTop;
	ParticlePointer lepTop = solution->leptonicTop;
	ParticlePointer hadW = solution->hadronicW;
	ParticlePointer lepW = solution->leptonicW;

	double NeutrinoChi2 = solution->neutrinoChi2;

	double hadBJetCSV = hadBJet->getBTagDiscriminator(BAT::BtagAlgorithm::value::CombinedSecondaryVertexV2);
	double lepBJetCSV = lepBJet->getBTagDiscriminator(BAT::BtagAlgorithm::value::CombinedSecondaryVertexV2);

	double Wmass = hadW->mass();
	double Topmass = hadTop->mass();

	double probCorrectHadB = Globals::csvCorrectPermHistogram->Interpolate( hadBJetCSV );
	double probIncorrectHadB = Globals::csvIncorrectPermHistogram->Interpolate( hadBJetCSV );

	double probCorrectLepB = Globals::csvCorrectPermHistogram->Interpolate( lepBJetCSV );
	double probIncorrectLepB = Globals::csvIncorrectPermHistogram->Interpolate( lepBJetCSV );

	double probCorrectNuChi2 = Globals::NuChiCorrectPermHistogram->Interpolate( NeutrinoChi2 );
	double probIncorrectNuChi2 = Globals::NuChiIncorrectPermHistogram->Interpolate( NeutrinoChi2 );

	double probCorrectWBMass = Globals::HadronicRecoCorrectPermHistogram->Interpolate( Wmass , Topmass );
	double probIncorrectWBMass = Globals::HadronicRecoIncorrectPermHistogram->Interpolate( Wmass , Topmass );

	if (probCorrectWBMass == 0){
		probCorrectWBMass = 0.000000001;
	}
	if (probIncorrectWBMass == 0){
		probIncorrectWBMass = 0.000000001;
	}

	double NuChi2Disc =  - log(probCorrectNuChi2/probIncorrectNuChi2);
	double CSVDisc = - log((probCorrectHadB/probIncorrectHadB)*(probCorrectLepB/probIncorrectLepB));
	double MassDisc = - log(probCorrectWBMass/probIncorrectWBMass);
	double likelihoodratio = 20;
	// cout << "Mass Hadronic T : " << hadTop->mass() << ", Mass Hadronic W : " << hadW->getFourVector().M() << endl;
	// cout << "Mass Leptonic T : " << lepTop->getFourVector().M() << ", Mass Leptonic W : " << lepW->getFourVector().M() << endl;
	// cout << "Neutrino Chi Sq : " << NeutrinoChi2 << endl;

	if (NeutrinoChi2 >= 0.0 && Wmass <= 490 && Topmass <= 490){

		solution->CSVDiscriminator = CSVDisc;
		solution->MassDiscriminator = MassDisc;
		solution->NuChi2Discriminator = NuChi2Disc;

		likelihoodratio = - log(probCorrectWBMass/probIncorrectWBMass) - log(probCorrectNuChi2/probIncorrectNuChi2) - log((probCorrectHadB/probIncorrectHadB)*(probCorrectLepB/probIncorrectLepB));

		// if (solution->isCorrect()){

		// 	cout << "Mass Hadronic T : " << hadTop->mass() << ", Mass Hadronic W : " << hadW->mass() << endl;
		// 	cout << "Mass Leptonic T : " << lepTop->mass() << ", Mass Leptonic W : " << lepW->mass() << endl;

		// 	cout << "probCorrectHadB : " << hadBJetCSV << " prob : " << probCorrectHadB << endl;
		// 	cout << "probIncorrectHadB : " << hadBJetCSV << " prob : " << probIncorrectHadB << endl;
		// 	// cout << "probCorrectLepB : " << lepBJetCSV << " prob : " << probCorrectLepB << endl;
		// 	// cout << "probIncorrectLepB : " << lepBJetCSV << " prob : " << probIncorrectLepB << endl;

		// 	// cout << "CorrectNu : " << NeutrinoChi2 << " prob : " << probCorrectNuChi2 << endl;
		// 	// cout << "IncorrectNu : " << NeutrinoChi2 << " prob : " << probIncorrectNuChi2 << endl;

		// 	// cout << "CorrectMassReco : " << Wmass << " " << Topmass << " prob : " << probCorrectWBMass << endl;
		// 	// cout << "IncorrectMassReco : " << Wmass << " " << Topmass <<  " prob : " << probIncorrectWBMass << endl;

		// 	cout << "MassDisc : " << MassDisc << endl;
		// 	cout << "CSVDisc : " << CSVDisc << endl;
		// 	cout << "NuChi2Disc : " << NuChi2Disc << endl;

		// 	cout << "Likelihood Test : " << likelihoodratio << endl;
		// 	}
	}

	else{
		solution->CSVDiscriminator = 10;
		solution->MassDiscriminator = 10;
		solution->NuChi2Discriminator = 10;
	}
return likelihoodratio;
}

} /* namespace BAT */

max_stars_repo_name: kreczko/AnalysisSoftware

max_issues_repo_name: kreczko/AnalysisSoftware

max_forks_repo_name: kreczko/AnalysisSoftware


text:
/*=============================================================================
    Copyright (c) 2001-2011 Joel de Guzman

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(FUSION_VALUE_AT_05052005_0229)
#define FUSION_VALUE_AT_05052005_0229

#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/support/category_of.hpp>
#include <boost/fusion/support/config.hpp>
#include <boost/fusion/support/tag_of.hpp>
#include <boost/mpl/empty_base.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/less.hpp>
#include <boost/mpl/or.hpp>

namespace boost {
namespace fusion {
// Special tags:
struct sequence_facade_tag;
struct boost_tuple_tag;  // boost::tuples::tuple tag
struct boost_array_tag;  // boost::array tag
struct mpl_sequence_tag; // mpl sequence tag
struct std_pair_tag;     // std::pair tag

namespace extension {
template <typename Tag> struct value_at_impl {
  template <typename Sequence, typename N> struct apply;
};

template <> struct value_at_impl<sequence_facade_tag> {
  template <typename Sequence, typename N>
  struct apply : Sequence::template value_at<Sequence, N> {};
};

template <> struct value_at_impl<boost_tuple_tag>;

template <> struct value_at_impl<boost_array_tag>;

template <> struct value_at_impl<mpl_sequence_tag>;

template <> struct value_at_impl<std_pair_tag>;
} // namespace extension

namespace detail {
template <typename Sequence, typename N, typename Tag>
struct value_at_impl
    : mpl::if_<
          mpl::or_<mpl::less<N, typename extension::size_impl<
                                    Tag>::template apply<Sequence>::type>,
                   traits::is_unbounded<Sequence>>,
          typename extension::value_at_impl<Tag>::template apply<Sequence, N>,
          mpl::empty_base>::type {};
} // namespace detail

namespace result_of {
template <typename Sequence, typename N>
struct value_at
    : detail::value_at_impl<Sequence, N,
                            typename detail::tag_of<Sequence>::type> {};

template <typename Sequence, int N>
struct value_at_c : fusion::result_of::value_at<Sequence, mpl::int_<N>> {};
} // namespace result_of
} // namespace fusion
} // namespace boost

#endif

ext: hpp

max_stars_repo_name: henrywarhurst/matrix

max_issues_repo_name: henrywarhurst/matrix

max_forks_repo_name: henrywarhurst/matrix


text:
#define BOOST_TEST_MODULE tree_set test
#include <boost/test/unit_test.hpp>

#include <string>
#include <cstring>

#include "tree_set.hpp"

using std::vector;

template<typename T>
void test_adding_into_set(TreeSet<int>& set, vector<T> const & es) {
    size_t n = es.size();

    for (size_t i = 0; i <= n; ++i) {
        for (size_t j = 0; j < i; ++j) {
            BOOST_CHECK_EQUAL(set.contains(es[j]), true);
        }
        for (size_t j = i; j < n; ++j) {
            BOOST_CHECK_EQUAL(set.contains(es[j]), false);
        }

        if (i < n) {
            set.add(es[i]);
        }
    }

    for (size_t i = 0; i <= n; ++i) {
        for (size_t j = 0; j < n; ++j) {
            BOOST_CHECK_EQUAL(set.contains(es[j]), true);
        }

        if (i < n) {
            set.add(es[i]);
        }
    }
}

BOOST_AUTO_TEST_CASE( adding_test ) {
    vector<int> es;
    es.push_back(0);
    es.push_back(4);
    es.push_back(42);
    es.push_back(-1);

    TreeSet<int> set;

    test_adding_into_set(set, es);

    vector<int> es2;
    for (int i = 256; i < 512; ++i) {
        es2.push_back(i);
    }

    test_adding_into_set(set, es2);
}

ext: cc

max_stars_repo_name: ivartb/itmo-assembler

max_issues_repo_name: ivartb/itmo-assembler

max_forks_repo_name: ivartb/itmo-assembler


text:
#pragma once

#include <mdw/formula/cache/KnownType.hpp>
#include <mdw/Tracer.hpp>
#include <boost/unordered_map.hpp>

namespace mdw { namespace formula {

  template <class T> class TypedExpression;

  template <class T> class ActualType: public KnownType
  {
  public:
    ActualType(ExpressionType iType):
      KnownType(iType, TypeTraits<T>::kTypeAsString)
    {}

    Expression& getUnaryCached(Expression& ioChild,
                               const FactByAddress& ioFact,
                               ArenaAllocator& ioAllocator) const;

    Expression& getConstant(Expression& ioInitial,
                            ExpressionType iType,
                            ArenaAllocator& ioAllocator) const;

    virtual FactByAddress& getFactByAddress(const Expression& iFact, ArenaAllocator& ioAllocator) const;
  };

  template <class T> class ActualFactByAddress: public FactByAddress
  {
    const TypedExpression<T>& _expression;
  public:
    ActualFactByAddress(const Expression& iExpression);

    virtual const void *compute(IContext& ioContext) const;
    virtual const Expression& getExpression() const;
  };

}}

#include <mdw/formula/impl/ActualType.hpp>

max_stars_repo_name: AmadeusITGroup/Formula

max_issues_repo_name: AmadeusITGroup/Formula

max_forks_repo_name: AmadeusITGroup/Formula


text:
// (C) Copyright Jeremy Siek 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Sample output:
//  mask =      101010101010
//  Enter a 12-bit bitset in binary: 100110101101
//  x =        100110101101
//  As ulong:  2477
//  And with mask: 100010101000
//  Or with mask:  101110101111

#include <iostream>
#include <boost/dynamic_bitset.hpp>

int main(int, char*[]) {
  const boost::dynamic_bitset<> mask(12, 2730ul);
  std::cout << "mask = " << mask << std::endl;

  boost::dynamic_bitset<> x(12);
  std::cout << "x.size()=" << x.size() << std::endl;

  std::cout << "Enter a 12-bit bitset in binary: " << std::flush;
  if (std::cin >> x) {
    std::cout << "input number:     " << x << std::endl;
    std::cout << "As unsigned long: " << x.to_ulong() << std::endl;
    std::cout << "And with mask:    " << (x & mask) << std::endl;
    std::cout << "Or with mask:     " << (x | mask) << std::endl;
    std::cout << "Shifted left:     " << (x << 1) << std::endl;
    std::cout << "Shifted right:    " << (x >> 1) << std::endl;
  }
  return EXIT_SUCCESS;
}

ext: cpp

max_stars_repo_name: spxuw/RFIM

max_issues_repo_name: spxuw/RFIM

max_forks_repo_name: spxuw/RFIM


text:
#ifndef BOOST_DETAIL_ATOMIC_GCC_PPC_HPP
#define BOOST_DETAIL_ATOMIC_GCC_PPC_HPP

//  Copyright (c) 2009 Helge Bahmann
//
//  Distributed under the Boost Software License, Version 1.0.
//  See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

#include <boost/atomic/detail/base.hpp>

/*
	Refer to: Motorola: "Programming Environments Manual for 32-Bit
	Implementations of the PowerPC Architecture", Appendix E:
	"Synchronization Programming Examples" for an explanation of what is
	going on here (can be found on the web at various places by the
	name "MPCFPE32B.pdf", Google is your friend...)

	Most of the atomic operations map to instructions in a relatively
	straight-forward fashion, but "load"s may at first glance appear
	a bit strange as they map to:

			lwz %rX, addr
			cmpw %rX, %rX
			bne- 1f
		1:

	That is, the CPU is forced to perform a branch that "formally" depends
	on the value retrieved from memory. This scheme has an overhead of
	about 1-2 clock cycles per load, but it allows to map "acquire" to
	the "isync" instruction instead of "sync" uniformly and for all type
	of atomic operations. Since "isync" has a cost of about 15 clock
	cycles, while "sync" hast a cost of about 50 clock cycles, the small
	penalty to atomic loads more than compensates for this.

	Byte- and halfword-sized atomic values are realized by encoding the
	value to be represented into a word, performing sign/zero extension
	as appropriate. This means that after add/sub operations the value
	needs fixing up to accurately preserve the wrap-around semantic of
	the smaller type. (Nothing special needs to be done for the bit-wise
	and the "exchange type" operators as the compiler already sees to
	it that values carried in registers are extended appropriately and
	everything falls into place naturally).

	The register constrant "b"  instructs gcc to use any register
	except r0; this is sometimes required because the encoding for
	r0 is used to signify "constant zero" in a number of instructions,
	making r0 unusable in this place. For simplicity this constraint
	is used everywhere since I am to lazy to look this up on a
	per-instruction basis, and ppc has enough registers for this not
	to pose a problem.
*/

#define BOOST_ATOMIC_CHAR_LOCK_FREE 2
#define BOOST_ATOMIC_CHAR16_T_LOCK_FREE 2
#define BOOST_ATOMIC_CHAR32_T_LOCK_FREE 2
#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 2
#define BOOST_ATOMIC_SHORT_LOCK_FREE 2
#define BOOST_ATOMIC_INT_LOCK_FREE 2
#define BOOST_ATOMIC_LONG_LOCK_FREE 2
#define BOOST_ATOMIC_ADDRESS_LOCK_FREE 2
#if defined(__powerpc64__)
#define BOOST_ATOMIC_LLONG_LOCK_FREE 2
#else
#define BOOST_ATOMIC_LLONG_LOCK_FREE 0
#endif
#define BOOST_ATOMIC_BOOL_LOCK_FREE 2

/* Would like to move the slow-path of failed compare_exchange
(that clears the "success" bit) out-of-line. gcc can in
principle do that using ".subsection"/".previous", but Apple's
binutils seemingly does not understand that. Therefore wrap
the "clear" of the flag in a macro and let it remain
in-line for Apple
*/

#if !defined(__APPLE__)

#define BOOST_ATOMIC_ASM_SLOWPATH_CLEAR \
	"1:\n" \
	".subsection 2\n" \
	"2: addi %1,0,0\n" \
	"b 1b\n" \
	".previous\n" \

#else

#define BOOST_ATOMIC_ASM_SLOWPATH_CLEAR \
	"b 1f\n" \
	"2: addi %1,0,0\n" \
	"1:\n" \

#endif

namespace boost {
namespace detail {
namespace atomic {

static inline void
ppc_fence_before(memory_order order)
{
	switch(order) {
		case memory_order_release:
		case memory_order_acq_rel:
#if defined(__powerpc64__)
			__asm__ __volatile__ ("lwsync" ::: "memory");
			break;
#endif
		case memory_order_seq_cst:
			__asm__ __volatile__ ("sync" ::: "memory");
		default:;
	}
}

static inline void
ppc_fence_after(memory_order order)
{
	switch(order) {
		case memory_order_acquire:
		case memory_order_acq_rel:
		case memory_order_seq_cst:
			__asm__ __volatile__ ("isync");
		case memory_order_consume:
			__asm__ __volatile__ ("" ::: "memory");
		default:;
	}
}

static inline void
ppc_fence_after_store(memory_order order)
{
	switch(order) {
		case memory_order_seq_cst:
			__asm__ __volatile__ ("sync");
		default:;
	}
}

/* integral types */

template<typename T>
class base_atomic<T, int, 1, true> {
	typedef base_atomic this_type;
	typedef T value_type;
	typedef int32_t storage_type;
	typedef T difference_type;
public:
	explicit base_atomic(value_type v) : v_(v) {}
	base_atomic(void) {}

	void
	store(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		ppc_fence_before(order);
		__asm__ (
			"stw %1, %0\n"
			: "+m"(v_)
			: "r" (v)
		);
		ppc_fence_after_store(order);
	}

	value_type
	load(memory_order order = memory_order_seq_cst) const volatile
	{
		value_type v;
		__asm__ __volatile__ (
			"lwz %0, %1\n"
			"cmpw %0, %0\n"
			"bne- 1f\n"
			"1:\n"
			: "=&r" (v)
			: "m" (v_)
		);
		ppc_fence_after(order);
		return v;
	}

	value_type
	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y1\n"
			"stwcx. %2,%y1\n"
			"bne- 1b\n"
			: "=&b" (original), "+Z"(v_)
			: "b" (v)
			: "cr0"
		);
		ppc_fence_after(order);
		return original;
	}

	bool
	compare_exchange_weak(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 2f\n"
			"addi %1,0,1\n"
			"1:"
			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	bool
	compare_exchange_strong(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"0: lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 0b\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	value_type
	fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"add %1,%0,%3\n"
			"extsb %1, %1\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"sub %1,%0,%3\n"
			"extsb %1, %1\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"and %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"or %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"xor %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	bool
	is_lock_free(void) const volatile
	{
		return true;
	}

	BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
private:
	base_atomic(const base_atomic &) /* = delete */ ;
	void operator=(const base_atomic &) /* = delete */ ;
	storage_type v_;
};

template<typename T>
class base_atomic<T, int, 1, false> {
	typedef base_atomic this_type;
	typedef T value_type;
	typedef uint32_t storage_type;
	typedef T difference_type;
public:
	explicit base_atomic(value_type v) : v_(v) {}
	base_atomic(void) {}

	void
	store(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		ppc_fence_before(order);
		__asm__ (
			"stw %1, %0\n"
			: "+m"(v_)
			: "r" (v)
		);
		ppc_fence_after_store(order);
	}

	value_type
	load(memory_order order = memory_order_seq_cst) const volatile
	{
		value_type v;
		__asm__ __volatile__ (
			"lwz %0, %1\n"
			"cmpw %0, %0\n"
			"bne- 1f\n"
			"1:\n"
			: "=&r" (v)
			: "m" (v_)
		);
		ppc_fence_after(order);
		return v;
	}

	value_type
	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y1\n"
			"stwcx. %2,%y1\n"
			"bne- 1b\n"
			: "=&b" (original), "+Z"(v_)
			: "b" (v)
			: "cr0"
		);
		ppc_fence_after(order);
		return original;
	}

	bool
	compare_exchange_weak(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 2f\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	bool
	compare_exchange_strong(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"0: lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 0b\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	value_type
	fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"add %1,%0,%3\n"
			"rlwinm %1, %1, 0, 0xff\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"sub %1,%0,%3\n"
			"rlwinm %1, %1, 0, 0xff\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"and %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"or %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"xor %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	bool
	is_lock_free(void) const volatile
	{
		return true;
	}

	BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
private:
	base_atomic(const base_atomic &) /* = delete */ ;
	void operator=(const base_atomic &) /* = delete */ ;
	storage_type v_;
};

template<typename T>
class base_atomic<T, int, 2, true> {
	typedef base_atomic this_type;
	typedef T value_type;
	typedef int32_t storage_type;
	typedef T difference_type;
public:
	explicit base_atomic(value_type v) : v_(v) {}
	base_atomic(void) {}

	void
	store(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		ppc_fence_before(order);
		__asm__ (
			"stw %1, %0\n"
			: "+m"(v_)
			: "r" (v)
		);
		ppc_fence_after_store(order);
	}

	value_type
	load(memory_order order = memory_order_seq_cst) const volatile
	{
		value_type v;
		__asm__ __volatile__ (
			"lwz %0, %1\n"
			"cmpw %0, %0\n"
			"bne- 1f\n"
			"1:\n"
			: "=&r" (v)
			: "m" (v_)
		);
		ppc_fence_after(order);
		return v;
	}

	value_type
	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y1\n"
			"stwcx. %2,%y1\n"
			"bne- 1b\n"
			: "=&b" (original), "+Z"(v_)
			: "b" (v)
			: "cr0"
		);
		ppc_fence_after(order);
		return original;
	}

	bool
	compare_exchange_weak(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 2f\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	bool
	compare_exchange_strong(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"0: lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 0b\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	value_type
	fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"add %1,%0,%3\n"
			"extsh %1, %1\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"sub %1,%0,%3\n"
			"extsh %1, %1\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"and %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"or %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"xor %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	bool
	is_lock_free(void) const volatile
	{
		return true;
	}

	BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
private:
	base_atomic(const base_atomic &) /* = delete */ ;
	void operator=(const base_atomic &) /* = delete */ ;
	storage_type v_;
};

template<typename T>
class base_atomic<T, int, 2, false> {
	typedef base_atomic this_type;
	typedef T value_type;
	typedef uint32_t storage_type;
	typedef T difference_type;
public:
	explicit base_atomic(value_type v) : v_(v) {}
	base_atomic(void) {}

	void
	store(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		ppc_fence_before(order);
		__asm__ (
			"stw %1, %0\n"
			: "+m"(v_)
			: "r" (v)
		);
		ppc_fence_after_store(order);
	}

	value_type
	load(memory_order order = memory_order_seq_cst) const volatile
	{
		value_type v;
		__asm__ __volatile__ (
			"lwz %0, %1\n"
			"cmpw %0, %0\n"
			"bne- 1f\n"
			"1:\n"
			: "=&r" (v)
			: "m" (v_)
		);
		ppc_fence_after(order);
		return v;
	}

	value_type
	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y1\n"
			"stwcx. %2,%y1\n"
			"bne- 1b\n"
			: "=&b" (original), "+Z"(v_)
			: "b" (v)
			: "cr0"
		);
		ppc_fence_after(order);
		return original;
	}

	bool
	compare_exchange_weak(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 2f\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	bool
	compare_exchange_strong(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"0: lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 0b\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	value_type
	fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"add %1,%0,%3\n"
			"rlwinm %1, %1, 0, 0xffff\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"sub %1,%0,%3\n"
			"rlwinm %1, %1, 0, 0xffff\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"and %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"or %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"xor %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	bool
	is_lock_free(void) const volatile
	{
		return true;
	}

	BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
private:
	base_atomic(const base_atomic &) /* = delete */ ;
	void operator=(const base_atomic &) /* = delete */ ;
	storage_type v_;
};

template<typename T, bool Sign>
class base_atomic<T, int, 4, Sign> {
	typedef base_atomic this_type;
	typedef T value_type;
	typedef T difference_type;
public:
	explicit base_atomic(value_type v) : v_(v) {}
	base_atomic(void) {}

	void
	store(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		ppc_fence_before(order);
		const_cast<volatile value_type &>(v_) = v;
		ppc_fence_after_store(order);
	}

	value_type
	load(memory_order order = memory_order_seq_cst) const volatile
	{
		value_type v = const_cast<const volatile value_type &>(v_);
		__asm__ __volatile__ (
			"cmpw %0, %0\n"
			"bne- 1f\n"
			"1:\n"
			: "+b"(v)
			:
			: "cr0"
		);
		ppc_fence_after(order);
		return v;
	}

	value_type
	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y1\n"
			"stwcx. %2,%y1\n"
			"bne- 1b\n"
			: "=&b" (original), "+Z"(v_)
			: "b" (v)
			: "cr0"
		);
		ppc_fence_after(order);
		return original;
	}

	bool
	compare_exchange_weak(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 2f\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	bool
	compare_exchange_strong(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"0: lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 0b\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	value_type
	fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"add %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"sub %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"and %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"or %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"xor %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	bool
	is_lock_free(void) const volatile
	{
		return true;
	}

	BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
private:
	base_atomic(const base_atomic &) /* = delete */ ;
	void operator=(const base_atomic &) /* = delete */ ;
	value_type v_;
};

#if defined(__powerpc64__)

template<typename T, bool Sign>
class base_atomic<T, int, 8, Sign> {
	typedef base_atomic this_type;
	typedef T value_type;
	typedef T difference_type;
public:
	explicit base_atomic(value_type v) : v_(v) {}
	base_atomic(void) {}

	void
	store(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		ppc_fence_before(order);
		const_cast<volatile value_type &>(v_) = v;
		ppc_fence_after_store(order);
	}

	value_type
	load(memory_order order = memory_order_seq_cst) const volatile
	{
		value_type v = const_cast<const volatile value_type &>(v_);
		__asm__ __volatile__ (
			"cmpd %0, %0\n"
			"bne- 1f\n"
			"1:\n"
			: "+b"(v)
			:
			: "cr0"
		);
		ppc_fence_after(order);
		return v;
	}

	value_type
	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"ldarx %0,%y1\n"
			"stdcx. %2,%y1\n"
			"bne- 1b\n"
			: "=&b" (original), "+Z"(v_)
			: "b" (v)
			: "cr0"
		);
		ppc_fence_after(order);
		return original;
	}

	bool
	compare_exchange_weak(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"ldarx %0,%y2\n"
			"cmpd %0, %3\n"
			"bne- 2f\n"
			"stdcx. %4,%y2\n"
			"bne- 2f\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	bool
	compare_exchange_strong(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"0: ldarx %0,%y2\n"
			"cmpd %0, %3\n"
			"bne- 2f\n"
			"stdcx. %4,%y2\n"
			"bne- 0b\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	value_type
	fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"ldarx %0,%y2\n"
			"add %1,%0,%3\n"
			"stdcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"ldarx %0,%y2\n"
			"sub %1,%0,%3\n"
			"stdcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"ldarx %0,%y2\n"
			"and %1,%0,%3\n"
			"stdcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"ldarx %0,%y2\n"
			"or %1,%0,%3\n"
			"stdcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"ldarx %0,%y2\n"
			"xor %1,%0,%3\n"
			"stdcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	bool
	is_lock_free(void) const volatile
	{
		return true;
	}

	BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
private:
	base_atomic(const base_atomic &) /* = delete */ ;
	void operator=(const base_atomic &) /* = delete */ ;
	value_type v_;
};

#endif

/* pointer types */

#if !defined(__powerpc64__)

template<bool Sign>
class base_atomic<void *, void *, 4, Sign> {
	typedef base_atomic this_type;
	typedef void * value_type;
public:
	explicit base_atomic(value_type v) : v_(v) {}
	base_atomic(void) {}

	void
	store(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		ppc_fence_before(order);
		__asm__ (
			"stw %1, %0\n"
			: "+m" (v_)
			: "r" (v)
		);
		ppc_fence_after_store(order);
	}

	value_type
	load(memory_order order = memory_order_seq_cst) const volatile
	{
		value_type v;
		__asm__ (
			"lwz %0, %1\n"
			"cmpw %0, %0\n"
			"bne- 1f\n"
			"1:\n"
			: "=r"(v)
			: "m"(v_)
			: "cr0"
		);
		ppc_fence_after(order);
		return v;
	}

	value_type
	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y1\n"
			"stwcx. %2,%y1\n"
			"bne- 1b\n"
			: "=&b" (original), "+Z"(v_)
			: "b" (v)
			: "cr0"
		);
		ppc_fence_after(order);
		return original;
	}

	bool
	compare_exchange_weak(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 2f\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	bool
	compare_exchange_strong(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"0: lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 0b\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	bool
	is_lock_free(void) const volatile
	{
		return true;
	}

	BOOST_ATOMIC_DECLARE_BASE_OPERATORS
private:
	base_atomic(const base_atomic &) /* = delete */ ;
	void operator=(const base_atomic &) /* = delete */ ;
	value_type v_;
};

template<typename T, bool Sign>
class base_atomic<T *, void *, 4, Sign> {
	typedef base_atomic this_type;
	typedef T * value_type;
	typedef ptrdiff_t difference_type;
public:
	explicit base_atomic(value_type v) : v_(v) {}
	base_atomic(void) {}

	void
	store(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		ppc_fence_before(order);
		__asm__ (
			"stw %1, %0\n"
			: "+m" (v_)
			: "r" (v)
		);
		ppc_fence_after_store(order);
	}

	value_type
	load(memory_order order = memory_order_seq_cst) const volatile
	{
		value_type v;
		__asm__ (
			"lwz %0, %1\n"
			"cmpw %0, %0\n"
			"bne- 1f\n"
			"1:\n"
			: "=r"(v)
			: "m"(v_)
			: "cr0"
		);
		ppc_fence_after(order);
		return v;
	}

	value_type
	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y1\n"
			"stwcx. %2,%y1\n"
			"bne- 1b\n"
			: "=&b" (original), "+Z"(v_)
			: "b" (v)
			: "cr0"
		);
		ppc_fence_after(order);
		return original;
	}

	bool
	compare_exchange_weak(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 2f\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	bool
	compare_exchange_strong(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"0: lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 0b\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	value_type
	fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile
	{
		v = v * sizeof(*v_);
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"add %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile
	{
		v = v * sizeof(*v_);
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y2\n"
			"sub %1,%0,%3\n"
			"stwcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	bool
	is_lock_free(void) const volatile
	{
		return true;
	}

	BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
private:
	base_atomic(const base_atomic &) /* = delete */ ;
	void operator=(const base_atomic &) /* = delete */ ;
	value_type v_;
};

#else

template<bool Sign>
class base_atomic<void *, void *, 8, Sign> {
	typedef base_atomic this_type;
	typedef void * value_type;
public:
	explicit base_atomic(value_type v) : v_(v) {}
	base_atomic(void) {}

	void
	store(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		ppc_fence_before(order);
		__asm__ (
			"std %1, %0\n"
			: "+m" (v_)
			: "r" (v)
		);
		ppc_fence_after_store(order);
	}

	value_type
	load(memory_order order = memory_order_seq_cst) const volatile
	{
		value_type v;
		__asm__ (
			"ld %0, %1\n"
			"cmpd %0, %0\n"
			"bne- 1f\n"
			"1:\n"
			: "=r"(v)
			: "m"(v_)
			: "cr0"
		);
		ppc_fence_after(order);
		return v;
	}

	value_type
	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"ldarx %0,%y1\n"
			"stdcx. %2,%y1\n"
			"bne- 1b\n"
			: "=&b" (original), "+Z"(v_)
			: "b" (v)
			: "cr0"
		);
		ppc_fence_after(order);
		return original;
	}

	bool
	compare_exchange_weak(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"ldarx %0,%y2\n"
			"cmpd %0, %3\n"
			"bne- 2f\n"
			"stdcx. %4,%y2\n"
			"bne- 2f\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	bool
	compare_exchange_strong(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"0: ldarx %0,%y2\n"
			"cmpd %0, %3\n"
			"bne- 2f\n"
			"stdcx. %4,%y2\n"
			"bne- 0b\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	bool
	is_lock_free(void) const volatile
	{
		return true;
	}

	BOOST_ATOMIC_DECLARE_BASE_OPERATORS
private:
	base_atomic(const base_atomic &) /* = delete */ ;
	void operator=(const base_atomic &) /* = delete */ ;
	value_type v_;
};

template<typename T, bool Sign>
class base_atomic<T *, void *, 8, Sign> {
	typedef base_atomic this_type;
	typedef T * value_type;
	typedef ptrdiff_t difference_type;
public:
	explicit base_atomic(value_type v) : v_(v) {}
	base_atomic(void) {}

	void
	store(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		ppc_fence_before(order);
		__asm__ (
			"std %1, %0\n"
			: "+m" (v_)
			: "r" (v)
		);
		ppc_fence_after_store(order);
	}

	value_type
	load(memory_order order = memory_order_seq_cst) const volatile
	{
		value_type v;
		__asm__ (
			"ld %0, %1\n"
			"cmpd %0, %0\n"
			"bne- 1f\n"
			"1:\n"
			: "=r"(v)
			: "m"(v_)
			: "cr0"
		);
		ppc_fence_after(order);
		return v;
	}

	value_type
	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		value_type original;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"ldarx %0,%y1\n"
			"stdcx. %2,%y1\n"
			"bne- 1b\n"
			: "=&b" (original), "+Z"(v_)
			: "b" (v)
			: "cr0"
		);
		ppc_fence_after(order);
		return original;
	}

	bool
	compare_exchange_weak(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"ldarx %0,%y2\n"
			"cmpd %0, %3\n"
			"bne- 2f\n"
			"stdcx. %4,%y2\n"
			"bne- 2f\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	bool
	compare_exchange_strong(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		int success;
		ppc_fence_before(success_order);
		__asm__(
			"0: ldarx %0,%y2\n"
			"cmpd %0, %3\n"
			"bne- 2f\n"
			"stdcx. %4,%y2\n"
			"bne- 0b\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected), "=&b" (success), "+Z"(v_)
			: "b" (expected), "b" (desired)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		return success;
	}

	value_type
	fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile
	{
		v = v * sizeof(*v_);
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"ldarx %0,%y2\n"
			"add %1,%0,%3\n"
			"stdcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	value_type
	fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile
	{
		v = v * sizeof(*v_);
		value_type original, tmp;
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"ldarx %0,%y2\n"
			"sub %1,%0,%3\n"
			"stdcx. %1,%y2\n"
			"bne- 1b\n"
			: "=&b" (original), "=&b" (tmp), "+Z"(v_)
			: "b" (v)
			: "cc");
		ppc_fence_after(order);
		return original;
	}

	bool
	is_lock_free(void) const volatile
	{
		return true;
	}

	BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
private:
	base_atomic(const base_atomic &) /* = delete */ ;
	void operator=(const base_atomic &) /* = delete */ ;
	value_type v_;
};

#endif

/* generic */

template<typename T, bool Sign>
class base_atomic<T, void, 1, Sign> {
	typedef base_atomic this_type;
	typedef T value_type;
	typedef uint32_t storage_type;
public:
	explicit base_atomic(value_type v) : v_(0)
	{
		memcpy(&v_, &v, sizeof(value_type));
	}
	base_atomic(void) : v_(0) {}

	void
	store(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		storage_type tmp = 0;
		memcpy(&tmp, &v, sizeof(value_type));
		ppc_fence_before(order);
		__asm__ (
			"stw %1, %0\n"
			: "+m" (v_)
			: "r" (tmp)
		);
		ppc_fence_after_store(order);
	}

	value_type
	load(memory_order order = memory_order_seq_cst) const volatile
	{
		storage_type tmp;
		__asm__ __volatile__ (
			"lwz %0, %1\n"
			"cmpw %0, %0\n"
			"bne- 1f\n"
			"1:\n"
			: "=r"(tmp)
			: "m"(v_)
			: "cr0"
		);
		ppc_fence_after(order);

		value_type v;
		memcpy(&v, &tmp, sizeof(value_type));
		return v;
	}

	value_type
	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		storage_type tmp = 0, original;
		memcpy(&tmp, &v, sizeof(value_type));
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y1\n"
			"stwcx. %2,%y1\n"
			"bne- 1b\n"
			: "=&b" (original), "+Z"(v_)
			: "b" (tmp)
			: "cr0"
		);
		ppc_fence_after(order);
		memcpy(&v, &original, sizeof(value_type));
		return v;
	}

	bool
	compare_exchange_weak(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		storage_type expected_s = 0, desired_s = 0;
		memcpy(&expected_s, &expected, sizeof(value_type));
		memcpy(&desired_s, &desired, sizeof(value_type));

		int success;
		ppc_fence_before(success_order);
		__asm__(
			"lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 2f\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected_s), "=&b" (success), "+Z"(v_)
			: "b" (expected_s), "b" (desired_s)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		memcpy(&expected, &expected_s, sizeof(value_type));
		return success;
	}

	bool
	compare_exchange_strong(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		storage_type expected_s = 0, desired_s = 0;
		memcpy(&expected_s, &expected, sizeof(value_type));
		memcpy(&desired_s, &desired, sizeof(value_type));

		int success;
		ppc_fence_before(success_order);
		__asm__(
			"0: lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 0b\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected_s), "=&b" (success), "+Z"(v_)
			: "b" (expected_s), "b" (desired_s)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		memcpy(&expected, &expected_s, sizeof(value_type));
		return success;
	}

	bool
	is_lock_free(void) const volatile
	{
		return true;
	}

	BOOST_ATOMIC_DECLARE_BASE_OPERATORS
private:
	base_atomic(const base_atomic &) /* = delete */ ;
	void operator=(const base_atomic &) /* = delete */ ;
	storage_type v_;
};

template<typename T, bool Sign>
class base_atomic<T, void, 2, Sign> {
	typedef base_atomic this_type;
	typedef T value_type;
	typedef uint32_t storage_type;
public:
	explicit base_atomic(value_type v) : v_(0)
	{
		memcpy(&v_, &v, sizeof(value_type));
	}
	base_atomic(void) : v_(0) {}

	void
	store(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		storage_type tmp = 0;
		memcpy(&tmp, &v, sizeof(value_type));
		ppc_fence_before(order);
		__asm__ (
			"stw %1, %0\n"
			: "+m" (v_)
			: "r" (tmp)
		);
		ppc_fence_after_store(order);
	}

	value_type
	load(memory_order order = memory_order_seq_cst) const volatile
	{
		storage_type tmp;
		__asm__ __volatile__ (
			"lwz %0, %1\n"
			"cmpw %0, %0\n"
			"bne- 1f\n"
			"1:\n"
			: "=r"(tmp)
			: "m"(v_)
			: "cr0"
		);
		ppc_fence_after(order);

		value_type v;
		memcpy(&v, &tmp, sizeof(value_type));
		return v;
	}

	value_type
	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		storage_type tmp = 0, original;
		memcpy(&tmp, &v, sizeof(value_type));
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y1\n"
			"stwcx. %2,%y1\n"
			"bne- 1b\n"
			: "=&b" (original), "+Z"(v_)
			: "b" (tmp)
			: "cr0"
		);
		ppc_fence_after(order);
		memcpy(&v, &original, sizeof(value_type));
		return v;
	}

	bool
	compare_exchange_weak(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		storage_type expected_s = 0, desired_s = 0;
		memcpy(&expected_s, &expected, sizeof(value_type));
		memcpy(&desired_s, &desired, sizeof(value_type));

		int success;
		ppc_fence_before(success_order);
		__asm__(
			"lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 2f\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected_s), "=&b" (success), "+Z"(v_)
			: "b" (expected_s), "b" (desired_s)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		memcpy(&expected, &expected_s, sizeof(value_type));
		return success;
	}

	bool
	compare_exchange_strong(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		storage_type expected_s = 0, desired_s = 0;
		memcpy(&expected_s, &expected, sizeof(value_type));
		memcpy(&desired_s, &desired, sizeof(value_type));

		int success;
		ppc_fence_before(success_order);
		__asm__(
			"0: lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 0b\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected_s), "=&b" (success), "+Z"(v_)
			: "b" (expected_s), "b" (desired_s)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		memcpy(&expected, &expected_s, sizeof(value_type));
		return success;
	}

	bool
	is_lock_free(void) const volatile
	{
		return true;
	}

	BOOST_ATOMIC_DECLARE_BASE_OPERATORS
private:
	base_atomic(const base_atomic &) /* = delete */ ;
	void operator=(const base_atomic &) /* = delete */ ;
	storage_type v_;
};

template<typename T, bool Sign>
class base_atomic<T, void, 4, Sign> {
	typedef base_atomic this_type;
	typedef T value_type;
	typedef uint32_t storage_type;
public:
	explicit base_atomic(value_type v) : v_(0)
	{
		memcpy(&v_, &v, sizeof(value_type));
	}
	base_atomic(void) : v_(0) {}

	void
	store(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		storage_type tmp = 0;
		memcpy(&tmp, &v, sizeof(value_type));
		ppc_fence_before(order);
		__asm__ (
			"stw %1, %0\n"
			: "+m" (v_)
			: "r" (tmp)
		);
		ppc_fence_after_store(order);
	}

	value_type
	load(memory_order order = memory_order_seq_cst) const volatile
	{
		storage_type tmp;
		__asm__ __volatile__ (
			"lwz %0, %1\n"
			"cmpw %0, %0\n"
			"bne- 1f\n"
			"1:\n"
			: "=r"(tmp)
			: "m"(v_)
			: "cr0"
		);
		ppc_fence_after(order);

		value_type v;
		memcpy(&v, &tmp, sizeof(value_type));
		return v;
	}

	value_type
	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		storage_type tmp = 0, original;
		memcpy(&tmp, &v, sizeof(value_type));
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"lwarx %0,%y1\n"
			"stwcx. %2,%y1\n"
			"bne- 1b\n"
			: "=&b" (original), "+Z"(v_)
			: "b" (tmp)
			: "cr0"
		);
		ppc_fence_after(order);
		memcpy(&v, &original, sizeof(value_type));
		return v;
	}

	bool
	compare_exchange_weak(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		storage_type expected_s = 0, desired_s = 0;
		memcpy(&expected_s, &expected, sizeof(value_type));
		memcpy(&desired_s, &desired, sizeof(value_type));

		int success;
		ppc_fence_before(success_order);
		__asm__(
			"lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 2f\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected_s), "=&b" (success), "+Z"(v_)
			: "b" (expected_s), "b" (desired_s)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		memcpy(&expected, &expected_s, sizeof(value_type));
		return success;
	}

	bool
	compare_exchange_strong(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		storage_type expected_s = 0, desired_s = 0;
		memcpy(&expected_s, &expected, sizeof(value_type));
		memcpy(&desired_s, &desired, sizeof(value_type));

		int success;
		ppc_fence_before(success_order);
		__asm__(
			"0: lwarx %0,%y2\n"
			"cmpw %0, %3\n"
			"bne- 2f\n"
			"stwcx. %4,%y2\n"
			"bne- 0b\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected_s), "=&b" (success), "+Z"(v_)
			: "b" (expected_s), "b" (desired_s)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		memcpy(&expected, &expected_s, sizeof(value_type));
		return success;
	}

	bool
	is_lock_free(void) const volatile
	{
		return true;
	}

	BOOST_ATOMIC_DECLARE_BASE_OPERATORS
private:
	base_atomic(const base_atomic &) /* = delete */ ;
	void operator=(const base_atomic &) /* = delete */ ;
	storage_type v_;
};

#if defined(__powerpc64__)

template<typename T, bool Sign>
class base_atomic<T, void, 8, Sign> {
	typedef base_atomic this_type;
	typedef T value_type;
	typedef uint64_t storage_type;
public:
	explicit base_atomic(value_type v)
	{
		memcpy(&v_, &v, sizeof(value_type));
	}
	base_atomic(void) {}

	void
	store(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		storage_type tmp;
		memcpy(&tmp, &v, sizeof(value_type));
		ppc_fence_before(order);
		__asm__ (
			"std %1, %0\n"
			: "+m" (v_)
			: "r" (tmp)
		);
		ppc_fence_after_store(order);
	}

	value_type
	load(memory_order order = memory_order_seq_cst) const volatile
	{
		storage_type tmp;
		__asm__ __volatile__ (
			"ld %0, %1\n"
			"cmpd %0, %0\n"
			"bne- 1f\n"
			"1:\n"
			: "=r"(tmp)
			: "m"(v_)
			: "cr0"
		);
		ppc_fence_after(order);

		value_type v;
		memcpy(&v, &tmp, sizeof(value_type));
		return v;
	}

	value_type
	exchange(value_type v, memory_order order = memory_order_seq_cst) volatile
	{
		storage_type tmp = 0, original;
		memcpy(&tmp, &v, sizeof(value_type));
		ppc_fence_before(order);
		__asm__ (
			"1:\n"
			"ldarx %0,%y1\n"
			"stdcx. %2,%y1\n"
			"bne- 1b\n"
			: "=&b" (original), "+Z"(v_)
			: "b" (tmp)
			: "cr0"
		);
		ppc_fence_after(order);
		memcpy(&v, &original, sizeof(value_type));
		return v;
	}

	bool
	compare_exchange_weak(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		storage_type expected_s, desired_s;
		memcpy(&expected_s, &expected, sizeof(value_type));
		memcpy(&desired_s, &desired, sizeof(value_type));

		int success;
		ppc_fence_before(success_order);
		__asm__(
			"ldarx %0,%y2\n"
			"cmpd %0, %3\n"
			"bne- 2f\n"
			"stdcx. %4,%y2\n"
			"bne- 2f\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected_s), "=&b" (success), "+Z"(v_)
			: "b" (expected_s), "b" (desired_s)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		memcpy(&expected, &expected_s, sizeof(value_type));
		return success;
	}

	bool
	compare_exchange_strong(
		value_type & expected,
		value_type desired,
		memory_order success_order,
		memory_order failure_order) volatile
	{
		storage_type expected_s, desired_s;
		memcpy(&expected_s, &expected, sizeof(value_type));
		memcpy(&desired_s, &desired, sizeof(value_type));

		int success;
		ppc_fence_before(success_order);
		__asm__(
			"0: ldarx %0,%y2\n"
			"cmpd %0, %3\n"
			"bne- 2f\n"
			"stdcx. %4,%y2\n"
			"bne- 0b\n"
			"addi %1,0,1\n"
			"1:"

			BOOST_ATOMIC_ASM_SLOWPATH_CLEAR
			: "=&b" (expected_s), "=&b" (success), "+Z"(v_)
			: "b" (expected_s), "b" (desired_s)
			: "cr0"
		);
		if (success)
			ppc_fence_after(success_order);
		else
			ppc_fence_after(failure_order);
		memcpy(&expected, &expected_s, sizeof(value_type));
		return success;
	}

	bool
	is_lock_free(void) const volatile
	{
		return true;
	}

	BOOST_ATOMIC_DECLARE_BASE_OPERATORS
private:
	base_atomic(const base_atomic &) /* = delete */ ;
	void operator=(const base_atomic &) /* = delete */ ;
	storage_type v_;
};
#endif

}
}

#define BOOST_ATOMIC_THREAD_FENCE 2
inline void
atomic_thread_fence(memory_order order)
{
	switch(order) {
		case memory_order_acquire:
			__asm__ __volatile__ ("isync" ::: "memory");
			break;
		case memory_order_release:
#if defined(__powerpc64__)
			__asm__ __volatile__ ("lwsync" ::: "memory");
			break;
#endif
		case memory_order_acq_rel:
		case memory_order_seq_cst:
			__asm__ __volatile__ ("sync" ::: "memory");
		default:;
	}
}

#define BOOST_ATOMIC_SIGNAL_FENCE 2
inline void
atomic_signal_fence(memory_order order)
{
	switch(order) {
		case memory_order_acquire:
		case memory_order_release:
		case memory_order_acq_rel:
		case memory_order_seq_cst:
			__asm__ __volatile__ ("" ::: "memory");
			break;
		default:;
	}
}

}

#endif

max_stars_repo_name: sosan/NoahGameFrame

max_issues_repo_name: sosan/NoahGameFrame

max_forks_repo_name: sosan/NoahGameFrame


text:
//
// Copyright 2016 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
//    names, trademarks, service marks, or product names of the Licensor
//    and its affiliates, except as required to comply with Section 4(c) of
//    the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//

#include "pxr/pxr.h"

#include "pxr/base/tf/api.h"
#include "pxr/base/tf/token.h"

#include "pxr/base/tf/hashset.h"
#include "pxr/base/tf/instantiateSingleton.h"
#include "pxr/base/tf/iterator.h"
#include "pxr/base/tf/registryManager.h"
#include "pxr/base/tf/stringUtils.h"
#include "pxr/base/tf/type.h"

#include "pxr/base/arch/align.h"

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>

#include <tbb/spin_mutex.h>

#include <string>
#include <iostream>
#include <vector>
#include <cstring>
#include <utility>

using std::vector;
using std::string;
using std::pair;

PXR_NAMESPACE_OPEN_SCOPE

struct Tf_TokenRegistry
{
    typedef TfToken::_Rep const *_RepPtr;
    typedef TfPointerAndBits<const TfToken::_Rep> _RepPtrAndBits;

    struct _Eq {
        inline size_t operator()(TfToken::_Rep const &rep1,
                                 TfToken::_Rep const &rep2) const {
            return (*this)(rep1._cstr, rep2._cstr);
        }
        inline bool operator()(const char* s1, const char* s2) const {
            return !strcmp(s1, s2);
        }
    };

    template <int Mul>
    struct _Hash {
        inline size_t operator()(TfToken::_Rep const &rep) const {
            return (*this)(rep._cstr);
        }
        inline size_t operator()(char const *s) const {
            // Matches STL original implementation for now.  Switch to something
            // better?
            unsigned int h = 0;
            for (; *s; ++s)
                h = Mul * h + *s;
            return h;
        }
    };

    typedef _Hash<7> _OuterHash;
    typedef _Hash<5> _InnerHash;

    static const size_t _NumSets = 128;
    static const size_t _SetMask = _NumSets-1;

    // Utility to pad an instance to take up a cache line to avoid false
    // sharing.
    template <class T>
    struct alignas(ARCH_CACHE_LINE_SIZE) _CacheLinePadded {
        T val;
    };

    // It's not ideal to use TfHashSet here.  It would be better to use
    // boost::multi_index from boost 1.56 or newer: it lets us lookup an element
    // by a key more easily.  It also has better performance.  Earlier versions
    // suffer from the issue where erase(iterator) has to return an iterator to
    // the next element, which has to scan forward to find the next, so we use
    // TfHashSet for now.
    typedef TfHashSet<TfToken::_Rep, _InnerHash, _Eq> _RepSet;

    // Data members.
    _RepSet _sets[_NumSets];
    mutable _CacheLinePadded<tbb::spin_mutex> _locks[_NumSets];

    static Tf_TokenRegistry& _GetInstance() {
        return TfSingleton<Tf_TokenRegistry>::GetInstance();
    }

    inline size_t _GetSetNum(char const *s) const {
        _OuterHash h;
        return h(s) & _SetMask;
    }

    inline _RepPtrAndBits _GetPtrChar(char const *s, bool makeImmortal) {
        return _GetPtrImpl(s, makeImmortal);
    }
    inline _RepPtrAndBits _GetPtrStr(string const &s, bool makeImmortal) {
        // Explicitly specify template arg -- if unspecified, it will deduce
        // string by-value, which we don't want.
        return _GetPtrImpl<string const &>(s, makeImmortal);
    }

    inline _RepPtrAndBits _FindPtrChar(char const *s) const {
        return _FindPtrImpl(s);
    }
    inline _RepPtrAndBits _FindPtrStr(string const &s) const {
        // Explicitly specify template arg -- if unspecified, it will deduce
        // string by-value, which we don't want.
        return _FindPtrImpl<string const &>(s);
    }

    /*
     * rep may be dying.  remove its key and raw pointer reference
     * from the table if it truly is.
     */
    void _PossiblyDestroyRep(_RepPtr rep) {
        bool repFoundInSet = true;
        string repString;
        {
            unsigned int setNum = rep->_setNum;

            tbb::spin_mutex::scoped_lock lock(_locks[setNum].val);

            if (!rep->_isCounted)
                return;

            /*
             * We hold the lock, but there could be others outside the lock
             * modifying this same counter.  Be safe: be atomic.
             */
            if (--rep->_refCount != 0)
                return;

            if (!_sets[setNum].erase(*rep)) {
                repFoundInSet = false;
                repString = rep->_str;
            }
        }
        TF_VERIFY(repFoundInSet,
                  "failed to find token '%s' in table for destruction",
                  repString.c_str());
    }

    void _DumpStats() const {
        std::vector<std::pair<size_t, size_t> > sizesWithSet;
        for (size_t i = 0; i != _NumSets; ++i) {
            sizesWithSet.push_back(std::make_pair(_sets[i].size(), i));
        }
        std::sort(sizesWithSet.begin(), sizesWithSet.end());
        printf("Set # -- Size\n");
        TF_FOR_ALL(i, sizesWithSet) {
            printf("%zu -- %zu\n", i->second, i->first);
        }
    }

private:

    inline bool _IsEmpty(char const *s) const { return !s || !s[0]; }
    inline bool _IsEmpty(string const &s) const { return s.empty(); }

    inline char const *_CStr(char const *s) const { return s; }
    inline char const *_CStr(string const &s) const { return s.c_str(); }

    static TfToken::_Rep _LookupRep(char const *cstr) {
        TfToken::_Rep ret;
        ret._cstr = cstr;
        return ret;
    }

    /*
     * Either finds a key that is stringwise-equal to s,
     * or puts a new _Rep into the map for s.
     */
    template <class Str>
    inline _RepPtrAndBits _GetPtrImpl(Str s, bool makeImmortal) {
        if (_IsEmpty(s))
            return _RepPtrAndBits();

        size_t setNum = _GetSetNum(_CStr(s));

        tbb::spin_mutex::scoped_lock lock(_locks[setNum].val);

        // Insert or lookup an existing.
        _RepSet::iterator iter = _sets[setNum].find(_LookupRep(_CStr(s)));
        if (iter != _sets[setNum].end()) {
            _RepPtr rep = &(*iter);
            bool isCounted = rep->_isCounted;
            if (isCounted) {
                if (makeImmortal)
                    isCounted = rep->_isCounted = false;
                else
                    ++rep->_refCount;
            }
            return _RepPtrAndBits(rep, isCounted);
        } else {
            // No entry present, add a new entry.
            TfAutoMallocTag noname("TfToken");
            _RepPtr rep = &(*_sets[setNum].insert(TfToken::_Rep(s)).first);
            rep->_isCounted = !makeImmortal;
            rep->_setNum = setNum;
            if (!makeImmortal)
                rep->_refCount = 1;
            return _RepPtrAndBits(rep, !makeImmortal);
        }
    }

    template <class Str>
    _RepPtrAndBits _FindPtrImpl(Str s) const {
        if (_IsEmpty(s))
            return _RepPtrAndBits();

        size_t setNum = _GetSetNum(_CStr(s));

        tbb::spin_mutex::scoped_lock lock(_locks[setNum].val);

        _RepSet::const_iterator iter =
            _sets[setNum].find(_LookupRep(_CStr(s)));
        if (iter == _sets[setNum].end())
            return _RepPtrAndBits();

        return _RepPtrAndBits(&(*iter), iter->IncrementIfCounted());
    }

};

TF_INSTANTIATE_SINGLETON(Tf_TokenRegistry);

TF_REGISTRY_FUNCTION(TfType)
{
    TfType::Define<TfToken>();
    TfType::Define< vector<TfToken> >()
        .Alias( TfType::GetRoot(), "vector<TfToken>" );
}

void
TfToken::_PossiblyDestroyRep() const
{
    Tf_TokenRegistry::_GetInstance()._PossiblyDestroyRep(_rep);
}

string const&
TfToken::_GetEmptyString()
{
    static std::string empty;
    return empty;
}

TfToken::TfToken(const string &s)
    : _rep(Tf_TokenRegistry::_GetInstance().
           _GetPtrStr(s, /*makeImmortal*/false))
{
}

TfToken::TfToken(const char *s)
    : _rep(Tf_TokenRegistry::_GetInstance().
           _GetPtrChar(s, /*makeImmortal*/false))
{
}

TfToken::TfToken(const string &s, _ImmortalTag)
    : _rep(Tf_TokenRegistry::_GetInstance().
           _GetPtrStr(s, /*makeImmortal*/true))
{
}

TfToken::TfToken(const char *s, _ImmortalTag)
    : _rep(Tf_TokenRegistry::_GetInstance().
           _GetPtrChar(s, /*makeImmortal*/true))
{
}

TfToken
TfToken::Find(const string& s)
{
    TfToken t;
    t._rep = Tf_TokenRegistry::_GetInstance()._FindPtrStr(s);
    return t;
}

bool
TfToken::operator==(const string &o) const
{
    return GetString() == o;
}

bool
TfToken::operator==(const char *o) const
{
    return GetString() == o;
}

std::vector<TfToken>
TfToTokenVector(const std::vector<string> &sv)
{
    return vector<TfToken>(sv.begin(), sv.end());
}

std::vector<string>
TfToStringVector(const std::vector<TfToken> &tv)
{
    std::vector<string> sv(tv.size());

    for (size_t i = 0; i != tv.size(); i++)
        sv[i] = tv[i].GetString();

    return sv;
}

std::ostream &
operator <<(std::ostream &stream, const TfToken& token)
{
    return stream << token.GetText();
}

TF_API void TfDumpTokenStats()
{
    Tf_TokenRegistry::_GetInstance()._DumpStats();
}

PXR_NAMESPACE_CLOSE_SCOPE

max_stars_repo_name: navefx/YuksUSD

max_issues_repo_name: navefx/YuksUSD

max_forks_repo_name: navefx/YuksUSD


text:
///////////////////////////////////////////////////////////////
//  Copyright 2012 John Maddock. Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt

#include <boost/multiprecision/cpp_int.hpp>
#include "test.hpp"

using Integer = boost::multiprecision::cpp_int;

void check_sqrt(const Integer& s, const Integer& r, const Integer& v) {
   BOOST_CHECK_EQUAL(s * s + r, v);
   BOOST_CHECK_GE(r, Integer(0));
   BOOST_CHECK_LE(s * s, v);
   BOOST_CHECK_GT((s + 1) * (s + 1), v);
}

template<typename I>
void check(const I& v) {
   I r;
   I s = boost::multiprecision::sqrt(v, r);
   check_sqrt(Integer(s), Integer(r), Integer(v));
}

void check_types(const Integer& v) {
   using namespace boost::multiprecision;
   size_t bits = 0;
   if (v > 0) {
      bits = msb(v);
   }
   if (bits < 32) {
      check(static_cast<uint32_t>(v));
   }
   if (bits < 64) {
      check(static_cast<uint64_t>(v));
   }
   if (bits < 128) {
      check(uint128_t(v));
   }
   if (bits < 256) {
      check(uint256_t(v));
   }
   if (bits < 512) {
      check(uint512_t(v));
   }
   check(v);
}

void check_near(const Integer& v) {
   check_types(v);
   for (size_t j = 0; j < 8; j++) {
      check_types(v - Integer(1 << j));
      check_types(v - Integer(1 << j) - 1);
      check_types(v - Integer(1 << j) + 1);
      check_types(v + Integer(1 << j));
      check_types(v + Integer(1 << j) - 1);
      check_types(v + Integer(1 << j) + 1);
   }
}

void test_first() {
   for (size_t i = 0; i < (1 << 16); i++) {
      check_types(Integer(i));
   }
}

void test_perfect() {
   for (size_t i = 256; i < (1 << 14); i++) {
      check_near(Integer(i) * Integer(i));
   }
}

void test_powers() {
   for (size_t i = 24; i < 2048; i++) {
      check_near(Integer(i) << i);
   }
}

void test_big() {
   for (size_t bits = 128; bits <= 2048; bits *= 2) {
      Integer i = Integer(1) << bits;
      Integer s = (i >> 8);
      Integer step = (i - s) / (1 << 8);
      for (Integer j = s; j <= i; j += step) {
         check_near(j);
      }
   }
}

int main()
{
   using namespace boost::multiprecision;

   test_first();
   test_perfect();
   test_powers();
   test_big();

   return boost::report_errors();
}


text:
// generate by pypp
// original source code: ISOBMFF/URL.hpp

#include <boost/python.hpp>

#include "ISOBMFF/URL.hpp"

void init_ISOBMFF_URL_hpp() {
    boost::python::class_<ISOBMFF::URL, boost::python::bases<ISOBMFF::FullBox>, std::shared_ptr<ISOBMFF::URL>>("URL")
        ;
}

max_stars_repo_name: mugwort-rc/python-ISOBMFF

max_issues_repo_name: mugwort-rc/python-ISOBMFF

max_forks_repo_name: mugwort-rc/python-ISOBMFF


text:
// Distributed under the MIT License.
// See LICENSE.txt for details.

#pragma once

#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/control/expr_iif.hpp>
#include <boost/preprocessor/list/adt.hpp>
#include <boost/preprocessor/repetition/for.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/tuple/to_list.hpp>
#include <limits>
#include <pup.h>
#include <vector>

#include "DataStructures/Tensor/TypeAliases.hpp"
#include "Options/Options.hpp"
#include "Parallel/CharmPupable.hpp"
#include "PointwiseFunctions/Hydro/EquationsOfState/EquationOfState.hpp"  // IWYU pragma: keep
#include "Utilities/Math.hpp"
#include "Utilities/TMPL.hpp"

/// \cond
class DataVector;

/// \endcond

// IWYU pragma: no_forward_declare Tensor

namespace EquationsOfState {

/*!
 * \ingroup EquationsOfStateGroup
 * \brief An equation of state given by parametrized enthalpy
 *
 * This equation of state is determined as a function of \f$x =
 * \ln(\rho/\rho_0)\f$ where \f$\rho\f$ is the rest mass density and
 * \f$\rho_0\f$ is the provided reference density.
 * The pseudo-enthalpy \f$h \equiv (p + rho  + u)/rho\f$
 * is expanded as
 *
 * \f{equation}
 * h(x) = \sum_i a_i x^i + \sum_j b_j \sin(jkx) + c_j \cos(jkx)
 * \f}
 *
 * This form allows for convenient calculation of thermodynamic
 * quantities for a cold equation of state. For example
 *
 * \f{equation}
 * h(x) = \frac{d e} {d \rho} |_{x = \log(\rho/\rho_0)}
 * \f}
 *
 * where \f$e\f$ is the total energy density.  At the same time \f$ dx =
 * d\rho/\rho \f$ so \f$ \rho_0 e^x dx = d \rho \f$ Therefore,
 *
 * \f{equation}
 * e(x) - e(x_0) = \int_{x_0}^x h(x') e^{x'} dx '
 * \f}
 *
 * This can be computed analytically because
 *
 * \f{equation}
 *  \int a_i \frac{x^i}{i!} e^{x} dx = \sum_{j \leq i} a_i (-1)^{i-j}
 * \frac{(x)^{j}}{j!}
 * + C \f}
 *
 * and
 *
 * \f{equation}
 * \int b_j \sin(j k x) e^x dx = b_j e^x \frac{\sin(jkx) - j k \cos(jkx)}{j^2
 * k^2 + 1} \f}
 *
 * \f{equation}
 * \int c_j \cos(j k x) e^x dx = b_j e^x \frac{\cos(jkx) + j k \sin(jkx)}{j^2
 * k^2 + 1} \f}
 *
 * From this most other thermodynamic quantities can be computed
 * analytically
 *
 * The internal energy density
 * \f{equation}
 * \epsilon(x)\rho(x) = e(x)  - \rho(x)
 * \f}
 *
 * The pressure
 * \f{equation}
 * p(x) = \rho(x) h(x) - e(x)
 * \f}
 *
 * The derivative of the pressure with respect to the rest mass density
 * \f{equation}
 * \chi(x) = \frac{dp}{d\rho} |_{x = x(\rho)} = \frac{dh}{dx}
 * \f}
 *
 * Below the minimum density, a spectral parameterization
 * is used.
 *
 *
 *
 */
template <typename LowDensityEoS>
class Enthalpy : public EquationOfState<true, 1> {
 private:
  struct Coefficients {
    std::vector<double> polynomial_coefficients;
    std::vector<double> sin_coefficients;
    std::vector<double> cos_coefficients;
    double trig_scale;
    double reference_density;
    bool has_exponential_prefactor;
    double exponential_external_constant;
    Coefficients() = default;
    ~Coefficients() = default;
    Coefficients(const Coefficients& coefficients) = default;
    Coefficients(std::vector<double> in_polynomial_coefficients,
                 std::vector<double> in_sin_coefficients,
                 std::vector<double> in_cos_coefficients, double in_trig_scale,
                 double in_reference_density,
                 double in_exponential_constant =
                     std::numeric_limits<double>::quiet_NaN());

    Enthalpy<LowDensityEoS>::Coefficients compute_exponential_integral(
        const std::pair<double, double>& initial_condition);
    Enthalpy<LowDensityEoS>::Coefficients compute_derivative();
    void pup(PUP::er& p);
  };

 public:
  static constexpr size_t thermodynamic_dim = 1;
  static constexpr bool is_relativistic = true;

  struct ReferenceDensity {
    using type = double;
    static constexpr Options::String help = {"Reference density rho_0"};
    static double lower_bound() { return 0.0; }
  };

  struct MinimumDensity {
    using type = double;
    static constexpr Options::String help = {
        "Minimum valid density rho_min,"
        " for this parametrization"};
    static double lower_bound() { return 0.0; }
  };
  struct MaximumDensity {
    using type = double;
    static constexpr Options::String help = {"Maximum density for this EoS"};
    static double lower_bound() { return 0.0; }
  };

  struct PolynomialCoefficients {
    using type = std::vector<double>;
    static constexpr Options::String help = {"Polynomial coefficients a_i"};
  };

  struct TrigScaling {
    using type = double;
    static constexpr Options::String help = {
        "Fundamental wavenumber of trig "
        "functions, k"};
    static double lower_bound() { return 0.0; }
  };

  struct SinCoefficients {
    using type = std::vector<double>;
    static constexpr Options::String help = {"Sine coefficients b_j"};
  };
  struct CosCoefficients {
    using type = std::vector<double>;
    static constexpr Options::String help = {"Cosine coefficients c_j"};
  };
  struct StitchedLowDensityEoS {
    using type = LowDensityEoS;
    static std::string name() {
      return pretty_type::short_name<LowDensityEoS>();
    }
    static constexpr Options::String help = {
        "Low density EoS stitched at the MinimumDensity"};
  };

  struct TransitionDeltaEpsilon {
    using type = double;
    static constexpr Options::String help = {
        "the change in internal energy across the low-"
        "to-high-density transition, generically 0.0"};
    static double lower_bound() { return 0.0; }
  };

  static constexpr Options::String help = {
      "An EoS with a parametrized value h(log(rho/rho_0)) with h the specific "
      "enthalpy and rho the baryon rest mass density.  The enthalpy is "
      "expanded as a sum of polynomial terms and trigonometric corrections. "
      "let x = log(rho/rho_0) in"
      "h(x) = \\sum_i a_ix^i + \\sum_j b_jsin(k * j * x) + c_jcos(k * j * x) "
      "Note that rho(x)(1+epsilon(x)) = int_0^x e^x' h((x') dx' can be "
      "computed "
      "analytically, and therefore so can "
      "P(x) = rho(x) * (h(x) - (1 + epsilon(x))) "};

  using options =
      tmpl::list<ReferenceDensity, MaximumDensity, MinimumDensity, TrigScaling,
                 PolynomialCoefficients, SinCoefficients, CosCoefficients,
                 StitchedLowDensityEoS, TransitionDeltaEpsilon>;

  Enthalpy() = default;
  Enthalpy(const Enthalpy&) = default;
  Enthalpy& operator=(const Enthalpy&) = default;
  Enthalpy(Enthalpy&&) = default;
  Enthalpy& operator=(Enthalpy&&) = default;
  ~Enthalpy() override = default;

  Enthalpy(double reference_density, double max_density, double min_density,
           double trig_scale,
           const std::vector<double>& polynomial_coefficients,
           const std::vector<double>& sin_coefficients,
           const std::vector<double>& cos_coefficients,
           const LowDensityEoS& low_density_eos,
           const double transition_delta_epsilon);

  EQUATION_OF_STATE_FORWARD_DECLARE_MEMBERS(Enthalpy, 1)

  WRAPPED_PUPable_decl_base_template(  // NOLINT
      SINGLE_ARG(EquationOfState<true, 1>), Enthalpy);

  /// The lower bound of the rest mass density that is valid for this EOS
  double rest_mass_density_lower_bound() const override { return 0.0; }

  /// The upper bound of the rest mass density that is valid for this EOS
  double rest_mass_density_upper_bound() const override {
    return std::numeric_limits<double>::max();
  }

  /// The lower bound of the specific internal energy that is valid for this EOS
  /// at the given rest mass density \f$\rho\f$
  double specific_internal_energy_lower_bound(
      const double /* rest_mass_density */) const override {
    return 0.0;
  }

  /// The upper bound of the specific internal energy that is valid for this EOS
  /// at the given rest mass density \f$\rho\f$
  double specific_internal_energy_upper_bound(
      const double /* rest_mass_density */) const override {
    return std::numeric_limits<double>::max();
  }

  /// The lower bound of the specific enthalpy that is valid for this EOS
  double specific_enthalpy_lower_bound() const override { return 1.0; }

 private:
  EQUATION_OF_STATE_FORWARD_DECLARE_MEMBER_IMPLS(1)

  SPECTRE_ALWAYS_INLINE
  bool in_low_density_domain(const double density) const {
    return density < minimum_density_;
  }

  double x_from_density(const double density) const;
  double density_from_x(const double x) const;
  double energy_density_from_log_density(const double x) const;
  static double evaluate_coefficients(
      const Enthalpy::Coefficients& coefficients, const double x);

  double chi_from_density(const double density) const;
  double specific_internal_energy_from_density(const double density) const;
  double specific_enthalpy_from_density(const double density) const;
  double pressure_from_density(const double density) const;
  double pressure_from_log_density(const double x) const;
  double rest_mass_density_from_enthalpy(const double specific_enthalpy) const;

  double reference_density_ = std::numeric_limits<double>::signaling_NaN();
  double minimum_density_ = std::numeric_limits<double>::signaling_NaN();
  double maximum_density_ = std::numeric_limits<double>::signaling_NaN();
  double minimum_enthalpy_ = std::numeric_limits<double>::signaling_NaN();

  LowDensityEoS low_density_eos_;
  Coefficients coefficients_;
  Coefficients exponential_integral_coefficients_;
  Coefficients derivative_coefficients_;
};

}  // namespace EquationsOfState

max_stars_repo_name: nilsvu/spectre

max_issues_repo_name: nilsvu/spectre

max_forks_repo_name: nilsvu/spectre


text:
//   Copyright 2015 Patrick Putnam
//
//   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.
#ifndef CLOTHO_CROSSOVER_GENERATOR_HPP_
#define CLOTHO_CROSSOVER_GENERATOR_HPP_

#include <boost/property_tree/ptree.hpp>

#include "clotho/utility/bit_helper.hpp"
#include "clotho/utility/debruijn_bit_walker.hpp"
#include "clotho/data_spaces/crossover/crossover_method.hpp"
#include "clotho/data_spaces/generators/crossover_event_generator.hpp"

namespace clotho {
namespace genetics {

template < class RNG, class GeneticSpaceType >
class Crossover {
public:
    typedef GeneticSpaceType    genetic_space_type;

    typedef typename genetic_space_type::allele_type        allele_type;
    typedef typename genetic_space_type::association_type   association_type;

    typedef crossover_method< RNG, allele_type, association_type >  method_type;

    typedef typename method_type::sequence_iterator             sequence_iterator;
    typedef typename method_type::genome_iterator               genome_iterator;
    typedef typename genetic_space_type::individual_id_type     individual_id_type;

    typedef std::vector< std::pair< individual_id_type, individual_id_type > >  mate_pair_type;
    typedef typename mate_pair_type::iterator                                   iterator;

    Crossover( RNG * rng, boost::property_tree::ptree & config ) :
        m_method( rng, config )
    { }

    void update( genetic_space_type * parental_genomes, mate_pair_type & parents, genetic_space_type * offspring_genomes ) {
        iterator mate_it = parents.begin(), mate_end = parents.end();

        m_method.initAlleles( parental_genomes->getAlleleSpace() );

        offspring_genomes->getSequenceSpace().clear();

        size_t i = 0;
        size_t p_step = parental_genomes->getSequenceSpace().block_column_count();
        size_t c_step = offspring_genomes->getSequenceSpace().block_column_count();
        while( mate_it != mate_end ) {

            genome_iterator start = parental_genomes->begin_genome( mate_it->first );
            genome_iterator end = parental_genomes->end_genome( mate_it->first );
            sequence_iterator c = offspring_genomes->begin_sequence( i++ );

            m_method.crossover( start, end, c, p_step, c_step );

            start = parental_genomes->begin_genome( mate_it->second );
            end = parental_genomes->end_genome( mate_it->second );
            c = offspring_genomes->begin_sequence( i++ );

            m_method.crossover( start, end, c, p_step, c_step );

            ++mate_it;
        }
    }

    virtual ~Crossover() {}

protected:
    method_type m_method;
};

}   // namespace genetics
}   // namespace clotho

#include "clotho/data_spaces/crossover/row_grouped_crossover.hpp"
#include "clotho/data_spaces/crossover/crossover_spec.hpp"

#endif  // CLOTHO_CROSSOVER_GENERATOR_HPP_

max_stars_repo_name: putnampp/clotho

max_issues_repo_name: putnampp/clotho

max_forks_repo_name: putnampp/clotho