summaryrefslogtreecommitdiffstats
path: root/src/concurrent/qtconcurrentmedian.h
blob: 01cb8b93e00be79d091c36ff6f8ceb00e626d6a6 (plain)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
// Copyright (C) 2016 The Qt Company Ltd.// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only#ifndef QTCONCURRENT_MEDIAN_H#define QTCONCURRENT_MEDIAN_H#include <QtConcurrent/qtconcurrent_global.h>#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)#include <algorithm>#include <cstring> QT_BEGIN_NAMESPACE namespace QtConcurrent {class Median {public:enum{ BufferSize =7};Median():currentMedian(),currentIndex(0),valid(false),dirty(true){std::fill_n(values,static_cast<int>(BufferSize),0.0);}voidreset(){std::fill_n(values,static_cast<int>(BufferSize),0.0); currentIndex =0; valid =false; dirty =true;}voidaddValue(double value){++currentIndex;if(currentIndex == BufferSize) { currentIndex =0; valid =true;}// Only update the cached median value when we have to, that// is when the new value is on then other side of the median// compared to the current value at the index.const double currentIndexValue = values[currentIndex];if((currentIndexValue > currentMedian && currentMedian > value)|| (currentMedian > currentIndexValue && value > currentMedian)) { dirty =true;} values[currentIndex] = value;}boolisMedianValid()const{return valid;}doublemedian(){if(dirty) { dirty =false;double sorted[BufferSize];::memcpy(&sorted, &values,sizeof(sorted));std::sort(sorted, sorted +static_cast<int>(BufferSize)); currentMedian = sorted[BufferSize /2];}return currentMedian;}private:double values[BufferSize];double currentMedian;int currentIndex;bool valid;bool dirty;};}// namespace QtConcurrent QT_END_NAMESPACE #endif// QT_NO_CONCURRENT#endif
close