<commit_before>/* Copyright (c) 2006, NIF File Format Library and Tools
All rights reserved.  Please see niflib.h for licence. */

#include "../../include/obj/NiNode.h"
#include "../../include/obj/NiAVObject.h"
#include "../../include/obj/NiDynamicEffect.h"
#include "../../include/obj/NiSkinInstance.h"
#include "../../include/obj/NiSkinData.h"
#include "../../include/obj/NiTriBasedGeom.h"
using namespace Niflib;

//Definition of TYPE constant
const Type NiNode::TYPE("NiNode", &NI_NODE_PARENT::TypeConst() );

NiNode::NiNode() NI_NODE_CONSTRUCT {
	//Set flag to default of 8: not a skin influence
	flags = 8;
}

NiNode::~NiNode() {
	//Unbind any attached skins - must happen before children are cleared
	for ( list<NiSkinInstance*>::iterator it = skins.begin(); it != skins.end(); ++it ) {
		(*it)->SkeletonLost();
	}

	//Clear Children
	ClearChildren();
}

void NiNode::Read( istream& in, list<unsigned int> & link_stack, unsigned int version, unsigned int user_version ) {
	InternalRead( in, link_stack, version, user_version );
}

void NiNode::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, unsigned int version, unsigned int user_version ) const {
	InternalWrite( out, link_map, version, user_version );
}

string NiNode::asString( bool verbose ) const {
	return InternalAsString( verbose );
}

void NiNode::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, unsigned int version, unsigned int user_version ) {
	InternalFixLinks( objects, link_stack, version, user_version );
	//Connect children to their parents and remove any NULL ones
	for ( vector< NiAVObjectRef >::iterator it = children.begin(); it != children.end(); ) {
		if ( *it == NULL) {
			it = children.erase( it );
		} else {
			(*it)->SetParent(this);
			++it;
		}
	}
}

list<NiObjectRef> NiNode::GetRefs() const {
	return InternalGetRefs();
}

const Type & NiNode::GetType() const {
	return TYPE;
};

void NiNode::AddChild( Ref<NiAVObject> obj ) {
	if ( obj->GetParent() != NULL ) {
		throw runtime_error( "You have attempted to add a child to a NiNode which already is the child of another NiNode." );
	}
	obj->SetParent( this );
	//Sometimes NiTriBasedGeom with skins can be siblings of NiNodes that
	//represent joints for that same skin.  This is not allowed, so we have
	//to prevent it by always adding NiTriBasedGeom to the begining of the child list.
	NiTriBasedGeomRef niGeom = DynamicCast<NiTriBasedGeom>(obj);
	if ( niGeom != NULL ) {
		//This is a NiTriBasedGeom, so shift all children to the right
		size_t old_size = children.size();
		children.resize( children.size() + 1 );
		for ( size_t i = children.size() - 1; i >= 1; --i ) {
			children[i] = children[i-1];
		}

		//Now add the new child to the begining of the list
		children[0] = obj;
	} else {
		//This is some other type of object.  Just add it to the end of the list.
		children.push_back( obj );
	}
}

void NiNode::RemoveChild( Ref<NiAVObject> obj ) {
	//Search child list for the one to remove
	for ( vector< NiAVObjectRef >::iterator it = children.begin(); it != children.end(); ) {
		if ( *it == obj ) {
			//Ensure that this child is not a skin influence
			NiNodeRef niNode = DynamicCast<NiNode>((*it));
			if ( niNode != NULL && niNode->IsSkinInfluence() == true ) {
				throw runtime_error("You cannot remove a node child that is a skin influence.  Detatch the skin first.");
			}
			(*it)->SetParent(NULL);
			it = children.erase( it );
		} else {
			++it;
		}
	}
}

void NiNode::ClearChildren() {
	for ( vector< NiAVObjectRef >::iterator it = children.begin(); it != children.end(); ++it) {
		if ( *it != NULL ) {
			(*it)->SetParent(NULL);
		}
	}
	children.clear();
}

vector< Ref<NiAVObject> > NiNode::GetChildren() const {
	return children;
}

void NiNode::AddEffect( Ref<NiDynamicEffect> obj ) {
   obj->SetParent( this );
   effects.push_back( obj );
}

void NiNode::RemoveEffect( Ref<NiDynamicEffect> obj ) {
   //Search Effect list for the one to remove
   for ( vector< NiDynamicEffectRef >::iterator it = effects.begin(); it != effects.end(); ) {
      if ( *it == obj ) {
         (*it)->SetParent(NULL);
         it = effects.erase( it );
      } else {
         ++it;
      }
   }
}

void NiNode::ClearEffects() {
   for ( vector< NiDynamicEffectRef >::iterator it = effects.begin(); it != effects.end(); ++it) {
      if (*it) (*it)->SetParent(NULL);
   }
   effects.clear();
}

vector< Ref<NiDynamicEffect> > NiNode::GetEffects() const {
   return effects;
}

bool NiNode::IsSkeletonRoot() const {
	return ( skins.size() > 0 );
}

bool NiNode::IsSkinInfluence() const {
	return ((flags & 8) == 0);
}

void NiNode::AddSkin( NiSkinInstance * skin_inst ) {
	skins.push_back( skin_inst );
}

void NiNode::RemoveSkin( NiSkinInstance * skin_inst ) {
	//Remove the reference
	skins.remove( skin_inst);

	//Ensure that any multiply referenced bone nodes still
	//have their skin flag set
	vector<NiNodeRef> bones;
	for ( list<NiSkinInstance*>::iterator it = skins.begin(); it != skins.end(); ++it ) {
		bones = (*it)->GetBones();
		for ( unsigned int i = 0; i < bones.size(); ++i ) {
			bones[i]->SetSkinFlag(true);
		}
	}
}

void NiNode::SetSkinFlag( bool n ) {
	if ( IsSkinInfluence() == n ) {
		//Already set to the requested value
		return;
	} else {
		//Requested value is different, flip bit
		flags ^= 8;
	}
}

void NiNode::GoToSkeletonBindPosition() {
	//map<NiNodeRef, Matrix44> world_positions;

	//Loop through all attached skins, straightening the skeleton on each
	for ( list<NiSkinInstance*>::iterator it = skins.begin(); it != skins.end(); ++it ) {
		//Get Bone list and Skin Data
		vector<NiNodeRef> bone_nodes = (*it)->GetBones();
		NiSkinDataRef skin_data = (*it)->GetSkinData();

		if ( skin_data == NULL ) {
			//There's no skin data for this skin instance; skip it.
			continue;
		}

		//Make sure the counts match
		if ( bone_nodes.size() != skin_data->GetBoneCount() ) {
			throw runtime_error( "Bone counts in NiSkinInstance and attached NiSkinData must match" );
		}

		//Loop through all bones influencing this skin
		for ( unsigned int i = 0; i < bone_nodes.size(); ++i ) {
			//Get current offset Matrix for this bone
			Matrix44 parent_offset = skin_data->GetBoneTransform(i);

			//Loop through all bones again, checking for any that have this bone as a parent
			for ( unsigned int j = 0; j < bone_nodes.size(); ++j ) {
				if ( bone_nodes[j]->GetParent() == bone_nodes[i] ) {
					//Node 2 has node 1 as a parent

					//Get child offset Matrix33
					Matrix44 child_offset = skin_data->GetBoneTransform(j);

					//Do calculation to get correct bone postion in relation to parent
					Matrix44 child_pos = child_offset.Inverse() * parent_offset;

					//bones[j]->SetWorldBindPos( child_pos );
					bone_nodes[j]->SetLocalRotation( child_pos.GetRotation() );
					bone_nodes[j]->SetLocalScale( 1.0f );
					bone_nodes[j]->SetLocalTranslation( child_pos.GetTranslation() );
				}
			}
		}
	}
}

void NiNode::PropagateTransform() {

	Matrix44 par_trans = this->GetLocalTransform();

	//Loop through each child and apply this node's transform to it
	for ( unsigned i = 0; i < children.size(); ++i ) {
		children[i]->SetLocalTransform(
			children[i]->GetLocalTransform() * par_trans
		);
	}

	//Nowthat the transforms have been propogated, clear them out
	this->SetLocalTransform( Matrix44::Identity() );
}

bool NiNode::IsSplitMeshProxy() const {
	//Let us guess that a node is a split mesh proxy if:
	// 1)  It is not a skin influence
	// 2)  All its children are NiTriBasedGeom derived objects.
	// 3)  All its children have identity transforms.
	// 4)  It has more than one child
	// 5)  All meshes are visible
	// 6)  ????  May need more criteria as time goes on.

	if ( this->IsSkinInfluence() ) {
		return false;
	}

	if ( children.size() < 2 ) {
		return false;
	}

	for ( unsigned i = 0; i < children.size(); ++i ) {
		if ( children[i]->IsDerivedType( NiTriBasedGeom::TypeConst() ) == false ) {
			return false;
		}
		if ( children[i]->GetLocalTransform() != Matrix44::Identity() ) {
			return false;
		}
		if ( children[i]->GetVisibility() == false ) {
			return false;
		}
	}

	//Made it all the way through the loop without returning false
	return true;
}

const Type & NiNode::TypeConst() {
	return TYPE;
}
<commit_msg>Fixed description of NiNode child order fix in comment.<commit_after>/* Copyright (c) 2006, NIF File Format Library and Tools
All rights reserved.  Please see niflib.h for licence. */

#include "../../include/obj/NiNode.h"
#include "../../include/obj/NiAVObject.h"
#include "../../include/obj/NiDynamicEffect.h"
#include "../../include/obj/NiSkinInstance.h"
#include "../../include/obj/NiSkinData.h"
#include "../../include/obj/NiTriBasedGeom.h"
using namespace Niflib;

//Definition of TYPE constant
const Type NiNode::TYPE("NiNode", &NI_NODE_PARENT::TypeConst() );

NiNode::NiNode() NI_NODE_CONSTRUCT {
	//Set flag to default of 8: not a skin influence
	flags = 8;
}

NiNode::~NiNode() {
	//Unbind any attached skins - must happen before children are cleared
	for ( list<NiSkinInstance*>::iterator it = skins.begin(); it != skins.end(); ++it ) {
		(*it)->SkeletonLost();
	}

	//Clear Children
	ClearChildren();
}

void NiNode::Read( istream& in, list<unsigned int> & link_stack, unsigned int version, unsigned int user_version ) {
	InternalRead( in, link_stack, version, user_version );
}

void NiNode::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, unsigned int version, unsigned int user_version ) const {
	InternalWrite( out, link_map, version, user_version );
}

string NiNode::asString( bool verbose ) const {
	return InternalAsString( verbose );
}

void NiNode::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, unsigned int version, unsigned int user_version ) {
	InternalFixLinks( objects, link_stack, version, user_version );
	//Connect children to their parents and remove any NULL ones
	for ( vector< NiAVObjectRef >::iterator it = children.begin(); it != children.end(); ) {
		if ( *it == NULL) {
			it = children.erase( it );
		} else {
			(*it)->SetParent(this);
			++it;
		}
	}
}

list<NiObjectRef> NiNode::GetRefs() const {
	return InternalGetRefs();
}

const Type & NiNode::GetType() const {
	return TYPE;
};

void NiNode::AddChild( Ref<NiAVObject> obj ) {
	if ( obj->GetParent() != NULL ) {
		throw runtime_error( "You have attempted to add a child to a NiNode which already is the child of another NiNode." );
	}
	obj->SetParent( this );
	//Sometimes NiTriBasedGeom with skins can be siblings of NiNodes that
	//represent joints for that same skin.  When this is the case, NiTriBasedGeom
	//must com first, so we enforce that by always adding NiTriBasedGeom to the
	//begining of the child list.
	NiTriBasedGeomRef niGeom = DynamicCast<NiTriBasedGeom>(obj);
	if ( niGeom != NULL ) {
		//This is a NiTriBasedGeom, so shift all children to the right
		size_t old_size = children.size();
		children.resize( children.size() + 1 );
		for ( size_t i = children.size() - 1; i >= 1; --i ) {
			children[i] = children[i-1];
		}

		//Now add the new child to the begining of the list
		children[0] = obj;
	} else {
		//This is some other type of object.  Just add it to the end of the list.
		children.push_back( obj );
	}
}

