Last active
November 18, 2020 15:05
-
-
Save sophec/4a220a0cd5fb8167fca33de5aba8ad10 to your computer and use it in GitHub Desktop.
C-style buffer wrapper class for C++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef CXX_BUFFER_HPP_ | |
#define CXX_BUFFER_HPP_ | |
#include <functional> | |
#include <cstdlib> | |
#include <cstring> | |
#include <system_error> | |
#include <stdexcept> | |
#include <initializer_list> | |
template<typename T> | |
class buffer { | |
private: | |
T* buf = nullptr; | |
std::size_t len = 0; | |
public: | |
buffer(T* _buf, std::size_t _len): len(_len) { | |
if (_len != 0) { | |
buf = (T*)calloc(_len, sizeof(T)); | |
if (buf == nullptr) { | |
throw std::system_error(std::error_code(ENOMEM, std::generic_category())); | |
} else { | |
memcpy((void*)buf, (void*)_buf, sizeof(T) * _len); | |
} | |
} | |
} | |
buffer(std::size_t _len): len(_len) { | |
buf = (T*)calloc(_len, sizeof(T)); | |
if (buf == nullptr) { | |
throw std::system_error(std::error_code(ENOMEM, std::generic_category())); | |
} | |
} | |
buffer(std::initializer_list<T> li) { | |
buf = (T*)calloc(li.size(), sizeof(T)); | |
if (buf == nullptr) { | |
throw std::system_error(std::error_code(ENOMEM, std::generic_category())); | |
} | |
len = li.size(); | |
std::size_t n = 0; | |
for (const T* it = std::begin(li); it != std::end(li); it++, n++) { | |
buf[n] = *it; | |
} | |
} | |
buffer() {} | |
~buffer() { | |
if (buf) { | |
free(buf); | |
} | |
} | |
std::size_t length() const { | |
return len; | |
} | |
std::size_t size() const { | |
return len; | |
} | |
T& at(std::size_t n) { | |
if (n >= len) { | |
throw std::range_error("buffer index out of bounds!"); | |
} | |
return buf[n]; | |
} | |
const T& at(std::size_t n) const { | |
return this->at(n); | |
} | |
T& operator[] (std::size_t n) { | |
return this->at(n); | |
} | |
const T& operator[] (std::size_t n) const { | |
return this->at(n); | |
} | |
T& operator* () { | |
if (buf == nullptr) { | |
throw std::range_error("cannot dereference null pointer!"); | |
} | |
return *buf; | |
} | |
const T& operator* () const { | |
if (buf == nullptr) { | |
throw std::range_error("cannot dereference null pointer!"); | |
} | |
return *buf; | |
} | |
void resize(std::size_t n) { | |
if (realloc(buf, n * sizeof(T)) == nullptr) { | |
throw std::system_error(std::error_code(ENOMEM, std::generic_category())); | |
} else { | |
if (n > 0) { | |
memset((void*)(buf + len * sizeof(T)), 0, (n - len) * sizeof(T)); | |
} else { | |
buf = nullptr; | |
} | |
len = n; | |
} | |
} | |
void fill(const T& val) { | |
for (std::size_t i = 0; i < len; i++) { | |
buf[i] = val; | |
} | |
} | |
void map(std::function<T(T)> fn) { | |
for (std::size_t i = 0; i < len; i++) { | |
buf[i] = fn(buf[i]); | |
} | |
} | |
template<typename nT> | |
operator nT* () { | |
return static_cast<nT*>(buf); | |
} | |
T* begin() { | |
return buf; | |
} | |
const T* begin() const { | |
return (const T*)buf; | |
} | |
T* end() { | |
return buf + len; | |
} | |
const T* end() const { | |
return (const T*)(buf + len); | |
} | |
}; | |
#endif /* CXX_BUFFER_HPP_ */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdio> | |
#include <iostream> | |
#include <cstring> | |
#include <cstdlib> | |
#include <system_error> | |
#include <stdexcept> | |
#include <initializer_list> | |
#include <functional> | |
#include "buf.hpp" | |
int main(void) { | |
buffer<char> mybuf(64); | |
scanf("%64s", (char*)mybuf); | |
printf("%s\n", (char*)mybuf); | |
buffer<int> mybuf2{1, 2, 3, 4, 5, 6}; | |
mybuf2.map([](auto x) { return x*2; }); | |
for (const auto& v : mybuf2) { | |
std::cout << v << '\n'; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment