11 changes: 11 additions & 0 deletions libc/utils/testutils/StreamWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "StreamWrapper.h"
#include <cassert>
#include <fstream>
#include <iostream>
#include <memory>
#include <string>
Expand All @@ -21,6 +22,7 @@ template <typename T> StreamWrapper &StreamWrapper::operator<<(T t) {
assert(OS);
std::ostream &Stream = *reinterpret_cast<std::ostream *>(OS);
Stream << t;
Stream.flush();
return *this;
}

Expand All @@ -43,6 +45,15 @@ template StreamWrapper &
StreamWrapper::operator<<<unsigned long long>(unsigned long long t);
template StreamWrapper &StreamWrapper::operator<<<bool>(bool t);
template StreamWrapper &StreamWrapper::operator<<<std::string>(std::string t);
template StreamWrapper &StreamWrapper::operator<<<float>(float t);
template StreamWrapper &StreamWrapper::operator<<<double>(double t);

OutputFileStream::OutputFileStream(const char *FN)
: StreamWrapper(new std::ofstream(FN)) {}

OutputFileStream::~OutputFileStream() {
delete reinterpret_cast<std::ofstream *>(OS);
}

} // namespace testutils
} // namespace __llvm_libc
7 changes: 7 additions & 0 deletions libc/utils/testutils/StreamWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace testutils {
// standard headers so we must provide streams through indirection to not
// expose the system libc headers.
class StreamWrapper {
protected:
void *OS;

public:
Expand All @@ -26,6 +27,12 @@ class StreamWrapper {

StreamWrapper outs();

class OutputFileStream : public StreamWrapper {
public:
explicit OutputFileStream(const char *FN);
~OutputFileStream();
};

} // namespace testutils
} // namespace __llvm_libc

Expand Down
42 changes: 42 additions & 0 deletions libc/utils/testutils/Timer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//===-- Timer.cpp --------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "Timer.h"

#include <chrono>
#include <fstream>

namespace __llvm_libc {
namespace testing {

struct TimerImplementation {
std::chrono::high_resolution_clock::time_point Start;
std::chrono::high_resolution_clock::time_point End;
};

Timer::Timer() : Impl(new TimerImplementation) {}

Timer::~Timer() { delete reinterpret_cast<TimerImplementation *>(Impl); }

void Timer::start() {
auto T = reinterpret_cast<TimerImplementation *>(Impl);
T->Start = std::chrono::high_resolution_clock::now();
}

void Timer::stop() {
auto T = reinterpret_cast<TimerImplementation *>(Impl);
T->End = std::chrono::high_resolution_clock::now();
}

uint64_t Timer::nanoseconds() const {
auto T = reinterpret_cast<TimerImplementation *>(Impl);
return std::chrono::nanoseconds(T->End - T->Start).count();
}

} // namespace testing
} // namespace __llvm_libc
33 changes: 33 additions & 0 deletions libc/utils/testutils/Timer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//===-- Timer.h -------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_UTILS_TESTUTILS_TIMER_H
#define LLVM_LIBC_UTILS_TESTUTILS_TIMER_H

#include <stdint.h>

namespace __llvm_libc {
namespace testing {

class Timer {
void *Impl;

public:
Timer();
~Timer();

void start();
void stop();

uint64_t nanoseconds() const;
};

} // namespace testing
} // namespace __llvm_libc

#endif // LLVM_LIBC_UTILS_TESTUTILS_TIMER_H