void NiNode::RemoveChild( Ref<NiAVObject> obj ) {
	//Search child list for the one to remove
	for ( vector< NiAVObjectRef >::iterator it = children.begin(); it != children.end(); ) {
		if ( *it == obj ) {
			//Ensure that this child is not a skin influence
			NiNodeRef niNode = DynamicCast<NiNode>((*it));
			if ( niNode != NULL && niNode->IsSkinInfluence() == true ) {
				throw runtime_error("You cannot remove a node child that is a skin influence.  Detatch the skin first.");
			}
			(*it)->SetParent(NULL);
			it = children.erase( it );
		} else {
			++it;
		}
	}
}

void NiNode::ClearChildren() {
	for ( vector< NiAVObjectRef >::iterator it = children.begin(); it != children.end(); ++it) {
		if ( *it != NULL ) {
			(*it)->SetParent(NULL);
		}
	}
	children.clear();
}

vector< Ref<NiAVObject> > NiNode::GetChildren() const {
	return children;
}

void NiNode::AddEffect( Ref<NiDynamicEffect> obj ) {
   obj->SetParent( this );
   effects.push_back( obj );
}

void NiNode::RemoveEffect( Ref<NiDynamicEffect> obj ) {
   //Search Effect list for the one to remove
   for ( vector< NiDynamicEffectRef >::iterator it = effects.begin(); it != effects.end(); ) {
      if ( *it == obj ) {
         (*it)->SetParent(NULL);
         it = effects.erase( it );
      } else {
         ++it;
      }
   }
}

void NiNode::ClearEffects() {
   for ( vector< NiDynamicEffectRef >::iterator it = effects.begin(); it != effects.end(); ++it) {
      if (*it) (*it)->SetParent(NULL);
   }
   effects.clear();
}

vector< Ref<NiDynamicEffect> > NiNode::GetEffects() const {
   return effects;
}

bool NiNode::IsSkeletonRoot() const {
	return ( skins.size() > 0 );
}

bool NiNode::IsSkinInfluence() const {
	return ((flags & 8) == 0);
}

void NiNode::AddSkin( NiSkinInstance * skin_inst ) {
	skins.push_back( skin_inst );
}

void NiNode::RemoveSkin( NiSkinInstance * skin_inst ) {
	//Remove the reference
	skins.remove( skin_inst);

	//Ensure that any multiply referenced bone nodes still
	//have their skin flag set
	vector<NiNodeRef> bones;
	for ( list<NiSkinInstance*>::iterator it = skins.begin(); it != skins.end(); ++it ) {
		bones = (*it)->GetBones();
		for ( unsigned int i = 0; i < bones.size(); ++i ) {
			bones[i]->SetSkinFlag(true);
		}
	}
}

void NiNode::SetSkinFlag( bool n ) {
	if ( IsSkinInfluence() == n ) {
		//Already set to the requested value
		return;
	} else {
		//Requested value is different, flip bit
		flags ^= 8;
	}
}

void NiNode::GoToSkeletonBindPosition() {
	//map<NiNodeRef, Matrix44> world_positions;

	//Loop through all attached skins, straightening the skeleton on each
	for ( list<NiSkinInstance*>::iterator it = skins.begin(); it != skins.end(); ++it ) {
		//Get Bone list and Skin Data
		vector<NiNodeRef> bone_nodes = (*it)->GetBones();
		NiSkinDataRef skin_data = (*it)->GetSkinData();

		if ( skin_data == NULL ) {
			//There's no skin data for this skin instance; skip it.
			continue;
		}

		//Make sure the counts match
		if ( bone_nodes.size() != skin_data->GetBoneCount() ) {
			throw runtime_error( "Bone counts in NiSkinInstance and attached NiSkinData must match" );
		}

		//Loop through all bones influencing this skin
		for ( unsigned int i = 0; i < bone_nodes.size(); ++i ) {
			//Get current offset Matrix for this bone
			Matrix44 parent_offset = skin_data->GetBoneTransform(i);

			//Loop through all bones again, checking for any that have this bone as a parent
			for ( unsigned int j = 0; j < bone_nodes.size(); ++j ) {
				if ( bone_nodes[j]->GetParent() == bone_nodes[i] ) {
					//Node 2 has node 1 as a parent

					//Get child offset Matrix33
					Matrix44 child_offset = skin_data->GetBoneTransform(j);

					//Do calculation to get correct bone postion in relation to parent
					Matrix44 child_pos = child_offset.Inverse() * parent_offset;

					//bones[j]->SetWorldBindPos( child_pos );
					bone_nodes[j]->SetLocalRotation( child_pos.GetRotation() );
					bone_nodes[j]->SetLocalScale( 1.0f );
					bone_nodes[j]->SetLocalTranslation( child_pos.GetTranslation() );
				}
			}
		}
	}
}

void NiNode::PropagateTransform() {

	Matrix44 par_trans = this->GetLocalTransform();

	//Loop through each child and apply this node's transform to it
	for ( unsigned i = 0; i < children.size(); ++i ) {
		children[i]->SetLocalTransform(
			children[i]->GetLocalTransform() * par_trans
		);
	}

	//Nowthat the transforms have been propogated, clear them out
	this->SetLocalTransform( Matrix44::Identity() );
}

bool NiNode::IsSplitMeshProxy() const {
	//Let us guess that a node is a split mesh proxy if:
	// 1)  It is not a skin influence
	// 2)  All its children are NiTriBasedGeom derived objects.
	// 3)  All its children have identity transforms.
	// 4)  It has more than one child
	// 5)  All meshes are visible
	// 6)  ????  May need more criteria as time goes on.

	if ( this->IsSkinInfluence() ) {
		return false;
	}

	if ( children.size() < 2 ) {
		return false;
	}

	for ( unsigned i = 0; i < children.size(); ++i ) {
		if ( children[i]->IsDerivedType( NiTriBasedGeom::TypeConst() ) == false ) {
			return false;
		}
		if ( children[i]->GetLocalTransform() != Matrix44::Identity() ) {
			return false;
		}
		if ( children[i]->GetVisibility() == false ) {
			return false;
		}
	}

	//Made it all the way through the loop without returning false
	return true;
}

const Type & NiNode::TypeConst() {
	return TYPE;
}
<|endoftext|>


<commit_before>/**
 ** \file object/code-class.cc
 ** \brief Creation of the URBI object code.
 */

#include <libport/lexical-cast.hh>

#include <ast/function.hh>
#include <ast/print.hh>

#include <object/code.hh>
#include <object/list.hh>
#include <object/string.hh>
#include <object/object.hh>
#include <object/urbi-exception.hh>

#include <runner/runner.hh>

namespace object
{
  rObject code_class;

  Code::Code()
  {
    throw PrimitiveError(SYMBOL(clone),
			 "`Code' objects cannot be cloned");
  }

  Code::Code(ast_type a)
    : ast_(a)
    , captures_()
    , self_()
    , call_()
  {
    assert(code_class);
    proto_add(code_class);
  }

  Code::Code(rCode model)
    : ast_(model->ast_)
    , captures_(model->captures_)
    , self_(model->self_)
    , call_(model->call_)
  {
    proto_add(model);
  }

  Code::ast_type Code::ast_get() const
  {
    return ast_;
  }

  rObject Code::call_get() const
  {
    return call_;
  }

  const Code::captures_type& Code::captures_get() const
  {
    return captures_;
  }

  rObject Code::self_get() const
  {
    return self_;
  }

  Code::ast_type& Code::ast_get()
  {
    return ast_;
  }

  rObject& Code::call_get()
  {
    return call_;
  }

  Code::captures_type& Code::captures_get()
  {
    return captures_;
  }

  rObject& Code::self_get()
  {
    return self_;
  }

  rObject Code::apply(runner::Runner& r, rList args)
  {
    if (args->value_get().empty())
      throw PrimitiveError(SYMBOL(apply),
                           "list of arguments must begin with this");
    List::value_type a = args->value_get();
    rObject tgt = a.front();
    a.pop_front();
    return r.apply(tgt, this, SYMBOL(apply), a);
  }

  std::string Code::as_string(rObject what)
  {
    if (what.get() == code_class.get())
      return SYMBOL(LT_Code_GT);
    type_check<Code>(what, SYMBOL(asString));
    return string_cast(*what->as<Code>()->ast_get());

  }

  std::string Code::body_string()
  {
    if (code_class == this)
      return SYMBOL(LT_Code_GT);
    return
      string_cast(*ast_->body_get()->body_get());
  }

  std::ostream& Code::special_slots_dump(std::ostream& o,
                                         runner::Runner&) const
  {
    o << "value: " << *ast_get() << libport::iendl;
    return o;
  }

  void Code::initialize(CxxObject::Binder<Code>& bind)
  {
    bind(SYMBOL(apply), &Code::apply);
    bind(SYMBOL(asString), &Code::as_string);
    bind(SYMBOL(bodyString), &Code::body_string);
  }

  std::string Code::type_name_get() const
  {
    return type_name;
  }

  bool Code::code_added = CxxObject::add<Code>("Code", code_class);
  const std::string Code::type_name = "Code";

}; // namespace object
<commit_msg>Print Code special slot like other slots.<commit_after>/**
 ** \file object/code-class.cc
 ** \brief Creation of the URBI object code.
 */

#include <libport/lexical-cast.hh>

#include <ast/function.hh>
#include <ast/print.hh>

#include <object/code.hh>
#include <object/list.hh>
#include <object/string.hh>
#include <object/object.hh>
#include <object/urbi-exception.hh>

#include <runner/runner.hh>

namespace object
{
  rObject code_class;

  Code::Code()
  {
    throw PrimitiveError(SYMBOL(clone),
			 "`Code' objects cannot be cloned");
  }

  Code::Code(ast_type a)
    : ast_(a)
    , captures_()
    , self_()
    , call_()
  {
    assert(code_class);
    proto_add(code_class);
  }

  Code::Code(rCode model)
    : ast_(model->ast_)
    , captures_(model->captures_)
    , self_(model->self_)
    , call_(model->call_)
  {
    proto_add(model);
  }

  Code::ast_type Code::ast_get() const
  {
    return ast_;
  }

  rObject Code::call_get() const
  {
    return call_;
  }

  const Code::captures_type& Code::captures_get() const
  {
    return captures_;
  }

  rObject Code::self_get() const
  {
    return self_;
  }

  Code::ast_type& Code::ast_get()
  {
    return ast_;
  }

  rObject& Code::call_get()
  {
    return call_;
  }

  Code::captures_type& Code::captures_get()
  {
    return captures_;
  }

  rObject& Code::self_get()
  {
    return self_;
  }

  rObject Code::apply(runner::Runner& r, rList args)
  {
    if (args->value_get().empty())
      throw PrimitiveError(SYMBOL(apply),
                           "list of arguments must begin with this");
    List::value_type a = args->value_get();
    rObject tgt = a.front();
    a.pop_front();
    return r.apply(tgt, this, SYMBOL(apply), a);
  }

  std::string Code::as_string(rObject what)
  {
    if (what.get() == code_class.get())
      return SYMBOL(LT_Code_GT);
    type_check<Code>(what, SYMBOL(asString));
    return string_cast(*what->as<Code>()->ast_get());

  }

  std::string Code::body_string()
  {
    if (code_class == this)
      return SYMBOL(LT_Code_GT);
    return
      string_cast(*ast_->body_get()->body_get());
  }

  std::ostream& Code::special_slots_dump(std::ostream& o,
                                         runner::Runner&) const
  {
    o << "value = " << *ast_get() << libport::iendl;
    return o;
  }

  void Code::initialize(CxxObject::Binder<Code>& bind)
  {
    bind(SYMBOL(apply), &Code::apply);
    bind(SYMBOL(asString), &Code::as_string);
    bind(SYMBOL(bodyString), &Code::body_string);
  }

  std::string Code::type_name_get() const
  {
    return type_name;
  }

  bool Code::code_added = CxxObject::add<Code>("Code", code_class);
  const std::string Code::type_name = "Code";

}; // namespace object
<|endoftext|>


<commit_before>// ----------------------------------------------------------------------
//
//  Arbiter: Base class for Matrix and Round Robin Arbiter
//
// ----------------------------------------------------------------------

#include "arbiter.hpp"

#include <assert.h>

using namespace std ;

Arbiter::Arbiter()
  : _input_size(0), _request(0), _num_reqs(0), _last_req(-1) {
}

Arbiter::~Arbiter() {
  if ( _request )
    delete[] _request ;
}

void Arbiter::Init( int size ) {
  _input_size = size;
  _request    = new entry_t [size] ;
  for ( int i = 0 ; i < size ; i++ )
    _request[i].valid = false ;
}

void Arbiter::AddRequest( int input, int id, int pri ) {
  assert( 0 <= input && input < _input_size ) ;
  _num_reqs++ ;
  _last_req = input ;
  _request[input].valid = true ;
  _request[input].id = id ;
  _request[input].pri = pri ;

}
<commit_msg>handle case where multiple requests for the same port are added<commit_after>// ----------------------------------------------------------------------
//
//  Arbiter: Base class for Matrix and Round Robin Arbiter
//
// ----------------------------------------------------------------------

#include "arbiter.hpp"

#include <assert.h>

using namespace std ;

Arbiter::Arbiter()
  : _input_size(0), _request(0), _num_reqs(0), _last_req(-1) {
}

Arbiter::~Arbiter() {
  if ( _request )
    delete[] _request ;
}

void Arbiter::Init( int size ) {
  _input_size = size;
  _request    = new entry_t [size] ;
  for ( int i = 0 ; i < size ; i++ )
    _request[i].valid = false ;
}

void Arbiter::AddRequest( int input, int id, int pri ) {
  assert( 0 <= input && input < _input_size ) ;
  _last_req = input ;
  if(!_request[input].valid) {
    _num_reqs++ ;
    _request[input].valid = true ;
  }
  _request[input].id = id ;
  _request[input].pri = pri ;

}
<|endoftext|>


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

#include "base/bitunion.hh"

namespace ArmISA
{
    enum ConditionCode {
        COND_EQ  =   0,
        COND_NE, //  1
        COND_CS, //  2
        COND_CC, //  3
        COND_MI, //  4
        COND_PL, //  5
        COND_VS, //  6
        COND_VC, //  7
        COND_HI, //  8
        COND_LS, //  9
        COND_GE, // 10
        COND_LT, // 11
        COND_GT, // 12
        COND_LE, // 13
        COND_AL, // 14
        COND_UC  // 15
    };

    enum MiscRegIndex {
        MISCREG_CPSR = 0,
        MISCREG_SPSR,
        MISCREG_SPSR_FIQ,
        MISCREG_SPSR_IRQ,
        MISCREG_SPSR_SVC,
        MISCREG_SPSR_MON,
        MISCREG_SPSR_UND,
        MISCREG_SPSR_ABT,
        MISCREG_FPSR,
        MISCREG_FPSID,
        MISCREG_FPSCR,
        MISCREG_FPEXC,

        // CP15 registers
        MISCREG_CP15_START,
        MISCREG_SCTLR = MISCREG_CP15_START,
        MISCREG_DCCISW,
        MISCREG_DCCIMVAC,
        MISCREG_CONTEXTIDR,
        MISCREG_TPIDRURW,
        MISCREG_TPIDRURO,
        MISCREG_TPIDRPRW,
        MISCREG_CP15ISB,
        MISCREG_CP15DSB,
        MISCREG_CP15DMB,
        MISCREG_CPACR,
        MISCREG_CLIDR,
        MISCREG_ICIALLUIS,
        MISCREG_CP15_UNIMP_START,
        MISCREG_CTR = MISCREG_CP15_UNIMP_START,
        MISCREG_TCMTR,
        MISCREG_MPUIR,
        MISCREG_MPIDR,
        MISCREG_MIDR,
        MISCREG_ID_PFR0,
        MISCREG_ID_PFR1,
        MISCREG_ID_DFR0,
        MISCREG_ID_AFR0,
        MISCREG_ID_MMFR0,
        MISCREG_ID_MMFR1,
        MISCREG_ID_MMFR2,
        MISCREG_ID_MMFR3,
        MISCREG_ID_ISAR0,
        MISCREG_ID_ISAR1,
        MISCREG_ID_ISAR2,
        MISCREG_ID_ISAR3,
        MISCREG_ID_ISAR4,
        MISCREG_ID_ISAR5,
        MISCREG_CCSIDR,
        MISCREG_AIDR,
        MISCREG_CSSELR,
        MISCREG_ACTLR,
        MISCREG_DFSR,
        MISCREG_IFSR,
        MISCREG_ADFSR,
        MISCREG_AIFSR,
        MISCREG_DFAR,
        MISCREG_IFAR,
        MISCREG_DRBAR,
        MISCREG_IRBAR,
        MISCREG_DRSR,
        MISCREG_IRSR,
        MISCREG_DRACR,
        MISCREG_IRACR,
        MISCREG_RGNR,
        MISCREG_BPIALLIS,
        MISCREG_ICIALLU,
        MISCREG_ICIMVAU,
        MISCREG_BPIALL,
        MISCREG_BPIMVA,
        MISCREG_DCIMVAC,
        MISCREG_DCISW,
        MISCREG_DCCMVAC,
        MISCREG_MCCSW,
        MISCREG_DCCMVAU,

        MISCREG_CP15_END,

        // Dummy indices
        MISCREG_NOP = MISCREG_CP15_END,
        MISCREG_RAZ,

        NUM_MISCREGS
    };

    MiscRegIndex decodeCP15Reg(unsigned crn, unsigned opc1,
                               unsigned crm, unsigned opc2);

    const char * const miscRegName[NUM_MISCREGS] = {
        "cpsr", "spsr", "spsr_fiq", "spsr_irq", "spsr_svc",
        "spsr_mon", "spsr_und", "spsr_abt",
        "fpsr", "fpsid", "fpscr", "fpexc",
        "sctlr", "dccisw", "dccimvac",
        "contextidr", "tpidrurw", "tpidruro", "tpidrprw",
        "cp15isb", "cp15dsb", "cp15dmb", "cpacr", "clidr", "icialluis",
        "ctr", "tcmtr", "mpuir", "mpidr", "midr",
        "id_pfr0", "id_pfr1", "id_dfr0", "id_afr0",
        "id_mmfr0", "id_mmfr1", "id_mmfr2", "id_mmfr3",
        "id_isar0", "id_isar1", "id_isar2", "id_isar3", "id_isar4", "id_isar5",
        "ccsidr", "aidr", "csselr", "actlr",
        "dfsr", "ifsr", "adfsr", "aifsr", "dfar", "ifar",
        "drbar", "irbar", "drsr", "irsr", "dracr", "iracr",
        "rgnr", "bpiallis", "iciallu", "icimvau",
        "bpiall", "bpimva", "dcimvac", "dcisw", "dccmvac", "mccsw",
        "dccmvau",
        "nop", "raz"
    };

    BitUnion32(CPSR)
        Bitfield<31> n;
        Bitfield<30> z;
        Bitfield<29> c;
        Bitfield<28> v;
        Bitfield<27> q;
        Bitfield<26,25> it1;
        Bitfield<24> j;
        Bitfield<19, 16> ge;
        Bitfield<15,10> it2;
        Bitfield<9> e;
        Bitfield<8> a;
        Bitfield<7> i;
        Bitfield<6> f;
        Bitfield<5> t;
        Bitfield<4, 0> mode;
    EndBitUnion(CPSR)

    // This mask selects bits of the CPSR that actually go in the CondCodes
    // integer register to allow renaming.
    static const uint32_t CondCodesMask = 0xF80F0000;

    // These otherwise unused bits of the PC are used to select a mode
    // like the J and T bits of the CPSR.
    static const Addr PcJBitShift = 33;
    static const Addr PcTBitShift = 34;
    static const Addr PcModeMask = (ULL(1) << PcJBitShift) |
                                   (ULL(1) << PcTBitShift);

    BitUnion32(SCTLR)
        Bitfield<30> te;  // Thumb Exception Enable
        Bitfield<29> afe; // Access flag enable
        Bitfield<28> tre; // TEX Remap bit
        Bitfield<27> nmfi;// Non-maskable fast interrupts enable
        Bitfield<25> ee;  // Exception Endianness bit
        Bitfield<24> ve;  // Interrupt vectors enable
        Bitfield<23> rao1;// Read as one
        Bitfield<22> u;   // Alignment (now unused)
        Bitfield<21> fi;  // Fast interrupts configuration enable
        Bitfield<18> rao2;// Read as one
        Bitfield<17> ha;  // Hardware access flag enable
        Bitfield<16> rao3;// Read as one
        Bitfield<14> rr;  // Round robin cache replacement
        Bitfield<13> v;   // Base address for exception vectors
        Bitfield<12> i;   // instruction cache enable
        Bitfield<11> z;   // branch prediction enable bit
        Bitfield<10> sw;  // Enable swp/swpb
        Bitfield<6,3> rao4;// Read as one
        Bitfield<7>  b;   // Endianness support (unused)
        Bitfield<2>  c;   // Cache enable bit
        Bitfield<1>  a;   // Alignment fault checking
        Bitfield<0>  m;   // MMU enable bit
    EndBitUnion(SCTLR)
};

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

#include "base/bitunion.hh"

namespace ArmISA
{
    enum ConditionCode {
        COND_EQ  =   0,
        COND_NE, //  1
        COND_CS, //  2
        COND_CC, //  3
        COND_MI, //  4
        COND_PL, //  5
        COND_VS, //  6
        COND_VC, //  7
        COND_HI, //  8
        COND_LS, //  9
        COND_GE, // 10
        COND_LT, // 11
        COND_GT, // 12
        COND_LE, // 13
        COND_AL, // 14
        COND_UC  // 15
    };

    enum MiscRegIndex {
        MISCREG_CPSR = 0,
        MISCREG_SPSR,
        MISCREG_SPSR_FIQ,
        MISCREG_SPSR_IRQ,
        MISCREG_SPSR_SVC,
        MISCREG_SPSR_MON,
        MISCREG_SPSR_UND,
        MISCREG_SPSR_ABT,
        MISCREG_FPSR,
        MISCREG_FPSID,
        MISCREG_FPSCR,
        MISCREG_FPEXC,

        // CP15 registers
        MISCREG_CP15_START,
        MISCREG_SCTLR = MISCREG_CP15_START,
        MISCREG_DCCISW,
        MISCREG_DCCIMVAC,
        MISCREG_CONTEXTIDR,
        MISCREG_TPIDRURW,
        MISCREG_TPIDRURO,
        MISCREG_TPIDRPRW,
        MISCREG_CP15ISB,
        MISCREG_CP15DSB,
        MISCREG_CP15DMB,
        MISCREG_CPACR,
        MISCREG_CLIDR,
        MISCREG_ICIALLUIS,
        MISCREG_ICIALLU,
        MISCREG_CP15_UNIMP_START,
        MISCREG_CTR = MISCREG_CP15_UNIMP_START,
        MISCREG_TCMTR,
        MISCREG_MPUIR,
        MISCREG_MPIDR,
        MISCREG_MIDR,
        MISCREG_ID_PFR0,
        MISCREG_ID_PFR1,
        MISCREG_ID_DFR0,
        MISCREG_ID_AFR0,
        MISCREG_ID_MMFR0,
        MISCREG_ID_MMFR1,
        MISCREG_ID_MMFR2,
        MISCREG_ID_MMFR3,
        MISCREG_ID_ISAR0,
        MISCREG_ID_ISAR1,
        MISCREG_ID_ISAR2,
        MISCREG_ID_ISAR3,
        MISCREG_ID_ISAR4,
        MISCREG_ID_ISAR5,
        MISCREG_CCSIDR,
        MISCREG_AIDR,
        MISCREG_CSSELR,
        MISCREG_ACTLR,
        MISCREG_DFSR,
        MISCREG_IFSR,
        MISCREG_ADFSR,
        MISCREG_AIFSR,
        MISCREG_DFAR,
        MISCREG_IFAR,
        MISCREG_DRBAR,
        MISCREG_IRBAR,
        MISCREG_DRSR,
        MISCREG_IRSR,
        MISCREG_DRACR,
        MISCREG_IRACR,
        MISCREG_RGNR,
        MISCREG_BPIALLIS,
        MISCREG_ICIMVAU,
        MISCREG_BPIALL,
        MISCREG_BPIMVA,
        MISCREG_DCIMVAC,
        MISCREG_DCISW,
        MISCREG_DCCMVAC,
        MISCREG_MCCSW,
        MISCREG_DCCMVAU,

