Если Вы просто ищете чрезвычайно точные измерения [1 114] прошедшее время , используйте System.nanoTime()
. System.currentTimeMillis()
даст Вам самое точное прошедшее время в миллисекундах, так как эпоха, но System.nanoTime()
дает Вам точное наносекундой время, относительно некоторой произвольной точки.
Из Документации Java:
public static long nanoTime()
Возвраты текущее значение самого точного доступного системного таймера, в наносекундах.
Этот метод может только использоваться для измерения прошедшего времени и не связан ни с каким другим понятием системы или тактовое стеной время. Возвращенное значение представляет наносекунды с некоторого фиксированного, но произвольного момента времени (возможно, в будущем, таким образом, значения могут быть отрицательными). Этот метод обеспечивает точность наносекунды, но не обязательно точность наносекунды. Никакие гарантии не сделаны о том, как часто значения изменяются. Различия в последовательных вызовах, которые охватывают больше, чем приблизительно 292 года (2 63 глоток> наносекунды) точно не вычислят прошедшее время из-за числового переполнения.
, Например, для измерения, сколько времени некоторый код берет для выполнения:
long startTime = System.nanoTime();
// ... the code being measured ...
long estimatedTime = System.nanoTime() - startTime;
См. также: JavaDoc System.nanoTime () и JavaDoc System.currentTimeMillis () для большего количества информации
Это идеальная ситуация для использования фасета.
Пользовательская версия фасета codecvt может быть встроена в поток.
Таким образом, ваше использование будет выглядеть следующим образом:
int main()
{
/* Imbue std::cout before it is used */
std::ios::sync_with_stdio(false);
std::cout.imbue(std::locale(std::locale::classic(), new IndentFacet()));
std::cout << "Line 1\nLine 2\nLine 3\n";
/* You must imbue a file stream before it is opened. */
std::ofstream data;
data.imbue(indentLocale);
data.open("PLOP");
data << "Loki\nUses Locale\nTo do something silly\n";
}
Определение фасета немного сложное.
Но все дело в том, что кому-то, использующему фасет, не нужно ничего знать о форматировании. Форматирование применяется независимо от того, как используется поток.
#include <locale>
#include <algorithm>
#include <iostream>
#include <fstream>
class IndentFacet: public std::codecvt<char,char,std::mbstate_t>
{
public:
explicit IndentFacet(size_t ref = 0): std::codecvt<char,char,std::mbstate_t>(ref) {}
typedef std::codecvt_base::result result;
typedef std::codecvt<char,char,std::mbstate_t> parent;
typedef parent::intern_type intern_type;
typedef parent::extern_type extern_type;
typedef parent::state_type state_type;
int& state(state_type& s) const {return *reinterpret_cast<int*>(&s);}
protected:
virtual result do_out(state_type& tabNeeded,
const intern_type* rStart, const intern_type* rEnd, const intern_type*& rNewStart,
extern_type* wStart, extern_type* wEnd, extern_type*& wNewStart) const
{
result res = std::codecvt_base::noconv;
for(;(rStart < rEnd) && (wStart < wEnd);++rStart,++wStart)
{
// 0 indicates that the last character seen was a newline.
// thus we will print a tab before it. Ignore it the next
// character is also a newline
if ((state(tabNeeded) == 0) && (*rStart != '\n'))
{
res = std::codecvt_base::ok;
state(tabNeeded) = 1;
*wStart = '\t';
++wStart;
if (wStart == wEnd)
{
res = std::codecvt_base::partial;
break;
}
}
// Copy the next character.
*wStart = *rStart;
// If the character copied was a '\n' mark that state
if (*rStart == '\n')
{
state(tabNeeded) = 0;
}
}
if (rStart != rEnd)
{
res = std::codecvt_base::partial;
}
rNewStart = rStart;
wNewStart = wStart;
return res;
}
// Override so the do_out() virtual function is called.
virtual bool do_always_noconv() const throw()
{
return false; // Sometime we add extra tabs
}
};
См .: Примечания Тома ниже
Ну, это не тот ответ, который я ищу, но если такого ответа нет, вот способ сделать это вручную:
void
indentedOutput(ostream &outStream, const char *message, bool &newline)
{
while (char cur = *message) {
if (newline) {
outStream << " ";
newline = false;
}
outStream << cur;
if (cur == '\n') {
newline = true;
}
++message;
}
}
Способ добавить такую функцию - написать фильтрующий streambuf (т. Е. Streambuf, который перенаправляет операцию ввода-вывода другому streambuf, но манипулирует передаваемыми данными), который добавляет отступ как часть своего фильтра операция. Я привел пример написания streambuf здесь , и boost предоставляет библиотеку , чтобы помочь в этом.
Если ваш случай, член overflow () просто проверит на '\ n 'а затем при необходимости добавьте отступ сразу после него (именно то, что вы сделали в своей функции indentedOuput
, за исключением того, что новая строка
будет членом streambuf). Вероятно, у вас может быть настройка для увеличения или уменьшения размера отступа (возможно, доступная через манипулятор, манипулятор должен будет выполнить dynamic_cast, чтобы гарантировать, что streambuf, связанный с потоком, имеет правильный тип; есть механизм для добавления пользовательских данных в поток - basic_ios :: xalloc, iword и pword - но здесь мы хотим воздействовать на streambuf).
Простого пути нет, но о сложном написано много способы добиться этого. Прочтите эту статью , чтобы получить хорошее объяснение тема. Вот еще одна статья , к сожалению, на немецком языке. Но его исходный код должен вам помочь.
Например, вы можете написать функцию, которая регистрирует рекурсивную структуру. Для каждого уровня рекурсии отступ увеличивается:
std::ostream& operator<<(std::ostream& stream, Parameter* rp)
{
stream << "Parameter: " << std::endl;
// Get current indent
int w = format::get_indent(stream);
stream << "Name: " << rp->getName();
// ... log other attributes as well
if ( rp->hasParameters() )
{
stream << "subparameter (" << rp->getNumParameters() << "):\n";
// Change indent for sub-levels in the hierarchy
stream << format::indent(w+4);
// write sub parameters
stream << rp->getParameters();
}
// Now reset indent
stream << format::indent(w);
return stream;
}