Ejemplo n.º 1
0
// Construct the answer after parsing an input string
std::string answer(const std::map<std::string, coef_type, std::greater<std::string>>& tokens) {
    std::string ans;
    
    for (auto cit = tokens.cbegin(); cit != tokens.cend(); ++cit) {
        if (cit != tokens.cbegin() && cit->second > 0) {
            ans += "+";
        }
        
        if (cit->first != "1") {
            if (cit ->second > 1 || cit ->second < 1) {
                ans += std::to_string(cit->second);
                ans += "*";
            }
            ans += cit->first;
        }
        else {
            ans += std::to_string(cit->second);
        }
    }
    
    return ans;
}
Ejemplo n.º 2
0
//fills lst or const_lst  (depending on which is null) with all borrowers with specified name 
static void findByName_helper(const std::map<unsigned int, Borrower>& borrowers, const std::string name, 
	list<Borrower*const> *const lst, list<const Borrower*const> *const const_lst){

	borrowers_citer iter = borrowers.cbegin();

	while (iter != borrowers.cend())
	{
		if (iter->second.getName() == name)
		{
			const_lst == NULL ? lst->push_back(const_cast<Borrower*>(&iter->second)) : const_lst->push_back(&iter->second);
		}
		iter++;
	}
}
Ejemplo n.º 3
0
std::string optionsToString(std::map<std::string, std::string> const &options) {
  if (!options.empty()) {
    std::ostringstream resultStream;
    auto optionsKvpIt = options.cbegin();
    auto const &firstKvp = (*optionsKvpIt);
    resultStream << firstKvp.first << "='" << firstKvp.second << '\'';
    for (; optionsKvpIt != options.cend(); ++optionsKvpIt) {
      auto kvp = (*optionsKvpIt);
      resultStream << ", " << kvp.first << "='" << kvp.second << '\'';
    }
    return resultStream.str();
  } else {
    return std::string();
  }
}
Ejemplo n.º 4
0
int MeshInfoSet::InitializeMeshNeiboNum(const std::map<MeshPair, int>& meshPair, std::map<int, std::vector<std::pair<int, int>>>& meshNeiboNum)
{
	int rtn = 0;
	meshNeiboNum.clear();
	for (map<MeshPair, int>::const_iterator it = meshPair.cbegin(); it != meshPair.cend(); ++it)
	{
		rtn = AddMeshNeiboNum(it->first.first, it->first.second, it->second, meshNeiboNum);
		CHECK_RTN(rtn);
		rtn = AddMeshNeiboNum(it->first.second, it->first.first, it->second, meshNeiboNum);
		CHECK_RTN(rtn);
	}
	for (map<int, vector<pair<int, int>>>::iterator it = meshNeiboNum.begin(); it != meshNeiboNum.end(); ++it)
		sort(it->second.begin(), it->second.end(), CmpPairByLagerSecond<int, int>);
	return 0;
}
Ejemplo n.º 5
0
// assuming the namenode id is 0
void GetServerIDsFromHostMap(std::vector<int32_t> *server_ids,
    const std::map<int32_t, HostInfo>& host_map){
  
  int32_t num_servers = host_map.size() - 1;
  server_ids->resize(num_servers);
  int32_t i = 0;

  for (auto host_info_iter = host_map.cbegin();
    host_info_iter != host_map.cend(); host_info_iter++) {
    if (host_info_iter->first == 0)
      continue;
    (*server_ids)[i] = host_info_iter->first;
    ++i;
  }
}
Ejemplo n.º 6
0
/**
 * Function: wakeSleepingThreads
 * Iterates over all threads alive and wakes them up if needed.
 * If a thread is awaken it is added to the READY list.
 */
void wakeSleepingThreads()
{
	uthread *curr;
	// Add waking threads to READY list
	for (auto th=livingThreads.cbegin(); th != livingThreads.cend(); ++th)
	{
		// curr is the current thread in the for loop
		curr = th->second;
		// If the thread is sleeping and it should wake up, wake it up
		if (curr->get_state() == uthread::state::SLEEPING &&
		    uthread_get_time_until_wakeup(curr->get_id())==SHOULD_WAKE)
		{
			curr->set_state(uthread::state::READY);
			readyThreads.push_back(curr->get_id());
		}
	}
}
Ejemplo n.º 7
0
    void garbage_collection()
    {
        for (auto i = rx_pkt_queue.cbegin(); i != rx_pkt_queue.cend(); /* NO INCREMENT*/)
        {
            if (i->second->id <= last_fw_id)
            {
#ifdef VERBOSE
                printf("Erasing pkt with id=%u, last_fw_id %u\n", i->first, last_fw_id);
#endif
                rx_pkt_queue.erase(i++);
            }
            else
            {
                ++i;
            }
        }
    }
Ejemplo n.º 8
0
bool check_types(const std::map<std::string, uint16_t>& expected) {
  // holds the type names we see at runtime
  std::map<std::string, uint16_t> found;
  // fetch all available type names
  auto types = uniform_type_info::instances();
  for (auto tinfo : types) {
    found.insert(std::make_pair(tinfo->name(), tinfo->type_nr()));
  }
  // compare the two maps
  if (expected == found) {
    CAF_CHECKPOINT();
    return true;
  }
  CAF_CHECK(false);
  using const_iterator = std::map<std::string, uint16_t>::const_iterator;
  using std::setw;
  using std::left;
  std::ostringstream oss;
  oss << left << setw(20) << ("found (" + tostr(found.size(), 1) + ")")
      << "  |  expected (" << expected.size() << ")";
  CAF_PRINT(oss.str());
  oss.seekp(0);
  oss << std::setfill('-') << setw(22) << "" << "|" << setw(22) << "";
  CAF_PRINT(oss.str());
  auto fi = found.cbegin();
  auto fe = found.cend();
  auto ei = expected.cbegin();
  auto ee = expected.cend();
  std::string dummy(20, ' ');
  auto out = [&](const_iterator& i, const_iterator last) -> std::string {
    if (i == last) {
      return dummy;
    }
    std::ostringstream tmp;
    tmp << left << setw(16) << i->first << "[" << tostr(i->second) << "]";
    ++i;
    return tmp.str();
  };
  while (fi != fe || ei != ee) {
    CAF_PRINT(out(fi, fe) << "  |  " << out(ei, ee));
  }
  return false;
}
Ejemplo n.º 9
0
void check_martialarts()
{
    for( auto style = martialarts.cbegin(); style != martialarts.cend(); ++style ) {
        for( auto technique = style->second.techniques.cbegin();
             technique != style->second.techniques.cend(); ++technique ) {
            if( ma_techniques.find( *technique ) == ma_techniques.end() ) {
                debugmsg( "Technique with id %s in style %s doesn't exist.",
                          technique->c_str(), style->second.name.c_str() );
            }
        }
        for( auto weapon = style->second.weapons.cbegin();
             weapon != style->second.weapons.cend(); ++weapon ) {
            if( !item::type_is_defined( *weapon ) ) {
                debugmsg( "Weapon %s in style %s doesn't exist.",
                          weapon->c_str(), style->second.name.c_str() );
            }
        }
    }
}
Ejemplo n.º 10
0
Archivo: main.cpp Proyecto: CCJY/coliru
int main()
{
    const std::map< int, std::vector<double> > map =
    {
        { 247, { 1.2, 2.3, 3.4, 4.5 } },
        { 106, { 5.6, 6.7, 7.8, 8.9, 9.1, 1.2, 2.3 } },
        { 184, { 3.4, 4.5 } }
    };

    {
        // option 1: range-based loops
        for( const auto& pair : map )
        {
            std::cout << "key: " << pair.first << "  value: [  " ;
            for( double d : pair.second ) std::cout << d << "  " ;
            std::cout << "]\n" ;
        }
    }
    std::cout << "----------------\n" ;
    {
        // option 2: iterators
        for( auto map_iter = map.cbegin() ; map_iter != map.cend() ; ++map_iter )
        {
            std::cout << "key: " << map_iter->first << "  value: [  " ;
            for( auto vec_iter = map_iter->second.cbegin() ; vec_iter != map_iter->second.cend() ; ++vec_iter )
                std::cout << *vec_iter << "  " ;
            std::cout << "]\n" ;
        }
    }
    std::cout << "----------------\n" ;
    {
        // option 3: range-based loop for map, subscript operator for vector
        for( const auto& pair : map )
        {
            std::cout << "key: " << pair.first << "  value: [  " ;
            for( std::size_t i = 0 ; i < pair.second.size() ; ++i )  std::cout << pair.second[i] << "  " ;
            std::cout << "]\n" ;
        }
    }
    
    // options 4, 5 ...
}
Ejemplo n.º 11
0
DRAWABLE_PTR_CONTAINER_TEMPLATE_CPP
const model_map	ModelData::readModelList(GLFWwindow* window, const std::map<std::string, std::string>& fileNamesAndPaths, const DescriptorType descType){
	model_map models;
	std::map<std::string, std::string>::const_iterator it;

	// Start to asynchronously load models
	for (it = fileNamesAndPaths.cbegin(); it != fileNamesAndPaths.cend(); ++it){
		models.emplace(it->first, new ModelData(it->second, false, descType)); // Do not create voxel space, also
	}

	// Wait for individual models to load
	std::map<std::string, ModelData*>::const_iterator m_i;
	for (m_i = models.cbegin(); m_i != models.cend(); ++m_i){
		Framework::GL::initObjectToDraw(m_i->second, window);
	}

	Framework::ModelUtils::updateModelTransforms(models);

	return models;
}
Ejemplo n.º 12
0
static std::string GetLanguageString(DiscIO::IVolume::ELanguage language, std::map<DiscIO::IVolume::ELanguage, std::string> strings)
{
	auto end = strings.end();
	auto it = strings.find(language);
	if (it != end)
		return it->second;

	// English tends to be a good fallback when the requested language isn't available
	if (language != DiscIO::IVolume::ELanguage::LANGUAGE_ENGLISH)
	{
		it = strings.find(DiscIO::IVolume::ELanguage::LANGUAGE_ENGLISH);
		if (it != end)
			return it->second;
	}

	// If English isn't available either, just pick something
	if (!strings.empty())
		return strings.cbegin()->second;

	return "";
}
Ejemplo n.º 13
0
/*
 * Description: This function creates a new thread, whose entry point is the
 * function f with the signature void f(void). The thread is added to the end
 * of the READY threads list. The uthread_spawn function should fail if it
 * would cause the number of concurrent threads to exceed the limit
 * (MAX_THREAD_NUM). Each thread should be allocated with a stack of size
 * STACK_SIZE bytes.
 * Return value: On success, return the ID of the created thread.
 * On failure, return -1.
*/
int uthread_spawn(void (*f)(void))
{
	// If the current number of threads is MAX_THREAD_NUM, no
	// more threads can be spawned.
	if (livingThreads.size() >= MAX_THREAD_NUM)
	{
		std::cerr << LIB_ERROR_MSG << "Number of threads exceeded "
			  << "the maximum number allowed." << std::endl;
		return EXIT_FAIL;
	}

	// Block SIGTVALRM signal
	sigset_t oldSet;
	blockSignal(SIGVTALRM, &oldSet);

	// Find the smallest id available, starting from MAIN_ID + 1.
	uthread::id newId = MAIN_THREAD_ID + 1;
	for (auto it = ++livingThreads.cbegin(); /* start from the second */
		  it != livingThreads.cend();
		++it)
	{
		if (newId < it->first)
		{
			// If the threads ids numbering doesn't match natural
			// incremental numbering, we found an empty spot.
			break;
		}
		++newId;
	}

	// Create a fresh thread with the found id and entry function f
	// Then put it in the living threads list and READY list.
	uthread *newThread = new uthread(newId, f);
	livingThreads.insert(std::make_pair(newId, newThread));
	readyThreads.push_back(newId);

	// Unblock SIGVTALRM and return
	resetSigMask(&oldSet);
	return newId;
}
Ejemplo n.º 14
0
/******************************************************************************
* Determines the the display particle radii.
******************************************************************************/
void ParticleDisplay::particleRadii(std::vector<FloatType>& output, ParticlePropertyObject* radiusProperty, ParticleTypeProperty* typeProperty)
{
	OVITO_ASSERT(radiusProperty == nullptr || radiusProperty->type() == ParticleProperty::RadiusProperty);
	OVITO_ASSERT(typeProperty == nullptr || typeProperty->type() == ParticleProperty::ParticleTypeProperty);

	if(radiusProperty) {
		// Take particle radii directly from the radius property.
		OVITO_ASSERT(radiusProperty->size() == output.size());
		std::copy(radiusProperty->constDataFloat(), radiusProperty->constDataFloat() + output.size(), output.begin());
	}
	else if(typeProperty) {
		// Assign radii based on particle types.
		OVITO_ASSERT(typeProperty->size() == output.size());
		// Build a lookup map for particle type radii.
		const std::map<int,FloatType> radiusMap = typeProperty->radiusMap();
		// Skip the following loop if all per-type radii are zero. In this case, simply use the default radius for all particles.
		if(std::any_of(radiusMap.cbegin(), radiusMap.cend(), [](const std::pair<int,FloatType>& it) { return it.second != 0; })) {
			// Fill radius array.
			const int* t = typeProperty->constDataInt();
			for(auto c = output.begin(); c != output.end(); ++c, ++t) {
				auto it = radiusMap.find(*t);
				// Set particle radius only if the type's radius is non-zero.
				if(it != radiusMap.end() && it->second != 0)
					*c = it->second;
			}
		}
		else {
			// Assign a constant radius to all particles.
			std::fill(output.begin(), output.end(), defaultParticleRadius());
		}
	}
	else {
		// Assign a constant radius to all particles.
		std::fill(output.begin(), output.end(), defaultParticleRadius());
	}
}
Ejemplo n.º 15
0
int main()
{
    {
        typedef std::pair<const int, double> V;
        V ar[] =
        {
            V(1, 1),
            V(1, 1.5),
            V(1, 2),
            V(2, 1),
            V(2, 1.5),
            V(2, 2),
            V(3, 1),
            V(3, 1.5),
            V(3, 2),
            V(4, 1),
            V(4, 1.5),
            V(4, 2),
            V(5, 1),
            V(5, 1.5),
            V(5, 2),
            V(6, 1),
            V(6, 1.5),
            V(6, 2),
            V(7, 1),
            V(7, 1.5),
            V(7, 2),
            V(8, 1),
            V(8, 1.5),
            V(8, 2)
        };
        std::map<int, double> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
        assert(std::distance(m.begin(), m.end()) == m.size());
        assert(std::distance(m.rbegin(), m.rend()) == m.size());
        std::map<int, double>::iterator i;
        i = m.begin();
        std::map<int, double>::const_iterator k = i;
        assert(i == k);
        for (int j = 1; j <= m.size(); ++j, ++i)
        {
            assert(i->first == j);
            assert(i->second == 1);
            i->second = 2.5;
            assert(i->second == 2.5);
        }
    }
    {
        typedef std::pair<const int, double> V;
        V ar[] =
        {
            V(1, 1),
            V(1, 1.5),
            V(1, 2),
            V(2, 1),
            V(2, 1.5),
            V(2, 2),
            V(3, 1),
            V(3, 1.5),
            V(3, 2),
            V(4, 1),
            V(4, 1.5),
            V(4, 2),
            V(5, 1),
            V(5, 1.5),
            V(5, 2),
            V(6, 1),
            V(6, 1.5),
            V(6, 2),
            V(7, 1),
            V(7, 1.5),
            V(7, 2),
            V(8, 1),
            V(8, 1.5),
            V(8, 2)
        };
        const std::map<int, double> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
        assert(std::distance(m.begin(), m.end()) == m.size());
        assert(std::distance(m.cbegin(), m.cend()) == m.size());
        assert(std::distance(m.rbegin(), m.rend()) == m.size());
        assert(std::distance(m.crbegin(), m.crend()) == m.size());
        std::map<int, double>::const_iterator i;
        i = m.begin();
        for (int j = 1; j <= m.size(); ++j, ++i)
        {
            assert(i->first == j);
            assert(i->second == 1);
        }
    }
#if __cplusplus >= 201103L || defined(_LIBCPP_MSVC)
    {
        typedef std::pair<const int, double> V;
        V ar[] =
        {
            V(1, 1),
            V(1, 1.5),
            V(1, 2),
            V(2, 1),
            V(2, 1.5),
            V(2, 2),
            V(3, 1),
            V(3, 1.5),
            V(3, 2),
            V(4, 1),
            V(4, 1.5),
            V(4, 2),
            V(5, 1),
            V(5, 1.5),
            V(5, 2),
            V(6, 1),
            V(6, 1.5),
            V(6, 2),
            V(7, 1),
            V(7, 1.5),
            V(7, 2),
            V(8, 1),
            V(8, 1.5),
            V(8, 2)
        };
        std::map<int, double, std::less<int>, min_allocator<V>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
        assert(std::distance(m.begin(), m.end()) == m.size());
        assert(std::distance(m.rbegin(), m.rend()) == m.size());
        std::map<int, double, std::less<int>, min_allocator<V>>::iterator i;
        i = m.begin();
        std::map<int, double, std::less<int>, min_allocator<V>>::const_iterator k = i;
        assert(i == k);
        for (int j = 1; j <= m.size(); ++j, ++i)
        {
            assert(i->first == j);
            assert(i->second == 1);
            i->second = 2.5;
            assert(i->second == 2.5);
        }
    }
    {
        typedef std::pair<const int, double> V;
        V ar[] =
        {
            V(1, 1),
            V(1, 1.5),
            V(1, 2),
            V(2, 1),
            V(2, 1.5),
            V(2, 2),
            V(3, 1),
            V(3, 1.5),
            V(3, 2),
            V(4, 1),
            V(4, 1.5),
            V(4, 2),
            V(5, 1),
            V(5, 1.5),
            V(5, 2),
            V(6, 1),
            V(6, 1.5),
            V(6, 2),
            V(7, 1),
            V(7, 1.5),
            V(7, 2),
            V(8, 1),
            V(8, 1.5),
            V(8, 2)
        };
        const std::map<int, double, std::less<int>, min_allocator<V>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
        assert(std::distance(m.begin(), m.end()) == m.size());
        assert(std::distance(m.cbegin(), m.cend()) == m.size());
        assert(std::distance(m.rbegin(), m.rend()) == m.size());
        assert(std::distance(m.crbegin(), m.crend()) == m.size());
        std::map<int, double, std::less<int>, min_allocator<V>>::const_iterator i;
        i = m.begin();
        for (int j = 1; j <= m.size(); ++j, ++i)
        {
            assert(i->first == j);
            assert(i->second == 1);
        }
    }
#endif
#if _LIBCPP_STD_VER > 11
    { // N3644 testing
        typedef std::map<int, double> C;
        C::iterator ii1{}, ii2{};
        C::iterator ii4 = ii1;
        C::const_iterator cii{};
        assert ( ii1 == ii2 );
        assert ( ii1 == ii4 );

        assert (!(ii1 != ii2 ));

        assert ( (ii1 == cii ));
        assert ( (cii == ii1 ));
        assert (!(ii1 != cii ));
        assert (!(cii != ii1 ));
    }
#endif
}
Ejemplo n.º 16
0
    void control::create(HWND parent, std::map<string, string>& attrs, resmgr& mgr) {
        decltype(attrs.begin()) it;

        for(auto it = attrs.cbegin(); it != attrs.cend(); it++)
            set_attr(it->first.c_str(), it->second.c_str());
    }