        MISCREG_CP15_END,

        // Dummy indices
        MISCREG_NOP = MISCREG_CP15_END,
        MISCREG_RAZ,

        NUM_MISCREGS
    };

    MiscRegIndex decodeCP15Reg(unsigned crn, unsigned opc1,
                               unsigned crm, unsigned opc2);

    const char * const miscRegName[NUM_MISCREGS] = {
        "cpsr", "spsr", "spsr_fiq", "spsr_irq", "spsr_svc",
        "spsr_mon", "spsr_und", "spsr_abt",
        "fpsr", "fpsid", "fpscr", "fpexc",
        "sctlr", "dccisw", "dccimvac",
        "contextidr", "tpidrurw", "tpidruro", "tpidrprw",
        "cp15isb", "cp15dsb", "cp15dmb", "cpacr", "clidr",
        "icialluis", "iciallu",
        "ctr", "tcmtr", "mpuir", "mpidr", "midr",
        "id_pfr0", "id_pfr1", "id_dfr0", "id_afr0",
        "id_mmfr0", "id_mmfr1", "id_mmfr2", "id_mmfr3",
        "id_isar0", "id_isar1", "id_isar2", "id_isar3", "id_isar4", "id_isar5",
        "ccsidr", "aidr", "csselr", "actlr",
        "dfsr", "ifsr", "adfsr", "aifsr", "dfar", "ifar",
        "drbar", "irbar", "drsr", "irsr", "dracr", "iracr",
        "rgnr", "bpiallis", "icimvau",
        "bpiall", "bpimva", "dcimvac", "dcisw", "dccmvac", "mccsw",
        "dccmvau",
        "nop", "raz"
    };

    BitUnion32(CPSR)
        Bitfield<31> n;
        Bitfield<30> z;
        Bitfield<29> c;
        Bitfield<28> v;
        Bitfield<27> q;
        Bitfield<26,25> it1;
        Bitfield<24> j;
        Bitfield<19, 16> ge;
        Bitfield<15,10> it2;
        Bitfield<9> e;
        Bitfield<8> a;
        Bitfield<7> i;
        Bitfield<6> f;
        Bitfield<5> t;
        Bitfield<4, 0> mode;
    EndBitUnion(CPSR)

    // This mask selects bits of the CPSR that actually go in the CondCodes
    // integer register to allow renaming.
    static const uint32_t CondCodesMask = 0xF80F0000;

    // These otherwise unused bits of the PC are used to select a mode
    // like the J and T bits of the CPSR.
    static const Addr PcJBitShift = 33;
    static const Addr PcTBitShift = 34;
    static const Addr PcModeMask = (ULL(1) << PcJBitShift) |
                                   (ULL(1) << PcTBitShift);

    BitUnion32(SCTLR)
        Bitfield<30> te;  // Thumb Exception Enable
        Bitfield<29> afe; // Access flag enable
        Bitfield<28> tre; // TEX Remap bit
        Bitfield<27> nmfi;// Non-maskable fast interrupts enable
        Bitfield<25> ee;  // Exception Endianness bit
        Bitfield<24> ve;  // Interrupt vectors enable
        Bitfield<23> rao1;// Read as one
        Bitfield<22> u;   // Alignment (now unused)
        Bitfield<21> fi;  // Fast interrupts configuration enable
        Bitfield<18> rao2;// Read as one
        Bitfield<17> ha;  // Hardware access flag enable
        Bitfield<16> rao3;// Read as one
        Bitfield<14> rr;  // Round robin cache replacement
        Bitfield<13> v;   // Base address for exception vectors
        Bitfield<12> i;   // instruction cache enable
        Bitfield<11> z;   // branch prediction enable bit
        Bitfield<10> sw;  // Enable swp/swpb
        Bitfield<6,3> rao4;// Read as one
        Bitfield<7>  b;   // Endianness support (unused)
        Bitfield<2>  c;   // Cache enable bit
        Bitfield<1>  a;   // Alignment fault checking
        Bitfield<0>  m;   // MMU enable bit
    EndBitUnion(SCTLR)
};

#endif // __ARCH_ARM_MISCREGS_HH__
<|endoftext|>


<commit_before>#include <af/defines.h>
#include <af/blas.h>
#include <Array.hpp>
#ifdef __APPLE__
#include <Accelerate/Accelerate.h>
#else
#include <cblas.h>
#endif

namespace cpu
{

template<typename T>
Array<T>* matmul(const Array<T> &lhs, const Array<T> &rhs,
                    af_blas_transpose optLhs, af_blas_transpose optRhs);
template<typename T>
Array<T>* dot(const Array<T> &lhs, const Array<T> &rhs,
                    af_blas_transpose optLhs, af_blas_transpose optRhs);

}
<commit_msg>Change required to make blas compile on centos 6<commit_after>#include <af/defines.h>
#include <af/blas.h>
#include <Array.hpp>
#ifdef __APPLE__
#include <Accelerate/Accelerate.h>
#else
extern "C" {
#include <cblas.h>
}
#endif

namespace cpu
{

template<typename T>
Array<T>* matmul(const Array<T> &lhs, const Array<T> &rhs,
                    af_blas_transpose optLhs, af_blas_transpose optRhs);
template<typename T>
Array<T>* dot(const Array<T> &lhs, const Array<T> &rhs,
                    af_blas_transpose optLhs, af_blas_transpose optRhs);

}
<|endoftext|>


<commit_before>/*
    Copyright (C) 2013  David Edmundson (davidedmundson@kde.org)

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

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

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "persondata.h"

#include "metacontact_p.h"
#include "personmanager_p.h"
#include "personpluginmanager.h"
#include "basepersonsdatasource.h"
#include "contactmonitor.h"

#include <QDebug>

namespace KPeople {
    class PersonDataPrivate {
    public:
        QStringList contactIds;
        MetaContact metaContact;
        QList<ContactMonitorPtr> watchers;
    };
}

using namespace KPeople;

KPeople::PersonData::PersonData(const QString &id, QObject* parent):
    QObject(parent),
    d_ptr(new PersonDataPrivate)
{
    Q_D(PersonData);

    QString personId;
    //query DB
    if (id.startsWith("kpeople://")) {
        personId = id;
    } else {
        personId = PersonManager::instance()->personIdForContact(id);
    }
    d->contactIds = PersonManager::instance()->contactsForPersonId(personId);

    KABC::Addressee::Map contacts;
    Q_FOREACH(BasePersonsDataSource *dataSource, PersonPluginManager::dataSourcePlugins()) {
        Q_FOREACH(const QString &contactId, d->contactIds) {
            //FIXME this is terrible.. we have to ask every datasource for the contact
            //future idea: plugins have a method of what their URIs will start with
            //then we keep plugins as a map
            ContactMonitorPtr cw = dataSource->contactMonitor(contactId);
            d->watchers << cw;
            if (!cw->contact().isEmpty()) {
                contacts[contactId] = cw->contact();
            }
            connect(cw.data(), SIGNAL(contactChanged()), SLOT(onContactChanged()));
        }
    }

    d->metaContact = MetaContact(personId, contacts);
}

PersonData::~PersonData()
{
    delete d_ptr;
}

KABC::Addressee PersonData::person() const
{
    Q_D(const PersonData);
    return d->metaContact.personAddressee();
}

KABC::AddresseeList PersonData::contacts() const
{
    Q_D(const PersonData);
    return d->metaContact.contacts();
}

void PersonData::onContactChanged()
{
    Q_D(PersonData);

    ContactMonitor *watcher = qobject_cast<ContactMonitor*>(sender());
    d->metaContact.updateContact(watcher->contactId(), watcher->contact());
    Q_EMIT dataChanged();
}
<commit_msg>Add contact id to contactIds if no person exists for that contact id<commit_after>/*
    Copyright (C) 2013  David Edmundson (davidedmundson@kde.org)

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

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

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "persondata.h"

#include "metacontact_p.h"
#include "personmanager_p.h"
#include "personpluginmanager.h"
#include "basepersonsdatasource.h"
#include "contactmonitor.h"

#include <QDebug>

namespace KPeople {
    class PersonDataPrivate {
    public:
        QStringList contactIds;
        MetaContact metaContact;
        QList<ContactMonitorPtr> watchers;
    };
}

using namespace KPeople;

KPeople::PersonData::PersonData(const QString &id, QObject* parent):
    QObject(parent),
    d_ptr(new PersonDataPrivate)
{
    Q_D(PersonData);

    QString personId;
    //query DB
    if (id.startsWith("kpeople://")) {
        personId = id;
    } else {
        personId = PersonManager::instance()->personIdForContact(id);
    }

    if (personId.isEmpty()) {
        d->contactIds = QStringList() << id;
    } else {
        d->contactIds = PersonManager::instance()->contactsForPersonId(personId);
    }

    KABC::Addressee::Map contacts;
    Q_FOREACH(BasePersonsDataSource *dataSource, PersonPluginManager::dataSourcePlugins()) {
        Q_FOREACH(const QString &contactId, d->contactIds) {
            //FIXME this is terrible.. we have to ask every datasource for the contact
            //future idea: plugins have a method of what their URIs will start with
            //then we keep plugins as a map
            ContactMonitorPtr cw = dataSource->contactMonitor(contactId);
            d->watchers << cw;
            if (!cw->contact().isEmpty()) {
                contacts[contactId] = cw->contact();
            }
            connect(cw.data(), SIGNAL(contactChanged()), SLOT(onContactChanged()));
        }
    }

    d->metaContact = MetaContact(personId, contacts);
}

PersonData::~PersonData()
{
    delete d_ptr;
}

KABC::Addressee PersonData::person() const
{
    Q_D(const PersonData);
    return d->metaContact.personAddressee();
}

KABC::AddresseeList PersonData::contacts() const
{
    Q_D(const PersonData);
    return d->metaContact.contacts();
}

void PersonData::onContactChanged()
{
    Q_D(PersonData);

    ContactMonitor *watcher = qobject_cast<ContactMonitor*>(sender());
    d->metaContact.updateContact(watcher->contactId(), watcher->contact());
    Q_EMIT dataChanged();
}
<|endoftext|>


<commit_before>#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
#include <cxxopts.hpp>
#pragma clang diagnostic pop

#include "constants.hpp"
#include "dispatcher_utility.hpp"
#include "karabiner_version.h"
#include "logger.hpp"
#include "monitor/configuration_monitor.hpp"
#include <iostream>
#include <pqrs/thread_wait.hpp>
#include <spdlog/sinks/stdout_color_sinks.h>

namespace {
void select_profile(const std::string& name) {
  auto wait = pqrs::make_thread_wait();
  krbn::configuration_monitor monitor(krbn::constants::get_user_core_configuration_file_path());

  monitor.core_configuration_updated.connect([name, wait](auto&& weak_core_configuration) {
    if (auto core_configuration = weak_core_configuration.lock()) {
      auto& profiles = core_configuration->get_profiles();
      for (size_t i = 0; i < profiles.size(); ++i) {
        if (profiles[i].get_name() == name) {
          core_configuration->select_profile(i);
          core_configuration->sync_save_to_file();
          goto finish;
        }
      }
      krbn::logger::get_logger()->error("`{0}` is not found.", name);
    }

  finish:
    wait->notify();
  });

  monitor.async_start();

  wait->wait_notice();
}

int copy_current_profile_to_system_default_profile(void) {
  pqrs::filesystem::create_directory_with_intermediate_directories(krbn::constants::get_system_configuration_directory(), 0755);
  pqrs::filesystem::copy(krbn::constants::get_user_core_configuration_file_path(),
                         krbn::constants::get_system_core_configuration_file_path());
  return 0;
}

int remove_system_default_profile(void) {
  if (!pqrs::filesystem::exists(krbn::constants::get_system_core_configuration_file_path())) {
    krbn::logger::get_logger()->error("{0} is not found.", krbn::constants::get_system_core_configuration_file_path());
    return 1;
  }
  if (unlink(krbn::constants::get_system_core_configuration_file_path()) != 0) {
    krbn::logger::get_logger()->error("Failed to unlink {0}.");
    return 1;
  }
  return 0;
}
} // namespace

int main(int argc, char** argv) {
  int exit_code = 0;

  krbn::dispatcher_utility::initialize_dispatchers();

  {
    auto l = spdlog::stdout_color_mt("karabiner_cli");
    l->set_pattern("[%l] %v");
    l->set_level(spdlog::level::err);
    krbn::logger::set_logger(l);
  }

  cxxopts::Options options("karabiner_cli", "A command line utility of Karabiner-Elements.");

  options.add_options()("select-profile", "Select a profile by name.", cxxopts::value<std::string>());
  options.add_options()("copy-current-profile-to-system-default-profile", "Copy the current profile to system default profile.");
  options.add_options()("remove-system-default-profile", "Remove the system default profile.");
  options.add_options()("version", "Displays version.");
  options.add_options()("version-number", "Displays version_number.");
  options.add_options()("help", "Print help.");

  try {
    auto parse_result = options.parse(argc, argv);

    {
      std::string key = "select-profile";
      if (parse_result.count(key)) {
        select_profile(parse_result[key].as<std::string>());
        goto finish;
      }
    }

    {
      std::string key = "copy-current-profile-to-system-default-profile";
      if (parse_result.count(key)) {
        if (getuid() != 0) {
          krbn::logger::get_logger()->error("--{0} requires root privilege.", key);
          exit_code = 1;
          goto finish;
        }
        exit_code = copy_current_profile_to_system_default_profile();
        goto finish;
      }
    }

    {
      std::string key = "remove-system-default-profile";
      if (parse_result.count(key)) {
        if (getuid() != 0) {
          krbn::logger::get_logger()->error("--{0} requires root privilege.", key);
          exit_code = 1;
          goto finish;
        }
        exit_code = remove_system_default_profile();
        goto finish;
      }
    }

    {
      std::string key = "version";
      if (parse_result.count(key)) {
        std::cout << karabiner_version << std::endl;
        goto finish;
      }
    }

    {
      std::string key = "version-number";
      if (parse_result.count(key)) {
        int n = 0;
        std::string number;

        for (const auto& c : std::string_view(karabiner_version)) {
          if (c == '.') {
            if (!number.empty()) {
              n += stoi(number);
              number.clear();
            }
            n *= 100;

          } else {
            number += c;
          }
        }

        if (!number.empty()) {
          n += stoi(number);
          number.clear();
        }

        std::cout << n << std::endl;
        goto finish;
      }
    }

  } catch (const cxxopts::OptionException& e) {
    std::cout << "error parsing options: " << e.what() << std::endl;
    exit_code = 2;
    goto finish;
  }

  std::cout << options.help() << std::endl;
  std::cout << "Examples:" << std::endl;
  std::cout << "  karabiner_cli --select-profile 'Default profile'" << std::endl;
  std::cout << std::endl;

  exit_code = 1;

finish:
  krbn::dispatcher_utility::terminate_dispatchers();

  return exit_code;
}
<commit_msg>add --lint-complex-modifications to cli<commit_after>#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
#include <cxxopts.hpp>
#pragma clang diagnostic pop

#include "complex_modifications_assets_file.hpp"
#include "constants.hpp"
#include "dispatcher_utility.hpp"
#include "karabiner_version.h"
#include "logger.hpp"
#include "monitor/configuration_monitor.hpp"
#include <iostream>
#include <pqrs/thread_wait.hpp>
#include <spdlog/sinks/stdout_color_sinks.h>

namespace {
void select_profile(const std::string& name) {
  auto wait = pqrs::make_thread_wait();
  krbn::configuration_monitor monitor(krbn::constants::get_user_core_configuration_file_path());

  monitor.core_configuration_updated.connect([name, wait](auto&& weak_core_configuration) {
    if (auto core_configuration = weak_core_configuration.lock()) {
      auto& profiles = core_configuration->get_profiles();
      for (size_t i = 0; i < profiles.size(); ++i) {
        if (profiles[i].get_name() == name) {
          core_configuration->select_profile(i);
          core_configuration->sync_save_to_file();
          goto finish;
        }
      }
      krbn::logger::get_logger()->error("`{0}` is not found.", name);
    }

  finish:
    wait->notify();
  });

  monitor.async_start();

  wait->wait_notice();
}

int copy_current_profile_to_system_default_profile(void) {
  pqrs::filesystem::create_directory_with_intermediate_directories(krbn::constants::get_system_configuration_directory(), 0755);
  pqrs::filesystem::copy(krbn::constants::get_user_core_configuration_file_path(),
                         krbn::constants::get_system_core_configuration_file_path());
  return 0;
}

int remove_system_default_profile(void) {
  if (!pqrs::filesystem::exists(krbn::constants::get_system_core_configuration_file_path())) {
    krbn::logger::get_logger()->error("{0} is not found.", krbn::constants::get_system_core_configuration_file_path());
    return 1;
  }
  if (unlink(krbn::constants::get_system_core_configuration_file_path()) != 0) {
    krbn::logger::get_logger()->error("Failed to unlink {0}.");
    return 1;
  }
  return 0;
}
} // namespace

int main(int argc, char** argv) {
  int exit_code = 0;

  krbn::dispatcher_utility::initialize_dispatchers();

  {
    auto l = spdlog::stdout_color_mt("karabiner_cli");
    l->set_pattern("[%l] %v");
    l->set_level(spdlog::level::err);
    krbn::logger::set_logger(l);
  }

  cxxopts::Options options("karabiner_cli", "A command line utility of Karabiner-Elements.");

  options.add_options()("select-profile", "Select a profile by name.", cxxopts::value<std::string>());
  options.add_options()("copy-current-profile-to-system-default-profile", "Copy the current profile to system default profile.");
  options.add_options()("remove-system-default-profile", "Remove the system default profile.");
  options.add_options()("lint-complex-modifications", "Check complex_modifications.", cxxopts::value<std::string>());
  options.add_options()("version", "Displays version.");
  options.add_options()("version-number", "Displays version_number.");
  options.add_options()("help", "Print help.");

  try {
    auto parse_result = options.parse(argc, argv);

    {
      std::string key = "select-profile";
      if (parse_result.count(key)) {
        select_profile(parse_result[key].as<std::string>());
        goto finish;
      }
    }

    {
      std::string key = "copy-current-profile-to-system-default-profile";
      if (parse_result.count(key)) {
        if (getuid() != 0) {
          krbn::logger::get_logger()->error("--{0} requires root privilege.", key);
          exit_code = 1;
          goto finish;
        }
        exit_code = copy_current_profile_to_system_default_profile();
        goto finish;
      }
    }

    {
      std::string key = "remove-system-default-profile";
      if (parse_result.count(key)) {
        if (getuid() != 0) {
          krbn::logger::get_logger()->error("--{0} requires root privilege.", key);
          exit_code = 1;
          goto finish;
        }
        exit_code = remove_system_default_profile();
        goto finish;
      }
    }

    {
      std::string key = "lint-complex-modifications";
      if (parse_result.count(key)) {
        auto file_path = parse_result[key].as<std::string>();
        try {
          auto assets_file = krbn::complex_modifications_assets_file(file_path);
          auto error_messages = assets_file.lint();
          if (error_messages.empty()) {
            std::cout << "ok" << std::endl;

          } else {
            exit_code = 1;

            for (const auto& e : error_messages) {
              std::cout << e << std::endl;
            }
          }
          goto finish;

        } catch (std::exception& e) {
          exit_code = 1;
          std::cout << e.what() << std::endl;
          goto finish;
        }
      }
    }

    {
      std::string key = "version";
      if (parse_result.count(key)) {
        std::cout << karabiner_version << std::endl;
        goto finish;
      }
    }

    {
      std::string key = "version-number";
      if (parse_result.count(key)) {
        int n = 0;
        std::string number;

        for (const auto& c : std::string_view(karabiner_version)) {
          if (c == '.') {
            if (!number.empty()) {
              n += stoi(number);
              number.clear();
            }
            n *= 100;

          } else {
            number += c;
          }
        }

        if (!number.empty()) {
          n += stoi(number);
          number.clear();
        }

        std::cout << n << std::endl;
        goto finish;
      }
    }

  } catch (const cxxopts::OptionException& e) {
    std::cout << "error parsing options: " << e.what() << std::endl;
    exit_code = 2;
    goto finish;
  }

  std::cout << options.help() << std::endl;
  std::cout << "Examples:" << std::endl;
  std::cout << "  karabiner_cli --select-profile 'Default profile'" << std::endl;
  std::cout << std::endl;

  exit_code = 1;

finish:
  krbn::dispatcher_utility::terminate_dispatchers();

  return exit_code;
}
<|endoftext|>


<commit_before>#pragma once

#include <memory>
#include <vector>

#include <boost/thread/tss.hpp>

#include "attribute.hpp"
#include "common.hpp"
#include "error/handler.hpp"
#include "filter.hpp"
#include "frontend.hpp"
#include "keyword.hpp"
#include "keyword/message.hpp"
#include "keyword/severity.hpp"
#include "keyword/thread.hpp"
#include "keyword/timestamp.hpp"
#include "keyword/tracebit.hpp"
#include "universe.hpp"
#include "utils/noncopyable.hpp"
#include "utils/unique.hpp"

#include "blackhole/config.hpp"
#include "blackhole/utils/atomic.hpp"
#include "blackhole/utils/noexcept.hpp"

namespace blackhole {

class scoped_attributes_concept_t;

template <typename Level>
struct logger_verbosity_traits {
    typedef Level level_type;

    static
    bool
    passed(level_type logger_verbosity, level_type record_verbosity) {
        typedef typename aux::underlying_type<Level>::type underlying_type;

        return static_cast<underlying_type>(record_verbosity) >=
            static_cast<underlying_type>(logger_verbosity);
    }
};

class logger_base_t {
protected:
    typedef boost::shared_mutex rw_mutex_type;
    typedef boost::shared_lock<rw_mutex_type> reader_lock_type;
    typedef boost::unique_lock<rw_mutex_type> writer_lock_type;

    struct state_t {
        std::atomic<bool> enabled;
        std::atomic<bool> tracked;

        filter_t filter;
        struct attrbutes_t {
            attribute::set_t global;
            boost::thread_specific_ptr<scoped_attributes_concept_t> scoped;

            attrbutes_t(void(*deleter)(scoped_attributes_concept_t*)) :
                scoped(deleter)
            {}
        } attributes;

        std::vector<std::unique_ptr<base_frontend_t>> frontends;
        log::exception_handler_t exception;

        struct {
            mutable rw_mutex_type open;
            mutable rw_mutex_type push;
        } lock;

        state_t();
    };
    state_t state;

    friend class scoped_attributes_concept_t;

    friend void swap(logger_base_t& lhs, logger_base_t& rhs) BLACKHOLE_NOEXCEPT;

public:
    logger_base_t();

    //! @compat GCC4.4
    //! Blaming GCC4.4 - it needs explicit move constructor definition,
    //! because it cannot define default move constructor for derived class.
    logger_base_t(logger_base_t&& other) BLACKHOLE_NOEXCEPT;
    logger_base_t& operator=(logger_base_t&& other) BLACKHOLE_NOEXCEPT;

    bool enabled() const;
    void enabled(bool enable);

    bool tracked() const;
    void tracked(bool enable);

    void set_filter(filter_t&& filter);
    void add_attribute(const attribute::pair_t& attribute);
    void add_frontend(std::unique_ptr<base_frontend_t> frontend);
    void set_exception_handler(log::exception_handler_t&& handler);

    record_t open_record() const;
    record_t open_record(attribute::pair_t attribute) const;
    record_t open_record(attribute::set_t attributes) const;

    void push(record_t&& record) const;

private:
    attribute::set_t get_event_attributes() const;
    attribute::set_t get_thread_attributes() const;
};

//!@todo: Develop ImmutableLogger class, which provides almost immutable
//!       internal state (filter, exception handler, frontends).
//!       This class won't require any synchronization mechanizm.

// NOTE: It's not movable to avoid moving to another thread.
class scoped_attributes_concept_t {
    BLACKHOLE_DECLARE_NONCOPYABLE(scoped_attributes_concept_t);

    logger_base_t *m_logger;
    scoped_attributes_concept_t *m_previous;

    friend void swap(logger_base_t&, logger_base_t&) BLACKHOLE_NOEXCEPT;

public:
    scoped_attributes_concept_t(logger_base_t& log);
    virtual ~scoped_attributes_concept_t();

    virtual const attribute::set_t& attributes() const = 0;

protected:
    bool has_parent() const;
    const scoped_attributes_concept_t& parent() const;
};

template<typename Level>
class verbose_logger_t : public logger_base_t {
public:
    typedef Level level_type;

private:
    level_type level;

public:
    verbose_logger_t() :
        logger_base_t(),
        level(static_cast<level_type>(0))
    {}

    //! @compat GCC4.4
    //! GCC 4.4 doesn't create default copy/move constructor for derived
    //! classes. It's a bug.
    verbose_logger_t(verbose_logger_t&& other) BLACKHOLE_NOEXCEPT :
        logger_base_t(std::move(other)),
        level(static_cast<level_type>(0))
    {}

    verbose_logger_t& operator=(verbose_logger_t&& other) BLACKHOLE_NOEXCEPT {
        logger_base_t::operator=(std::move(other));
        level = other.level;
        return *this;
    }

    // Explicit import other overloaded methods.
    using logger_base_t::open_record;

    /*!
     * Gets the current upper verbosity bound.
     */
    level_type verbosity() const {
        return level;
    }

    /*!
     * Sets the upper verbosity bound.
     * Every log event with a verbosity less than `level` will be dropped.
     * @param[in] level - Upper verbosity value.
     */
    void verbosity(level_type level) {
        this->level = level;
    }

    /*! @todo: Documentation is @deprecated.
     * Tries to open log record with specific verbosity level.
     * Internally this method compares desired verbosity level with the upper
     * one. Can return invalid log record if some conditions are not met.
     * @param[in] level - Desired verbosity level.
     * @return valid or invalid `record_t` object.
     */
    record_t
    open_record(level_type level,
                attribute::set_t local = attribute::set_t()) const
    {
        typedef logger_verbosity_traits<level_type> verbosity_traits;
        const bool passed = verbosity_traits::passed(this->level, level);

        bool trace = false;
        if (!passed) {
            auto it = local.find(keyword::tracebit().name());
            if (it != local.end()) {
                trace = boost::get<keyword::tag::tracebit_t::type>(it->second.value);
            } else {
                reader_lock_type lock(state.lock.open);
                if (state.attributes.scoped.get()) {
                    const auto& scoped = state.attributes.scoped->attributes();
                    auto scoped_it = scoped.find(keyword::tracebit().name());
                    if (scoped_it != scoped.end()) {
                        trace = boost::get<keyword::tag::tracebit_t::type>(
                            scoped_it->second.value
                        );
                    }
                }
            }
        }

        if (passed || trace) {
            attribute::set_t attributes = { keyword::severity<Level>() = level };
            attributes.insert(local.begin(), local.end());
            return logger_base_t::open_record(std::move(attributes));
        }

        return record_t();
    }
};

} // namespace blackhole

