BidirectionalIterator test_some(BidirectionalIterator first, BidirectionalIterator last) { BidirectionalIterator current = first; BidirectionalIterator start_of_completed = last; while (current != start_of_completed) { // Check if we have found a completed request. if (optional<status> result = current->test()) { using std::iter_swap; // We're expanding the set of completed requests --start_of_completed; // Swap the request we just completed with the last request that // has not yet been tested. iter_swap(current, start_of_completed); continue; } // Move to the next request. ++current; } return start_of_completed; }
std::pair<OutputIterator, BidirectionalIterator> test_some(BidirectionalIterator first, BidirectionalIterator last, OutputIterator out) { BidirectionalIterator current = first; BidirectionalIterator start_of_completed = last; while (current != start_of_completed) { // Check if we have found a completed request. if (optional<status> result = current->test()) { using std::iter_swap; // Emit the resulting status object *out++ = *result; // We're expanding the set of completed requests --start_of_completed; // Swap the request we just completed with the last request that // has not yet been tested. iter_swap(current, start_of_completed); continue; } // Move to the next request. ++current; } // Finish up by fixing the order of the completed set to match the // order in which we emitted status objects, then return. std::reverse(start_of_completed, last); return std::make_pair(out, start_of_completed); }
//shuffles the deck by switching cards at each position void MasterPile::shuffle(){ vector<Card>::iterator it = pile.begin(); srand(time(NULL)); while(it != pile.end()){ int randomValue = rand() % this->getSize(); iter_swap(it, pile.begin() + randomValue); it++; } }
template<class It> It uniquify(It begin, It const end) { std::vector<It> v; v.reserve(static_cast<size_t>(std::distance(begin, end))); for (It i = begin; i != end; ++i) { v.push_back(i); } std::sort(v.begin(), v.end(), target_less()); v.erase(std::unique(v.begin(), v.end(), target_equal()), v.end()); std::sort(v.begin(), v.end()); size_t j = 0; for (It i = begin; i != end && j != v.size(); ++i) { if (i == v[j]) { using std::iter_swap; iter_swap(i, begin); ++j; ++begin; } } return begin; }
void file_storage::optimize(int pad_file_limit) { // the main purpuse of padding is to optimize disk // I/O. This is a conservative memory page size assumption int alignment = 8*1024; // it doesn't make any sense to pad files that // are smaller than one piece if (pad_file_limit >= 0 && pad_file_limit < alignment) pad_file_limit = alignment; // put the largest file at the front, to make sure // it's aligned std::vector<file_entry>::iterator i = std::max_element(m_files.begin(), m_files.end() , boost::bind(&file_entry::size, _1) < boost::bind(&file_entry::size, _2)); using std::iter_swap; iter_swap(i, m_files.begin()); size_type off = 0; int padding_file = 0; for (std::vector<file_entry>::iterator i = m_files.begin(); i != m_files.end(); ++i) { if (pad_file_limit >= 0 && (off & (alignment-1)) != 0 && i->size > pad_file_limit && i->pad_file == false) { // if we have pad files enabled, and this file is // not piece-aligned and the file size exceeds the // limit, and it's not a padding file itself. // so add a padding file in front of it int pad_size = alignment - (off & (alignment-1)); // find the largest file that fits in pad_size std::vector<file_entry>::iterator best_match = m_files.end(); for (std::vector<file_entry>::iterator j = i+1; j < m_files.end(); ++j) { if (j->size > pad_size) continue; if (best_match == m_files.end() || j->size > best_match->size) best_match = j; } if (best_match != m_files.end()) { // we found one // We cannot have found i, because i->size > pad_file_limit // which is forced to be no less than alignment. We only // look for files <= pad_size, which never is greater than // alignment TORRENT_ASSERT(best_match != i); file_entry e = *best_match; m_files.erase(best_match); i = m_files.insert(i, e); i->offset = off; off += i->size; continue; } // we could not find a file that fits in pad_size // add a padding file // note that i will be set to point to the // new pad file. Once we're done adding it, we need // to increment i to point to the current file again file_entry e; i = m_files.insert(i, e); i->size = pad_size; i->offset = off; i->file_base = 0; char name[10]; std::sprintf(name, "%d", padding_file); i->path = *(i+1)->path.begin(); i->path /= "_____padding_file_"; i->path /= name; i->pad_file = true; off += pad_size; ++padding_file; // skip the pad file we just added and point // at the current file again ++i; } i->offset = off; off += i->size; } m_total_size = off; }
BidirectionalIterator wait_some(BidirectionalIterator first, BidirectionalIterator last) { using std::advance; if (first == last) return first; typedef typename std::iterator_traits<BidirectionalIterator>::difference_type difference_type; bool all_trivial_requests = true; difference_type n = 0; BidirectionalIterator current = first; BidirectionalIterator start_of_completed = last; while (true) { // Check if we have found a completed request. if (optional<status> result = current->test()) { using std::iter_swap; // We're expanding the set of completed requests --start_of_completed; // If we have hit the end of the list of pending requests, we're // done. if (current == start_of_completed) return start_of_completed; // Swap the request we just completed with the last request that // has not yet been tested. iter_swap(current, start_of_completed); continue; } // Check if this request (and all others before it) are "trivial" // requests, e.g., they can be represented with a single // MPI_Request. all_trivial_requests = all_trivial_requests && !current->m_handler && current->m_requests[1] == MPI_REQUEST_NULL; // Move to the next request. ++n; if (++current == start_of_completed) { // If we have satisfied some requests, we're done. if (start_of_completed != last) return start_of_completed; // We have reached the end of the list. If all requests thus far // have been trivial, we can call MPI_Waitsome directly, because // it may be more efficient than our busy-wait semantics. if (all_trivial_requests) { std::vector<MPI_Request> requests; std::vector<int> indices(n); requests.reserve(n); for (current = first; current != last; ++current) requests.push_back(current->m_requests[0]); // Let MPI wait until some of these operations complete. int num_completed; BOOST_MPI_CHECK_RESULT(MPI_Waitsome, (n, &requests[0], &num_completed, &indices[0], MPI_STATUSES_IGNORE)); // Translate the index-based result of MPI_Waitsome into a // partitioning on the requests. int current_offset = 0; current = first; for (int index = 0; index < num_completed; ++index) { using std::iter_swap; // Move "current" to the request object at this index advance(current, indices[index] - current_offset); current_offset = indices[index]; // Finish up the request and swap it into the "completed // requests" partition. current->m_requests[0] = requests[indices[index]]; --start_of_completed; iter_swap(current, start_of_completed); } // We have satisfied some requests, so we are done. return start_of_completed; } // There are some nontrivial requests, so we must continue our // busy waiting loop. n = 0; current = first; } } // We cannot ever get here BOOST_ASSERT(false); }