Ejemplo n.º 17
0
	// Must be a valid two digit code, state name, or standard state abbreviation
	Address &   Address::state(std::string     code) {

		// map containing the state codes and their names
		const std::map<std::string, std::string> states = 
		{
			{ "AL","Alabama" },
			{ "AK","Alaska" },
			{ "AZ","Arizona" },
			{ "AR","Arkansas" },
			{ "CA","California" },
			{ "CO","Colorado" },
			{ "CT","Connecticut" },
			{ "DE","Delaware" },
			{ "FL","Florida" },
			{ "GA","Georgia" },
			{ "HI","Hawaii" },
			{ "ID","Idaho" },
			{ "IL","Illinois" },
			{ "IN","Indiana" },
			{ "IA","Iowa" },
			{ "KS","Kansas" },
			{ "KY","Kentucky" },
			{ "LA","Louisiana" },
			{ "ME","Maine" },
			{ "MD","Maryland" },
			{ "MA","Massachusetts" },
			{ "MI","Michigan" },
			{ "MN","Minnesota" },
			{ "MS","Mississippi" },
			{ "MO","Missouri" },
			{ "MT","Montana" },
			{ "NE","Nebraska" },
			{ "NV","Nevada" },
			{ "NH","New Hampshire" },
			{ "NJ","New Jersey" },
			{ "NM","New Mexico" },
			{ "NY","New York" },
			{ "NC","North Carolina" },
			{ "ND","North Dakota" },
			{ "OH","Ohio" },
			{ "OK","Oklahoma" },
			{ "OR","Oregon" },
			{ "PA","Pennsylvania" },
			{ "RI","Rhode Island" },
			{ "SC","South Carolina" },
			{ "SD","South Dakota" },
			{ "TN","Tennessee" },
			{ "TX","Texas" },
			{ "UT","Utah" },
			{ "VT","Vermont" },
			{ "VA","Virginia" },
			{ "WA","Washington" },
			{ "WV","West Virginia" },
			{ "WI","Wisconsin" },
			{ "WY","Wyoming" },
			{ "DC","District of Columbia" },
		};

		// conversion functions
		auto toupper = [](char c) {
			return std::toupper(c, std::locale());
		};
		auto tolower = [](char c) {
			return std::tolower(c, std::locale());
		};

		// if the length is 2, it's an abbreviation. Look it up in the map
		if (code.length() == 2) {
			// convert to uppercase -- supports input such as "Wa" or "wa"
			std::transform(code.begin(), code.end(), code.begin(), toupper);

			std::map<std::string, std::string>::const_iterator itr = states.find(code);

			// if the key was found
			if (itr != states.cend()) {
				_state = itr->second;
			}
			// throw an exception
			else {
				throw StateCodeException("State abbreviation not valid", __LINE__, __func__, __FILE__);
			}
		}
		// it's not an abbreviation, look up the long name and make sure it's valid
		else {
			// convert to first letter capitalized, supporting input such as "WAshington" or "washington"
			std::transform(code.begin(), code.begin() + 1, code.begin(), toupper);
			std::transform(code.begin() + 1, code.end(), code.begin() + 1, tolower);

			// function to return whether or not the value matches the function parameter supplied
			auto nameExists = [code,toupper,tolower](auto value) {
				// convert the value in map to same format as code
				std::transform(value.second.begin(), value.second.begin() + 1, value.second.begin(), toupper);
				std::transform(value.second.begin() + 1, value.second.end(), value.second.begin() + 1, tolower);

				// compare
				return value.second == code;
			};

			// find the state in the map
			std::map<std::string, std::string>::const_iterator itr = std::find_if(states.cbegin(), states.cend(), nameExists);

			// the long name was found in the map
			if (itr != states.cend()) {
				_state = itr->second; // use the value pulled from the map
			}
			// throw exception
			else {
				throw StateCodeException("State name not valid", __LINE__, __func__, __FILE__);
			}
		}

		return *this;
	}