#if defined(BLACKHOLE_HEADER_ONLY)
#include "blackhole/logger.ipp"
#endif
<commit_msg>[Aux] Do not create temporary set just for single variable.<commit_after>#pragma once

#include <memory>
#include <vector>

#include <boost/thread/tss.hpp>

#include "attribute.hpp"
#include "common.hpp"
#include "error/handler.hpp"
#include "filter.hpp"
#include "frontend.hpp"
#include "keyword.hpp"
#include "keyword/message.hpp"
#include "keyword/severity.hpp"
#include "keyword/thread.hpp"
#include "keyword/timestamp.hpp"
#include "keyword/tracebit.hpp"
#include "universe.hpp"
#include "utils/noncopyable.hpp"
#include "utils/unique.hpp"

#include "blackhole/config.hpp"
#include "blackhole/utils/atomic.hpp"
#include "blackhole/utils/noexcept.hpp"

namespace blackhole {

class scoped_attributes_concept_t;

template <typename Level>
struct logger_verbosity_traits {
    typedef Level level_type;

    static
    bool
    passed(level_type logger_verbosity, level_type record_verbosity) {
        typedef typename aux::underlying_type<Level>::type underlying_type;

        return static_cast<underlying_type>(record_verbosity) >=
            static_cast<underlying_type>(logger_verbosity);
    }
};

class logger_base_t {
protected:
    typedef boost::shared_mutex rw_mutex_type;
    typedef boost::shared_lock<rw_mutex_type> reader_lock_type;
    typedef boost::unique_lock<rw_mutex_type> writer_lock_type;

    struct state_t {
        std::atomic<bool> enabled;
        std::atomic<bool> tracked;

        filter_t filter;
        struct attrbutes_t {
            attribute::set_t global;
            boost::thread_specific_ptr<scoped_attributes_concept_t> scoped;

            attrbutes_t(void(*deleter)(scoped_attributes_concept_t*)) :
                scoped(deleter)
            {}
        } attributes;

        std::vector<std::unique_ptr<base_frontend_t>> frontends;
        log::exception_handler_t exception;

        struct {
            mutable rw_mutex_type open;
            mutable rw_mutex_type push;
        } lock;

        state_t();
    };
    state_t state;

    friend class scoped_attributes_concept_t;

    friend void swap(logger_base_t& lhs, logger_base_t& rhs) BLACKHOLE_NOEXCEPT;

public:
    logger_base_t();

    //! @compat GCC4.4
    //! Blaming GCC4.4 - it needs explicit move constructor definition,
    //! because it cannot define default move constructor for derived class.
    logger_base_t(logger_base_t&& other) BLACKHOLE_NOEXCEPT;
    logger_base_t& operator=(logger_base_t&& other) BLACKHOLE_NOEXCEPT;

    bool enabled() const;
    void enabled(bool enable);

    bool tracked() const;
    void tracked(bool enable);

    void set_filter(filter_t&& filter);
    void add_attribute(const attribute::pair_t& attribute);
    void add_frontend(std::unique_ptr<base_frontend_t> frontend);
    void set_exception_handler(log::exception_handler_t&& handler);

    record_t open_record() const;
    record_t open_record(attribute::pair_t attribute) const;
    record_t open_record(attribute::set_t attributes) const;

    void push(record_t&& record) const;

private:
    attribute::set_t get_event_attributes() const;
    attribute::set_t get_thread_attributes() const;
};

//!@todo: Develop ImmutableLogger class, which provides almost immutable
//!       internal state (filter, exception handler, frontends).
//!       This class won't require any synchronization mechanizm.

// NOTE: It's not movable to avoid moving to another thread.
class scoped_attributes_concept_t {
    BLACKHOLE_DECLARE_NONCOPYABLE(scoped_attributes_concept_t);

    logger_base_t *m_logger;
    scoped_attributes_concept_t *m_previous;

    friend void swap(logger_base_t&, logger_base_t&) BLACKHOLE_NOEXCEPT;

public:
    scoped_attributes_concept_t(logger_base_t& log);
    virtual ~scoped_attributes_concept_t();

    virtual const attribute::set_t& attributes() const = 0;

protected:
    bool has_parent() const;
    const scoped_attributes_concept_t& parent() const;
};

template<typename Level>
class verbose_logger_t : public logger_base_t {
public:
    typedef Level level_type;

private:
    level_type level;

public:
    verbose_logger_t() :
        logger_base_t(),
        level(static_cast<level_type>(0))
    {}

    //! @compat GCC4.4
    //! GCC 4.4 doesn't create default copy/move constructor for derived
    //! classes. It's a bug.
    verbose_logger_t(verbose_logger_t&& other) BLACKHOLE_NOEXCEPT :
        logger_base_t(std::move(other)),
        level(static_cast<level_type>(0))
    {}

    verbose_logger_t& operator=(verbose_logger_t&& other) BLACKHOLE_NOEXCEPT {
        logger_base_t::operator=(std::move(other));
        level = other.level;
        return *this;
    }

    // Explicit import other overloaded methods.
    using logger_base_t::open_record;

    /*!
     * Gets the current upper verbosity bound.
     */
    level_type verbosity() const {
        return level;
    }

    /*!
     * Sets the upper verbosity bound.
     * Every log event with a verbosity less than `level` will be dropped.
     * @param[in] level - Upper verbosity value.
     */
    void verbosity(level_type level) {
        this->level = level;
    }

    /*! @todo: Documentation is @deprecated.
     * Tries to open log record with specific verbosity level.
     * Internally this method compares desired verbosity level with the upper
     * one. Can return invalid log record if some conditions are not met.
     * @param[in] level - Desired verbosity level.
     * @return valid or invalid `record_t` object.
     */
    record_t
    open_record(level_type level,
                attribute::set_t local = attribute::set_t()) const
    {
        typedef logger_verbosity_traits<level_type> verbosity_traits;
        const bool passed = verbosity_traits::passed(this->level, level);

        bool trace = false;
        if (!passed) {
            auto it = local.find(keyword::tracebit().name());
            if (it != local.end()) {
                trace = boost::get<keyword::tag::tracebit_t::type>(it->second.value);
            } else {
                reader_lock_type lock(state.lock.open);
                if (state.attributes.scoped.get()) {
                    const auto& scoped = state.attributes.scoped->attributes();
                    auto scoped_it = scoped.find(keyword::tracebit().name());
                    if (scoped_it != scoped.end()) {
                        trace = boost::get<keyword::tag::tracebit_t::type>(
                            scoped_it->second.value
                        );
                    }
                }
            }
        }

        if (passed || trace) {
            local.insert(keyword::severity<Level>() = level);
            return logger_base_t::open_record(std::move(local));
        }

        return record_t();
    }
};

} // namespace blackhole

#if defined(BLACKHOLE_HEADER_ONLY)
#include "blackhole/logger.ipp"
#endif
<|endoftext|>


<commit_before>#pragma once

#include <memory>
#include <vector>

#include <boost/thread/tss.hpp>
#include <boost/thread/shared_mutex.hpp>

#include "blackhole/attribute.hpp"
#include "blackhole/config.hpp"
#include "blackhole/detail/config/atomic.hpp"
#include "blackhole/detail/config/noncopyable.hpp"
#include "blackhole/detail/config/nullptr.hpp"
#include "blackhole/detail/thread/lock.hpp"
#include "blackhole/detail/util/unique.hpp"
#include "blackhole/error/handler.hpp"
#include "blackhole/forwards.hpp"
#include "blackhole/filter.hpp"
#include "blackhole/frontend.hpp"
#include "blackhole/keyword/message.hpp"
#include "blackhole/keyword/severity.hpp"
#include "blackhole/keyword/thread.hpp"
#include "blackhole/keyword/timestamp.hpp"
#include "blackhole/keyword/tracebit.hpp"
#include "blackhole/keyword/process.hpp"
#include "blackhole/logger/feature/scoped.hpp"

namespace blackhole {

class base_logger_t {};

template<class T, class... FilterArgs>
class composite_logger_t : public base_logger_t {
    friend class scoped_attributes_concept_t;

public:
    typedef T mixed_type;

    typedef std::function<bool(const attribute::combined_view_t&, const FilterArgs&...)> filter_type;