Ejemplo n.º 18
0
	inline auto cbegin() const
	{
		return __savestates.cbegin();
	}
Ejemplo n.º 19
0
		ConstTextureIterator        cbegin () const
		{
			return textures.cbegin();
		}
Ejemplo n.º 20
0
int tc_libcxx_containers_map_access_iterator(void)
{
    {
        typedef std::pair<const int, double> V;
        V ar[] =
        {
            V(1, 1),
            V(1, 1.5),
            V(1, 2),
            V(2, 1),
            V(2, 1.5),
            V(2, 2),
            V(3, 1),
            V(3, 1.5),
            V(3, 2),
            V(4, 1),
            V(4, 1.5),
            V(4, 2),
            V(5, 1),
            V(5, 1.5),
            V(5, 2),
            V(6, 1),
            V(6, 1.5),
            V(6, 2),
            V(7, 1),
            V(7, 1.5),
            V(7, 2),
            V(8, 1),
            V(8, 1.5),
            V(8, 2)
        };
        std::map<int, double> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
        TC_ASSERT_EXPR(static_cast<std::size_t>(std::distance(m.begin(), m.end())) == m.size());
        TC_ASSERT_EXPR(static_cast<std::size_t>(std::distance(m.rbegin(), m.rend())) == m.size());
        std::map<int, double>::iterator i;
        i = m.begin();
        std::map<int, double>::const_iterator k = i;
        TC_ASSERT_EXPR(i == k);
        for (int j = 1; static_cast<std::size_t>(j) <= m.size(); ++j, ++i)
        {
            TC_ASSERT_EXPR(i->first == j);
            TC_ASSERT_EXPR(i->second == 1);
            i->second = 2.5;
            TC_ASSERT_EXPR(i->second == 2.5);
        }
    }
    {
        typedef std::pair<const int, double> V;
        V ar[] =
        {
            V(1, 1),
            V(1, 1.5),
            V(1, 2),
            V(2, 1),
            V(2, 1.5),
            V(2, 2),
            V(3, 1),
            V(3, 1.5),
            V(3, 2),
            V(4, 1),
            V(4, 1.5),
            V(4, 2),
            V(5, 1),
            V(5, 1.5),
            V(5, 2),
            V(6, 1),
            V(6, 1.5),
            V(6, 2),
            V(7, 1),
            V(7, 1.5),
            V(7, 2),
            V(8, 1),
            V(8, 1.5),
            V(8, 2)
        };
        const std::map<int, double> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
        TC_ASSERT_EXPR(static_cast<std::size_t>(std::distance(m.begin(), m.end())) == m.size());
        TC_ASSERT_EXPR(static_cast<std::size_t>(std::distance(m.cbegin(), m.cend())) == m.size());
        TC_ASSERT_EXPR(static_cast<std::size_t>(std::distance(m.rbegin(), m.rend())) == m.size());
        TC_ASSERT_EXPR(static_cast<std::size_t>(std::distance(m.crbegin(), m.crend())) == m.size());
        std::map<int, double>::const_iterator i;
        i = m.begin();
        for (int j = 1; static_cast<std::size_t>(j) <= m.size(); ++j, ++i)
        {
            TC_ASSERT_EXPR(i->first == j);
            TC_ASSERT_EXPR(i->second == 1);
        }
    }
#if TEST_STD_VER > 11
    { // N3644 testing
        typedef std::map<int, double> C;
        C::iterator ii1{}, ii2{};
        C::iterator ii4 = ii1;
        C::const_iterator cii{};
        TC_ASSERT_EXPR ( ii1 == ii2 );
        TC_ASSERT_EXPR ( ii1 == ii4 );

        TC_ASSERT_EXPR (!(ii1 != ii2 ));

        TC_ASSERT_EXPR ( (ii1 == cii ));
        TC_ASSERT_EXPR ( (cii == ii1 ));
        TC_ASSERT_EXPR (!(ii1 != cii ));
        TC_ASSERT_EXPR (!(cii != ii1 ));
    }
#endif
    TC_SUCCESS_RESULT();
    return 0;
}
Ejemplo n.º 21
0
bool CStakeInfo::BuildIndex(const std::map<std::string, std::map<unsigned int, std::map<unsigned int, SWLink>>>& mapRoadOut,
	std::vector<DCoord>& vecCoords)
{
	

	unsigned int iLinkCount = 0;
	unsigned int iCoordCount = 0;

	for (auto itWay = mapRoadOut.cbegin(); itWay != mapRoadOut.cend(); ++itWay)
	{	
		auto itStakeWay = m_mapStakeIndex.find(itWay->first);
		if (itStakeWay == m_mapStakeIndex.end()) //添加路线
		{
			std::map<int, CLIndex> mapIndex;
			std::map<int, std::map<int, CLIndex>> mapIndexDir;
			mapIndexDir.insert(std::pair<int, std::map<int, CLIndex>>(1, mapIndex)); //上行
			m_mapStakeIndex.insert(std::pair<std::string, std::map<int, std::map<int, CLIndex>>>(itWay->first, mapIndexDir));
			mapIndexDir.clear();
			mapIndexDir.insert(std::pair<int, std::map<int, CLIndex>>(2, mapIndex)); //下行
			m_mapStakeIndex.insert(std::pair<std::string, std::map<int, std::map<int, CLIndex>>>(itWay->first, mapIndexDir));
			itStakeWay = m_mapStakeIndex.find(itWay->first);
		}

		auto itStakeInfo = m_mapStakeInfo.find(itWay->first);
		if (itStakeInfo == m_mapStakeInfo.end())
		{//没有找到这条路线的里程桩
			printf("High way without stake info! id = %s", itWay->first.c_str());
			continue;
		}

		//分开上下行处理里程桩的
		/*void BuildCLIndex(std::map<int, std::map<int, CLIndex>>& mapIndexDir,
			std::map<long long, std::vector<StakeInfo>>& mapStakeLink,
			const std::map<unsigned int, std::map<unsigned int, SWLink>>& mapRoadDir,
			std::vector<DCoord>& vecCoords, int iDir, unsigned int& iLinkCount, unsigned int& iCoordCount);*/
#ifndef ONLY_STAKE_DATA

		BuildCLIndex(itStakeWay->second, itStakeInfo->second, itWay->second, 
			vecCoords, 1, iLinkCount, iCoordCount); //上行


		BuildCLIndex(itStakeWay->second, itStakeInfo->second, itWay->second,
			vecCoords, 2, iLinkCount, iCoordCount); //下行
#else
		auto itWayDir = itWay->second.find(1);
		if (itWayDir != itWay->second.end())
		{
			auto itStakeDir = itStakeWay->second.find(1);
			if (itStakeDir == itStakeWay->second.end())
			{
				std::map<int, CLIndex> mapIndex;
				std::map<int, std::map<int, CLIndex>> mapIndexDir;
				itStakeWay->second.insert(std::pair<int, std::map<int, CLIndex>>(2, mapIndex)); //上行
			}

			
			for (auto itWayLink = itWayDir->second.cbegin(); itWayLink != itWayDir->second.cend(); ++itWayLink, ++iLinkCount)
			{
				const SWLink& stLink = itWayLink->second;
				const long long lLinkID = stLink.lLinkID;
				auto itStakeList = itStakeInfo->second.find(lLinkID);
				if (itStakeList == itStakeInfo->second.end())
				{
					continue;
				}
				else
				{
					std::vector<StakeInfo>& vecStakeInfo = itStakeList->second;
					size_t iLinkCoordCount = 0;
					for (auto itVecStake = vecStakeInfo.cbegin(); itVecStake != vecStakeInfo.cend(); ++itVecStake)
					{
						unsigned int nlPosPoint = -1;

						//放入到坐标容器中
						int nVecCount = vecCoords.size();
						vecCoords.push_back(itVecStake->dcoord);

						//建立里程桩的坐标索引
						unsigned int iCIndex = nVecCount;
						CLIndex stIndex;
						stIndex.CIndex = iCIndex;
						stIndex.LIndex = iLinkCount;
						itStakeDir->second.insert(std::pair<int, CLIndex>(itVecStake->stakeID, stIndex));

						iLinkCoordCount = stLink.coords.size();
					}
				}

				iCoordCount = vecCoords.size();
			}
		}
#endif // 

	}
	return true;
}
Ejemplo n.º 22
0
/******************************************************************************
* Lets the display object render the data object.
******************************************************************************/
void ParticleDisplay::render(TimePoint time, DataObject* dataObject, const PipelineFlowState& flowState, SceneRenderer* renderer, ObjectNode* contextNode)
{
	// Get input data.
	ParticlePropertyObject* positionProperty = dynamic_object_cast<ParticlePropertyObject>(dataObject);
	ParticlePropertyObject* radiusProperty = ParticlePropertyObject::findInState(flowState, ParticleProperty::RadiusProperty);
	ParticlePropertyObject* colorProperty = ParticlePropertyObject::findInState(flowState, ParticleProperty::ColorProperty);
	ParticleTypeProperty* typeProperty = dynamic_object_cast<ParticleTypeProperty>(ParticlePropertyObject::findInState(flowState, ParticleProperty::ParticleTypeProperty));
	ParticlePropertyObject* selectionProperty = renderer->isInteractive() ? ParticlePropertyObject::findInState(flowState, ParticleProperty::SelectionProperty) : nullptr;
	ParticlePropertyObject* transparencyProperty = ParticlePropertyObject::findInState(flowState, ParticleProperty::TransparencyProperty);
	ParticlePropertyObject* shapeProperty = ParticlePropertyObject::findInState(flowState, ParticleProperty::AsphericalShapeProperty);
	if(shadingMode() != ParticlePrimitive::NormalShading)
		shapeProperty = nullptr;

	// Get number of particles.
	int particleCount = positionProperty ? (int)positionProperty->size() : 0;

	// Do we have to re-create the geometry buffer from scratch?
	bool recreateBuffer = !_particleBuffer || !_particleBuffer->isValid(renderer);

	// If rendering quality is set to automatic, pick quality level based on number of particles.
	ParticlePrimitive::RenderingQuality renderQuality = effectiveRenderingQuality(renderer, positionProperty);

	// Determine effective particle shape.
	ParticlePrimitive::ParticleShape effectiveParticleShape = particleShape();
	if(effectiveParticleShape == ParticlePrimitive::SquareShape && shapeProperty != nullptr)
		effectiveParticleShape = ParticlePrimitive::BoxShape;
	else
		shapeProperty = nullptr;

	// Set shading mode and rendering quality.
	if(!recreateBuffer) {
		recreateBuffer |= !(_particleBuffer->setShadingMode(shadingMode()));
		recreateBuffer |= !(_particleBuffer->setRenderingQuality(renderQuality));
		recreateBuffer |= !(_particleBuffer->setParticleShape(effectiveParticleShape));
		recreateBuffer |= ((transparencyProperty != nullptr) != _particleBuffer->translucentParticles());
	}

	// Do we have to resize the render buffer?
	bool resizeBuffer = recreateBuffer || (_particleBuffer->particleCount() != particleCount);

	// Do we have to update the particle positions in the render buffer?
	bool updatePositions = _positionsCacheHelper.updateState(positionProperty)
			|| resizeBuffer;

	// Do we have to update the particle radii in the geometry buffer?
	bool updateRadii = _radiiCacheHelper.updateState(
			radiusProperty,
			typeProperty,
			defaultParticleRadius())
			|| resizeBuffer;

	// Do we have to update the particle colors in the geometry buffer?
	bool updateColors = _colorsCacheHelper.updateState(
			colorProperty,
			typeProperty,
			selectionProperty,
			transparencyProperty,
			positionProperty)
			|| resizeBuffer;

	// Do we have to update the particle shapes in the geometry buffer?
	bool updateShapes = _shapesCacheHelper.updateState(
			shapeProperty) || resizeBuffer;

	// Re-create the geometry buffer if necessary.
	if(recreateBuffer)
		_particleBuffer = renderer->createParticlePrimitive(shadingMode(), renderQuality, effectiveParticleShape, transparencyProperty != nullptr);

	// Re-size the geometry buffer if necessary.
	if(resizeBuffer)
		_particleBuffer->setSize(particleCount);

	// Update position buffer.
	if(updatePositions && positionProperty) {
		OVITO_ASSERT(positionProperty->size() == particleCount);
		_particleBuffer->setParticlePositions(positionProperty->constDataPoint3());
	}

	// Update radius buffer.
	if(updateRadii && particleCount) {
		if(radiusProperty) {
			// Take particle radii directly from the radius property.
			OVITO_ASSERT(radiusProperty->size() == particleCount);
			_particleBuffer->setParticleRadii(radiusProperty->constDataFloat());
		}
		else if(typeProperty) {
			// Assign radii based on particle types.
			OVITO_ASSERT(typeProperty->size() == particleCount);
			// Build a lookup map for particle type raii.
			const std::map<int,FloatType> radiusMap = typeProperty->radiusMap();
			// Skip the following loop if all per-type radii are zero. In this case, simply use the default radius for all particles.
			if(std::any_of(radiusMap.cbegin(), radiusMap.cend(), [](const std::pair<int,FloatType>& it) { return it.second != 0; })) {
				// Allocate memory buffer.
				std::vector<FloatType> particleRadii(particleCount, defaultParticleRadius());
				// Fill radius array.
				const int* t = typeProperty->constDataInt();
				for(auto c = particleRadii.begin(); c != particleRadii.end(); ++c, ++t) {
					auto it = radiusMap.find(*t);
					// Set particle radius only if the type's radius is non-zero.
					if(it != radiusMap.end() && it->second != 0)
						*c = it->second;
				}
				_particleBuffer->setParticleRadii(particleRadii.data());
			}
			else {
				// Assign a constant radius to all particles.
				_particleBuffer->setParticleRadius(defaultParticleRadius());
			}
		}
		else {
			// Assign a constant radius to all particles.
			_particleBuffer->setParticleRadius(defaultParticleRadius());
		}
	}

	// Update color buffer.
	if(updateColors && particleCount) {
		if(colorProperty && !selectionProperty && !transparencyProperty) {
			// Direct particle colors.
			OVITO_ASSERT(colorProperty->size() == particleCount);
			_particleBuffer->setParticleColors(colorProperty->constDataColor());
		}
		else {
			std::vector<Color> colors(particleCount);
			particleColors(colors, colorProperty, typeProperty, selectionProperty);
			if(!transparencyProperty) {
				_particleBuffer->setParticleColors(colors.data());
			}
			else {
				// Add alpha channel based on transparency particle property.
				std::vector<ColorA> colorsWithAlpha(particleCount);
				const FloatType* t = transparencyProperty->constDataFloat();
				auto c_in = colors.cbegin();
				for(auto c_out = colorsWithAlpha.begin(); c_out != colorsWithAlpha.end(); ++c_out, ++c_in, ++t) {
					c_out->r() = c_in->r();
					c_out->g() = c_in->g();
					c_out->b() = c_in->b();
					c_out->a() = FloatType(1) - (*t);
				}
				_particleBuffer->setParticleColors(colorsWithAlpha.data());
			}
		}
	}

	// Update shapes buffer.
	if(updateShapes && particleCount) {
		if(shapeProperty) {
			OVITO_ASSERT(shapeProperty->size() == particleCount);
			_particleBuffer->setParticleShapes(shapeProperty->constDataVector3());
		}
	}

	if(renderer->isPicking()) {
		OORef<ParticlePickInfo> pickInfo(new ParticlePickInfo(flowState));
		renderer->beginPickObject(contextNode, pickInfo);
	}

	_particleBuffer->render(renderer);

	if(renderer->isPicking()) {
		renderer->endPickObject();
	}
}
Ejemplo n.º 23
0
void Util::PrintFoundDuplicates
        (const std::map<std::string, std::vector<std::string>> &words)
{
    // pair the words that have at least 2 substrings in common
    std::pair<std::string, std::string> related_words;
    // "shared" substrings between the 2 words. At least 2 substrings.
    std::vector<std::string> identical_substrings;

    bool found_at_least_one_common_substring = false;

    // To iterate through every pair in our map and compare every mapped type's
    // (vector of strings) elements I'll use an approach loops similar to
    // those used for simple bubble sort.
    // No random access iterators for maps, so I can't do end - 1 for example
    auto end1 = --words.cend();
    auto end2 =   words.cend();

    // compare starting at the first value_type in our map
    for (auto beg1 = words.cbegin(); beg1 != end1; ++beg1)
    {
        // don't want the original iterator incremented in the next for loop
        auto beg1_dupe = beg1;

        // identical_substrings.clear();

        // with the next immediate value_type
        for (auto beg2 = ++beg1_dupe; beg2 != end2; ++beg2)
        {
            // form the pair of words that potentially can have the
            // same substrings
            related_words = {beg1->first, beg2->first};

            identical_substrings.clear();

            // every substring in beg1's mapped_type (vector of strings)
            for (const std::string &word1 : beg1->second)
            {
                // with every substring beg2's mapped type (vector of strings)
                for (std::string word2 : beg2->second)
                {
                    if (word1 == word2)
                    {
                        found_at_least_one_common_substring = true;
                        identical_substrings.emplace_back(word2);
                    }
                }
            }

            if (identical_substrings.size() >= 2)
            {
                std::cout << "\"" << related_words.first << "\" and \""
                        << related_words.second << "\" have in common\n\t: ";
                for (auto substring : identical_substrings)
                    std::cout << substring << ' ';
                std::cout << std::endl;
            }
        }
    }

    if (!found_at_least_one_common_substring)
        std::cout << "\n\t\"fara solutie\"\n";
}
Ejemplo n.º 24
0
namespace Name
{
static std::map< nameFlags, std::vector< std::string > > names;

static const std::map< std::string, nameFlags > usage_flags = {
    { "given",     nameIsGivenName },
    { "family",    nameIsFamilyName },
    { "universal", nameIsGivenName | nameIsFamilyName },
    { "backer",    nameIsFullName },
    { "city",      nameIsTownName },
    { "world",     nameIsWorldName }
};

static const std::map< std::string, nameFlags > gender_flags {
    { "male",   nameIsMaleName },
    { "female", nameIsFemaleName },
    { "unisex", nameIsUnisexName }
};

static nameFlags usage_flag( const std::string &usage )
{
    auto it = usage_flags.find( usage );
    if( it != usage_flags.end() ) {
        return it->second;
    }
    return static_cast< nameFlags >( 0 );
}

static nameFlags gender_flag( const std::string &gender )
{
    auto it = gender_flags.find( gender );
    if( it != gender_flags.end() ) {
        return it->second;
    }
    return static_cast< nameFlags >( 0 );
}

// The loaded name is one of usage with optional gender.
// The combinations used in names files are as follows.
//
// Backer | (Female|Male|Unisex)
// Given  | (Female|Male)        // unisex names are duplicated in each group
// Family | Unisex
// City
// World
static void load( JsonIn &jsin )
{
    jsin.start_array();

    while( !jsin.end_array() ) {
        JsonObject jo = jsin.get_object();

        // get flags of name.
        const nameFlags type =
            usage_flag( jo.get_string( "usage" ) )
            | gender_flag( jo.get_string( "gender", "" ) );

        // find group type and add name to group
        names[type].push_back( jo.get_string( "name" ) );
    }
}

void load_from_file( const std::string &filename )
{
    read_from_file_json( filename, load );
}

// get name groups for which searchFlag is a subset.
//
// i.e. if searchFlag is  [ Male|Family ]
// it will match any group with those two flags set, such as [ Unisex|Family ]
using names_vec = std::vector< decltype( names.cbegin() ) >;
static names_vec get_matching_groups( nameFlags searchFlags )
{
    names_vec matching_groups;
    for( auto it = names.cbegin(), end = names.cend(); it != end; ++it ) {
        const nameFlags type = it->first;
        if( ( searchFlags & type ) == searchFlags ) {
            matching_groups.push_back( it );
        }
    }
    return matching_groups;
}

// Get a random name with the specified flag
std::string get( nameFlags searchFlags )
{
    auto matching_groups = get_matching_groups( searchFlags );
    if( ! matching_groups.empty() ) {
        // get number of choices
        size_t nChoices = 0;
        for( const auto &i : matching_groups ) {
            const auto &group = i->second;
            nChoices += group.size();
        }

        // make random selection and return result.
        size_t choice = rng( 0, nChoices - 1 );
        for( const auto &i : matching_groups ) {
            const auto &group = i->second;
            if( choice < group.size() ) {
                return group[choice];
            }
            choice -= group.size();
        }
    }
    // BUG, no matching name found.
    return std::string( _( "Tom" ) );
}

std::string generate( bool is_male )
{
    nameFlags baseSearchFlags = is_male ? nameIsMaleName : nameIsFemaleName;
    //One in four chance to pull from the backer list, otherwise generate a name from the parts list
    if( one_in( 4 ) ) {
        return get( baseSearchFlags | nameIsFullName );
    } else {
        //~ used for constructing names. swapping these will put family name first.
        return string_format( pgettext( "Full Name", "%1$s %2$s" ),
                              get( baseSearchFlags | nameIsGivenName ).c_str(),
                              get( baseSearchFlags | nameIsFamilyName ).c_str()
                            );
    }
}

void clear()
{
    names.clear();
}
}
int main()
{
    {
        typedef std::pair<const int, double> V;
        V ar[] =
        {
            V(1, 1),
            V(1, 1.5),
            V(1, 2),
            V(2, 1),
            V(2, 1.5),
            V(2, 2),
            V(3, 1),
            V(3, 1.5),
            V(3, 2),
            V(4, 1),
            V(4, 1.5),
            V(4, 2),
            V(5, 1),
            V(5, 1.5),
            V(5, 2),
            V(6, 1),
            V(6, 1.5),
            V(6, 2),
            V(7, 1),
            V(7, 1.5),
            V(7, 2),
            V(8, 1),
            V(8, 1.5),
            V(8, 2)
        };
        std::map<int, double> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
        assert(std::distance(m.begin(), m.end()) == m.size());
        assert(std::distance(m.rbegin(), m.rend()) == m.size());
        std::map<int, double>::iterator i;
        i = m.begin();
        std::map<int, double>::const_iterator k = i;
        assert(i == k);
        for (int j = 1; j <= m.size(); ++j, ++i)
        {
            assert(i->first == j);
            assert(i->second == 1);
            i->second = 2.5;
            assert(i->second == 2.5);
        }
    }
    {
        typedef std::pair<const int, double> V;
        V ar[] =
        {
            V(1, 1),
            V(1, 1.5),
            V(1, 2),
            V(2, 1),
            V(2, 1.5),
            V(2, 2),
            V(3, 1),
            V(3, 1.5),
            V(3, 2),
            V(4, 1),
            V(4, 1.5),
            V(4, 2),
            V(5, 1),
            V(5, 1.5),
            V(5, 2),
            V(6, 1),
            V(6, 1.5),
            V(6, 2),
            V(7, 1),
            V(7, 1.5),
            V(7, 2),
            V(8, 1),
            V(8, 1.5),
            V(8, 2)
        };
        const std::map<int, double> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
        assert(std::distance(m.begin(), m.end()) == m.size());
        assert(std::distance(m.cbegin(), m.cend()) == m.size());
        assert(std::distance(m.rbegin(), m.rend()) == m.size());
        assert(std::distance(m.crbegin(), m.crend()) == m.size());
        std::map<int, double>::const_iterator i;
        i = m.begin();
        for (int j = 1; j <= m.size(); ++j, ++i)
        {
            assert(i->first == j);
            assert(i->second == 1);
        }
    }
#if __cplusplus >= 201103L
    {
        typedef std::pair<const int, double> V;
        V ar[] =
        {
            V(1, 1),
            V(1, 1.5),
            V(1, 2),
            V(2, 1),
            V(2, 1.5),
            V(2, 2),
            V(3, 1),
            V(3, 1.5),
            V(3, 2),
            V(4, 1),
            V(4, 1.5),
            V(4, 2),
            V(5, 1),
            V(5, 1.5),
            V(5, 2),
            V(6, 1),
            V(6, 1.5),
            V(6, 2),
            V(7, 1),
            V(7, 1.5),
            V(7, 2),
            V(8, 1),
            V(8, 1.5),
            V(8, 2)
        };
        std::map<int, double, std::less<int>, min_allocator<V>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
        assert(std::distance(m.begin(), m.end()) == m.size());
        assert(std::distance(m.rbegin(), m.rend()) == m.size());
        std::map<int, double, std::less<int>, min_allocator<V>>::iterator i;
        i = m.begin();
        std::map<int, double, std::less<int>, min_allocator<V>>::const_iterator k = i;
        assert(i == k);
        for (int j = 1; j <= m.size(); ++j, ++i)
        {
            assert(i->first == j);
            assert(i->second == 1);
            i->second = 2.5;
            assert(i->second == 2.5);
        }
    }
    {
        typedef std::pair<const int, double> V;
        V ar[] =
        {
            V(1, 1),
            V(1, 1.5),
            V(1, 2),
            V(2, 1),
            V(2, 1.5),
            V(2, 2),
            V(3, 1),
            V(3, 1.5),
            V(3, 2),
            V(4, 1),
            V(4, 1.5),
            V(4, 2),
            V(5, 1),
            V(5, 1.5),
            V(5, 2),
            V(6, 1),
            V(6, 1.5),
            V(6, 2),
            V(7, 1),
            V(7, 1.5),
            V(7, 2),
            V(8, 1),
            V(8, 1.5),
            V(8, 2)
        };
        const std::map<int, double, std::less<int>, min_allocator<V>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
        assert(std::distance(m.begin(), m.end()) == m.size());
        assert(std::distance(m.cbegin(), m.cend()) == m.size());
        assert(std::distance(m.rbegin(), m.rend()) == m.size());
        assert(std::distance(m.crbegin(), m.crend()) == m.size());
        std::map<int, double, std::less<int>, min_allocator<V>>::const_iterator i;
        i = m.begin();
        for (int j = 1; j <= m.size(); ++j, ++i)
        {
            assert(i->first == j);
            assert(i->second == 1);
        }
    }
#endif
}
void CSVNStatusListCtrl::ColumnManager::UpdateUserPropList
    (const std::map<CTSVNPath, PropertyList>& propertymap)
{
    // collect all user-defined props

    std::set<CString> aggregatedProps;

    for (auto it = propertymap.cbegin(); it != propertymap.cend(); ++it)
        it->second.GetPropertyNames (aggregatedProps);

    itemProps = aggregatedProps;

    // add new ones to the internal list

    std::set<CString> newProps = aggregatedProps;
    for (size_t i = 0, count = userProps.size(); i < count; ++i)
        newProps.erase (userProps[i].name);

    while (newProps.size() && (newProps.size() + userProps.size() > SVNSLC_MAXCOLUMNCOUNT - SVNSLC_USERPROPCOLOFFSET))
        newProps.erase (--newProps.end());

    typedef std::set<CString>::const_iterator CIT;
    for ( CIT iter = newProps.begin(), end = newProps.end()
        ; iter != end
        ; ++iter)
    {
        int index = static_cast<int>(userProps.size())
                  + SVNSLC_USERPROPCOLOFFSET;
        if (columnOrder.size() < SVNSLC_MAXCOLUMNCOUNT)
            columnOrder.push_back (index);

        UserProp userProp;
        userProp.name = *iter;
        userProp.width = 0;

        userProps.push_back (userProp);
    }

    // remove unused columns from control.
    // remove used ones from the set of aggregatedProps.

    for (size_t i = columns.size(); i > 0; --i)
        if (   (columns[i-1].index >= SVNSLC_USERPROPCOLOFFSET)
            && (aggregatedProps.erase (GetName ((int)i-1)) == 0))
        {
            // this user-prop has not been set on any item

            if (!columns[i-1].visible)
            {
                control->DeleteColumn (static_cast<int>(i-1));
                columns.erase (columns.begin() + i-1);
            }
        }

    // aggregatedProps now contains new columns only.
    // we can't use newProps here because some props may have been used
    // earlier but were not in the recent list of used props.
    // -> they are neither in columns[] nor in newProps.

    for ( CIT iter = aggregatedProps.begin(), end = aggregatedProps.end()
        ; iter != end
        ; ++iter)
    {
        // get the logical column index / ID

        int index = -1;
        int width = 0;
        for (size_t i = 0, count = userProps.size(); i < count; ++i)
            if (userProps[i].name == *iter)
            {
                index = static_cast<int>(i) + SVNSLC_USERPROPCOLOFFSET;
                width = userProps[i].width;
                break;
            }

        if (index == -1)
        {
            // property got removed because there were more than SVNSLC_MAXCOLUMNCOUNT-SVNSLC_USERPROPCOLOFFSET
            continue;
        }

        // find insertion position

        std::vector<ColumnInfo>::iterator columnIter = columns.begin();
        std::vector<ColumnInfo>::iterator end2 = columns.end();
        for (; (columnIter != end2) && columnIter->index < index; ++columnIter);
        int pos = static_cast<int>(columnIter - columns.begin());

        ColumnInfo column;
        column.index = index;
        column.width = width;
        column.visible = false;

        columns.insert (columnIter, column);

        // update control

        int result = control->InsertColumn (pos, *iter, LVCFMT_LEFT, GetVisibleWidth(pos, false));
        assert (result != -1);
        UNREFERENCED_PARAMETER(result);
    }

    // update column order

    ApplyColumnOrder();
}