    typedef boost::shared_mutex rw_mutex_type;
    typedef boost::shared_lock<rw_mutex_type> reader_lock_type;
    typedef boost::unique_lock<rw_mutex_type> writer_lock_type;

    // TODO: Doc!
    typedef feature::scoped_t scoped_type;

private:
    feature::scoped_t scoped;

    struct {
        std::atomic<bool> enabled;

        filter_type filter;

        log::exception_handler_t exception;
        std::vector<std::unique_ptr<base_frontend_t>> frontends;

        struct {
            mutable rw_mutex_type open;
            mutable rw_mutex_type push;
        } lock;
    } d;

public:
    composite_logger_t(filter_type filter) {
        d.enabled = true;
        d.exception = log::default_exception_handler_t();
        d.filter = std::move(filter);
    }

    composite_logger_t(composite_logger_t&& other) {
        *this = std::move(other);
    }

    composite_logger_t& operator=(composite_logger_t&& other) {
        other.d.enabled = d.enabled.exchange(other.d.enabled);

        auto lock = detail::thread::multi_lock(d.lock.open, d.lock.push, other.d.lock.open, other.d.lock.push);

        using std::swap;
        swap(d.filter, other.d.filter);
        swap(d.frontends, other.d.frontends);

        scoped.swap(other.scoped);

        return *this;
    }

    bool enabled() const {
        return d.enabled;
    }

    void enabled(bool enable) {
        d.enabled.store(enable);
    }

    void set_filter(filter_type filter) {
        writer_lock_type lock(d.lock.open);
        d.filter = std::move(filter);
    }

    void add_frontend(std::unique_ptr<base_frontend_t> frontend) {
        writer_lock_type lock(d.lock.push);
        d.frontends.push_back(std::move(frontend));
    }

    void set_exception_handler(log::exception_handler_t handler) {
        writer_lock_type lock(d.lock.push);
        d.exception = handler;
    }

    record_t open_record(FilterArgs... args) const {
        return open_record(attribute::set_t(), std::forward<FilterArgs>(args)...);
    }

    record_t open_record(attribute::pair_t pair, FilterArgs... args) const {
        return open_record(attribute::set_t({ pair }), std::forward<FilterArgs>(args)...);
    }

    record_t open_record(attribute::set_t external, FilterArgs... args) const {
        if (!enabled()) {
            return record_t::invalid();
        }

        reader_lock_type lock(d.lock.open);
        if (!d.filter(scoped.view(external), args...)) {
            return record_t::invalid();
        }

        attribute::set_t internal;
        populate(internal);
        static_cast<const mixed_type&>(*this).populate_additional(internal, args...);

        external.reserve(BLACKHOLE_EXTERNAL_SET_RESERVED_SIZE);
        scoped.merge(external);
        return record_t(std::move(internal), std::move(external));
    }

    void push(record_t&& record) const {
        reader_lock_type lock(d.lock.push);
        for (auto it = d.frontends.begin(); it != d.frontends.end(); ++it) {
            try {
                (*it)->handle(record);
            } catch (...) {
                d.exception();
            }
        }
    }

private:
    void populate(attribute::set_t& internal) const {
        internal.reserve(BLACKHOLE_INTERNAL_SET_RESERVED_SIZE);
#ifdef BLACKHOLE_HAS_ATTRIBUTE_PID
        internal.emplace_back(keyword::pid() = keyword::init::pid());
#endif

#ifdef BLACKHOLE_HAS_ATTRIBUTE_TID
        internal.emplace_back(keyword::tid() = keyword::init::tid());
#endif

#ifdef BLACKHOLE_HAS_ATTRIBUTE_LWP
        internal.emplace_back(keyword::lwp() = keyword::init::lwp());
#endif

        internal.emplace_back(keyword::timestamp() = keyword::init::timestamp());
    }
};

class logger_base_t : public composite_logger_t<logger_base_t> {
    friend class composite_logger_t<logger_base_t>;

    typedef composite_logger_t<logger_base_t> base_type;

public:
    logger_base_t() :
        base_type(&filter::none)
    {}

#ifdef BLACKHOLE_HAS_GCC44
    logger_base_t(logger_base_t&& other) : base_type(std::move(other)) {}
    logger_base_t& operator=(logger_base_t&& other) {
        base_type::operator=(std::move(other));
        return *this;
    }
#endif

private:
    void populate_additional(attribute::set_t&) const {}
};

template<typename Level>
class verbose_logger_t : public composite_logger_t<verbose_logger_t<Level>, Level> {
    friend class composite_logger_t<verbose_logger_t<Level>, Level>;

    typedef composite_logger_t<verbose_logger_t<Level>, Level> base_type;

public:
    typedef Level level_type;
    typedef typename aux::underlying_type<level_type>::type underlying_type;

private:
    std::atomic<underlying_type> level;

public:
    verbose_logger_t(level_type level) :
        base_type(default_filter { level }),
        level(static_cast<underlying_type>(level))
    {}

    verbose_logger_t(verbose_logger_t&& other) :
        base_type(std::move(other)),
        level(other.level.load())
    {}

    verbose_logger_t& operator=(verbose_logger_t&& other) {
        base_type::operator=(std::move(other));
        level.store(other.level);
        return *this;
    }

    level_type verbosity() const {
        return static_cast<level_type>(level.load());
    }

    void set_filter(level_type level) {
        base_type::set_filter(default_filter { level });
        this->level.store(level);
    }

    void set_filter(level_type level, typename base_type::filter_type filter) {
        base_type::set_filter(std::move(filter));
        this->level.store(level);
    }

    record_t open_record(level_type level, attribute::set_t external = attribute::set_t()) const {
        return base_type::open_record(std::move(external), level);
    }

private:
    void populate_additional(attribute::set_t& internal, level_type level) const {
        internal.emplace_back(keyword::severity<level_type>() = level);
    }

    struct default_filter {
        const level_type threshold;

        inline bool operator()(const attribute::combined_view_t&, level_type level) const {
            typedef typename aux::underlying_type<level_type>::type underlying_type;
            return static_cast<underlying_type>(level) >= static_cast<underlying_type>(threshold);
        }
    };

};

} // namespace blackhole
<commit_msg>[Planning] Slightly changed my mind.<commit_after>#pragma once

#include <memory>
#include <vector>

#include <boost/thread/tss.hpp>
#include <boost/thread/shared_mutex.hpp>

#include "blackhole/attribute.hpp"
#include "blackhole/config.hpp"
#include "blackhole/detail/config/atomic.hpp"
#include "blackhole/detail/config/noncopyable.hpp"
#include "blackhole/detail/config/nullptr.hpp"
#include "blackhole/detail/thread/lock.hpp"
#include "blackhole/detail/util/unique.hpp"
#include "blackhole/error/handler.hpp"
#include "blackhole/forwards.hpp"
#include "blackhole/filter.hpp"
#include "blackhole/frontend.hpp"
#include "blackhole/keyword/message.hpp"
#include "blackhole/keyword/severity.hpp"
#include "blackhole/keyword/thread.hpp"
#include "blackhole/keyword/timestamp.hpp"
#include "blackhole/keyword/tracebit.hpp"
#include "blackhole/keyword/process.hpp"
#include "blackhole/logger/feature/scoped.hpp"

namespace blackhole {

class base_logger_t {};

template<class T, class... FilterArgs>
class composite_logger_t : public base_logger_t {
    friend class scoped_attributes_concept_t;

public:
    typedef T mixed_type;

    typedef std::function<bool(const attribute::combined_view_t&, const FilterArgs&...)> filter_type;

    typedef boost::shared_mutex rw_mutex_type;
    typedef boost::shared_lock<rw_mutex_type> reader_lock_type;
    typedef boost::unique_lock<rw_mutex_type> writer_lock_type;

    typedef feature::scoped_t scoped_type;

private:
    feature::scoped_t scoped;

    struct {
        std::atomic<bool> enabled;

        filter_type filter;

        log::exception_handler_t exception;
        std::vector<std::unique_ptr<base_frontend_t>> frontends;

        struct {
            mutable rw_mutex_type open;
            mutable rw_mutex_type push;
        } lock;
    } d;

public:
    composite_logger_t(filter_type filter) {
        d.enabled = true;
        d.exception = log::default_exception_handler_t();
        d.filter = std::move(filter);
    }

    composite_logger_t(composite_logger_t&& other) {
        *this = std::move(other);
    }

    composite_logger_t& operator=(composite_logger_t&& other) {
        other.d.enabled = d.enabled.exchange(other.d.enabled);

        auto lock = detail::thread::multi_lock(d.lock.open, d.lock.push, other.d.lock.open, other.d.lock.push);

        using std::swap;
        swap(d.filter, other.d.filter);
        swap(d.frontends, other.d.frontends);

        scoped.swap(other.scoped);

        return *this;
    }

    bool enabled() const {
        return d.enabled;
    }

    void enabled(bool enable) {
        d.enabled.store(enable);
    }

    void set_filter(filter_type filter) {
        writer_lock_type lock(d.lock.open);
        d.filter = std::move(filter);
    }

    void add_frontend(std::unique_ptr<base_frontend_t> frontend) {
        writer_lock_type lock(d.lock.push);
        d.frontends.push_back(std::move(frontend));
    }

    void set_exception_handler(log::exception_handler_t handler) {
        writer_lock_type lock(d.lock.push);
        d.exception = handler;
    }

    record_t open_record(FilterArgs... args) const {
        return open_record(attribute::set_t(), std::forward<FilterArgs>(args)...);
    }

    record_t open_record(attribute::pair_t pair, FilterArgs... args) const {
        return open_record(attribute::set_t({ pair }), std::forward<FilterArgs>(args)...);
    }

    record_t open_record(attribute::set_t external, FilterArgs... args) const {
        if (!enabled()) {
            return record_t::invalid();
        }

        reader_lock_type lock(d.lock.open);
        if (!d.filter(scoped.view(external), args...)) {
            return record_t::invalid();
        }

        attribute::set_t internal;
        populate(internal);
        static_cast<const mixed_type&>(*this).populate_additional(internal, args...);

        external.reserve(BLACKHOLE_EXTERNAL_SET_RESERVED_SIZE);
        scoped.merge(external);
        return record_t(std::move(internal), std::move(external));
    }

    void push(record_t&& record) const {
        reader_lock_type lock(d.lock.push);
        for (auto it = d.frontends.begin(); it != d.frontends.end(); ++it) {
            try {
                (*it)->handle(record);
            } catch (...) {
                d.exception();
            }
        }
    }

private:
    void populate(attribute::set_t& internal) const {
        internal.reserve(BLACKHOLE_INTERNAL_SET_RESERVED_SIZE);
#ifdef BLACKHOLE_HAS_ATTRIBUTE_PID
        internal.emplace_back(keyword::pid() = keyword::init::pid());
#endif

#ifdef BLACKHOLE_HAS_ATTRIBUTE_TID
        internal.emplace_back(keyword::tid() = keyword::init::tid());
#endif

#ifdef BLACKHOLE_HAS_ATTRIBUTE_LWP
        internal.emplace_back(keyword::lwp() = keyword::init::lwp());
#endif

        internal.emplace_back(keyword::timestamp() = keyword::init::timestamp());
    }
};

class logger_base_t : public composite_logger_t<logger_base_t> {
    friend class composite_logger_t<logger_base_t>;

    typedef composite_logger_t<logger_base_t> base_type;

public:
    logger_base_t() :
        base_type(&filter::none)
    {}

#ifdef BLACKHOLE_HAS_GCC44
    logger_base_t(logger_base_t&& other) : base_type(std::move(other)) {}
    logger_base_t& operator=(logger_base_t&& other) {
        base_type::operator=(std::move(other));
        return *this;
    }
#endif

private:
    void populate_additional(attribute::set_t&) const {}
};

template<typename Level>
class verbose_logger_t : public composite_logger_t<verbose_logger_t<Level>, Level> {
    friend class composite_logger_t<verbose_logger_t<Level>, Level>;

    typedef composite_logger_t<verbose_logger_t<Level>, Level> base_type;

public:
    typedef Level level_type;
    typedef typename aux::underlying_type<level_type>::type underlying_type;

private:
    std::atomic<underlying_type> level;

public:
    verbose_logger_t(level_type level) :
        base_type(default_filter { level }),
        level(static_cast<underlying_type>(level))
    {}

    verbose_logger_t(verbose_logger_t&& other) :
        base_type(std::move(other)),
        level(other.level.load())
    {}

    verbose_logger_t& operator=(verbose_logger_t&& other) {
        base_type::operator=(std::move(other));
        level.store(other.level);
        return *this;
    }

    level_type verbosity() const {
        return static_cast<level_type>(level.load());
    }

    void set_filter(level_type level) {
        base_type::set_filter(default_filter { level });
        this->level.store(level);
    }

    void set_filter(level_type level, typename base_type::filter_type filter) {
        base_type::set_filter(std::move(filter));
        this->level.store(level);
    }

    record_t open_record(level_type level, attribute::set_t external = attribute::set_t()) const {
        return base_type::open_record(std::move(external), level);
    }

private:
    void populate_additional(attribute::set_t& internal, level_type level) const {
        internal.emplace_back(keyword::severity<level_type>() = level);
    }

    struct default_filter {
        const level_type threshold;

        inline bool operator()(const attribute::combined_view_t&, level_type level) const {
            typedef typename aux::underlying_type<level_type>::type underlying_type;
            return static_cast<underlying_type>(level) >= static_cast<underlying_type>(threshold);
        }
    };

};

} // namespace blackhole
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <cmath>

#include "pulseTrain.hpp"

std::ostream& operator<<(std::ostream & os, const freqPulse& pulse) {
	os << "Pulse " << pulse._frequency << "MHz for " << pulse._duration << "ns with amplitude of " << pulse._amplitude;
	os << " and phase " << pulse._phase << "*pi";
	os << (pulse._markStart ? ", with " : ", without ") << "initial marker and ";
	os << (pulse._markDuration ? "with " : "without ") << "duration marker.";
	return os;
}

std::string freqPulse::markerChars(const unsigned int numPoints, unsigned int startMarkerPoints){
	std::string markerChars = "";
	markerChars.reserve(numPoints+1);

	if ( startMarkerPoints > numPoints ) startMarkerPoints = numPoints;

	if ( ! _markStart ) {
		unsigned char durationOnly = (_markDuration ? 0x01 : 0x00);
		for (unsigned int i = 0; i < numPoints; i++) markerChars += durationOnly;
	} else {
		unsigned char startPart	= (_markDuration ? 0x03 : 0x02);
		unsigned char endPart	= (_markDuration ? 0x01 : 0x00);
		unsigned int i;

		for (i = 0; i < startMarkerPoints; i++) markerChars += startPart;
		for (i = startMarkerPoints; i < numPoints; i++) markerChars += endPart;
	}

	return markerChars;
}

unsigned int freqPulse::numPoints(const double samplePeriod, const bool nearestHalfCycle) {
	if (! nearestHalfCycle) return ((unsigned int) _duration/samplePeriod);

	double halfCycles = round(_duration * _frequency * 2.0 * 0.001 /*ns*MHz*/) / 2.0;
	return (unsigned int) floor(halfCycles * (1000.0/_frequency)/samplePeriod);
}

std::string freqPulse::waveChars(const double samplePeriod, const unsigned int numPoints) {
	unsigned char waveBuffer[numPoints];
	const double TwoPi = 6.28318530717958647692; // NOT tau, that's just wrong
	const double phasePerSample = TwoPi * _frequency * samplePeriod * 0.001 /* ns * MHz*/;

	for (unsigned int i = 0; i < numPoints; i++) {
		static double point;
		point = 127.0  + (127.0 * _amplitude * sin(phasePerSample * ((double) i) + _phase));
		waveBuffer[i] = (unsigned char) round(point);
	}

	return std::string((char *) waveBuffer, numPoints);
}

std::string pulseTrain::markerChars(const double samplePeriod, const unsigned int numPoints, const bool nearestHalfCycle, const unsigned int startMarkerPoints) {
	std::string firstString  = "";
	std::string secondString = "";

	firstString.reserve(numPoints+1);
	secondString.reserve(numPoints+1);

	int shiftAmount = ((int) round(_cyclicShift/samplePeriod));
	int firstLength = ((shiftAmount >= 0) ? (numPoints - shiftAmount) : (-shiftAmount))%numPoints;

	std::deque<freqPulse>::iterator thisPulse = _pulses.begin();
	for (thisPulse = _pulses.begin(); thisPulse != _pulses.end(); thisPulse++) {
		firstString += thisPulse->markerChars(thisPulse->numPoints(samplePeriod, nearestHalfCycle), startMarkerPoints);
		if ( firstString.length() > firstLength ) {
			secondString = firstString.substr(firstLength);
			firstString = firstString.erase(firstLength);
			thisPulse++;
			break;
		}
	}

	for (; thisPulse != _pulses.end(); thisPulse++) {
		secondString += thisPulse->markerChars(thisPulse->numPoints(samplePeriod, nearestHalfCycle), startMarkerPoints);
	}

	secondString += firstString;

	return secondString;
}

std::string pulseTrain::waveChars(const double samplePeriod, const unsigned int numPoints, const bool nearestHalfCycle) {
	std::string firstString  = "";
	std::string secondString = "";

	firstString.reserve(numPoints+1);
	secondString.reserve(numPoints+1);

	int shiftAmount = ((int) round(_cyclicShift/samplePeriod));
	int firstLength = ((shiftAmount >= 0) ? (numPoints - shiftAmount) : (-shiftAmount))%numPoints;

	std::deque<freqPulse>::iterator thisPulse = _pulses.begin();
	for (thisPulse = _pulses.begin(); thisPulse != _pulses.end(); thisPulse++) {
		firstString += thisPulse->waveChars(samplePeriod, thisPulse->numPoints(samplePeriod, nearestHalfCycle));
		if ( firstString.length() > firstLength ) {
			secondString = firstString.substr(firstLength);
			firstString = firstString.erase(firstLength);
			thisPulse++;
			break;
		}
	}

	for (; thisPulse != _pulses.end(); thisPulse++) {
		secondString += thisPulse->waveChars(samplePeriod, thisPulse->numPoints(samplePeriod, nearestHalfCycle));
	}

	secondString += firstString;

	return secondString;
}

unsigned int pulseTrain::numPoints(const double samplePeriod, const bool nearestHalfCycle) {
	unsigned int totalPoints = 0;

	for (std::deque<freqPulse>::iterator thisPulse = _pulses.begin(); thisPulse != _pulses.end(); thisPulse++) {
		totalPoints += thisPulse->numPoints(samplePeriod, nearestHalfCycle);
	}

	return totalPoints;
}
<commit_msg>Add unsigned type to clear -Wsign-compare<commit_after>#include <iostream>
#include <string>
#include <cmath>

#include "pulseTrain.hpp"

std::ostream& operator<<(std::ostream & os, const freqPulse& pulse) {
	os << "Pulse " << pulse._frequency << "MHz for " << pulse._duration << "ns with amplitude of " << pulse._amplitude;
	os << " and phase " << pulse._phase << "*pi";
	os << (pulse._markStart ? ", with " : ", without ") << "initial marker and ";
	os << (pulse._markDuration ? "with " : "without ") << "duration marker.";
	return os;
}

std::string freqPulse::markerChars(const unsigned int numPoints, unsigned int startMarkerPoints){
	std::string markerChars = "";
	markerChars.reserve(numPoints+1);

	if ( startMarkerPoints > numPoints ) startMarkerPoints = numPoints;

	if ( ! _markStart ) {
		unsigned char durationOnly = (_markDuration ? 0x01 : 0x00);
		for (unsigned int i = 0; i < numPoints; i++) markerChars += durationOnly;
	} else {
		unsigned char startPart	= (_markDuration ? 0x03 : 0x02);
		unsigned char endPart	= (_markDuration ? 0x01 : 0x00);
		unsigned int i;

		for (i = 0; i < startMarkerPoints; i++) markerChars += startPart;
		for (i = startMarkerPoints; i < numPoints; i++) markerChars += endPart;
	}

	return markerChars;
}

unsigned int freqPulse::numPoints(const double samplePeriod, const bool nearestHalfCycle) {
	if (! nearestHalfCycle) return ((unsigned int) _duration/samplePeriod);

	double halfCycles = round(_duration * _frequency * 2.0 * 0.001 /*ns*MHz*/) / 2.0;
	return (unsigned int) floor(halfCycles * (1000.0/_frequency)/samplePeriod);
}

std::string freqPulse::waveChars(const double samplePeriod, const unsigned int numPoints) {
	unsigned char waveBuffer[numPoints];
	const double TwoPi = 6.28318530717958647692; // NOT tau, that's just wrong
	const double phasePerSample = TwoPi * _frequency * samplePeriod * 0.001 /* ns * MHz*/;

	for (unsigned int i = 0; i < numPoints; i++) {
		static double point;
		point = 127.0  + (127.0 * _amplitude * sin(phasePerSample * ((double) i) + _phase));
		waveBuffer[i] = (unsigned char) round(point);
	}

	return std::string((char *) waveBuffer, numPoints);
}

std::string pulseTrain::markerChars(const double samplePeriod, const unsigned int numPoints, const bool nearestHalfCycle, const unsigned int startMarkerPoints) {
	std::string firstString  = "";
	std::string secondString = "";

	firstString.reserve(numPoints+1);
	secondString.reserve(numPoints+1);

	int shiftAmount = ((int) round(_cyclicShift/samplePeriod));
	unsigned int firstLength = ((shiftAmount >= 0) ? (numPoints - shiftAmount) : (-shiftAmount))%numPoints;

	std::deque<freqPulse>::iterator thisPulse = _pulses.begin();
	for (thisPulse = _pulses.begin(); thisPulse != _pulses.end(); thisPulse++) {
		firstString += thisPulse->markerChars(thisPulse->numPoints(samplePeriod, nearestHalfCycle), startMarkerPoints);
		if ( firstString.length() > firstLength ) {
			secondString = firstString.substr(firstLength);
			firstString = firstString.erase(firstLength);
			thisPulse++;
			break;
		}
	}

	for (; thisPulse != _pulses.end(); thisPulse++) {
		secondString += thisPulse->markerChars(thisPulse->numPoints(samplePeriod, nearestHalfCycle), startMarkerPoints);
	}

	secondString += firstString;

	return secondString;
}

std::string pulseTrain::waveChars(const double samplePeriod, const unsigned int numPoints, const bool nearestHalfCycle) {
	std::string firstString  = "";
	std::string secondString = "";

	firstString.reserve(numPoints+1);
	secondString.reserve(numPoints+1);

	int shiftAmount = ((int) round(_cyclicShift/samplePeriod));
	unsigned int firstLength = ((shiftAmount >= 0) ? (numPoints - shiftAmount) : (-shiftAmount))%numPoints;

	std::deque<freqPulse>::iterator thisPulse = _pulses.begin();
	for (thisPulse = _pulses.begin(); thisPulse != _pulses.end(); thisPulse++) {
		firstString += thisPulse->waveChars(samplePeriod, thisPulse->numPoints(samplePeriod, nearestHalfCycle));
		if ( firstString.length() > firstLength ) {
			secondString = firstString.substr(firstLength);
			firstString = firstString.erase(firstLength);
			thisPulse++;
			break;
		}
	}

	for (; thisPulse != _pulses.end(); thisPulse++) {
		secondString += thisPulse->waveChars(samplePeriod, thisPulse->numPoints(samplePeriod, nearestHalfCycle));
	}

	secondString += firstString;

	return secondString;
}

unsigned int pulseTrain::numPoints(const double samplePeriod, const bool nearestHalfCycle) {
	unsigned int totalPoints = 0;

	for (std::deque<freqPulse>::iterator thisPulse = _pulses.begin(); thisPulse != _pulses.end(); thisPulse++) {
		totalPoints += thisPulse->numPoints(samplePeriod, nearestHalfCycle);
	}

	return totalPoints;
}
<|endoftext|>