From 27ec58c7eddc977387693359854b1ad95c0b7cc3 Mon Sep 17 00:00:00 2001 From: Mathias Waack Date: Sat, 13 Sep 2014 19:48:45 +0200 Subject: [PATCH] initial commit --- CMakeLists.txt | 22 +++++++++++++++ stringwriter.cpp | 8 ++++++ stringwriter.h | 66 ++++++++++++++++++++++++++++++++++++++++++++ teststringwriter.cpp | 61 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 157 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 stringwriter.cpp create mode 100644 stringwriter.h create mode 100644 teststringwriter.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f4cb5e4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,22 @@ +project(stringwriter) +cmake_minimum_required(VERSION 2.8) + +include(CheckCXXCompilerFlag) +check_cxx_compiler_flag(-std=c++11 HAS_STD_CPP11) +if (HAS_STD_CPP11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +else() + check_cxx_compiler_flag(-std=c++0x HAS_STD_CPP0X) + if (HAS_STD_CPP0X) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") + else() + message(WARNING + "C++ Compiler does not support the -std=c++11 flag. If you get compile errors make" + "sure you have a compiler that supports C++11.") + endif() +endif() +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wconversion") + +aux_source_directory(. SRC_LIST) +add_executable(${PROJECT_NAME} ${SRC_LIST}) + diff --git a/stringwriter.cpp b/stringwriter.cpp new file mode 100644 index 0000000..06d05af --- /dev/null +++ b/stringwriter.cpp @@ -0,0 +1,8 @@ +#include "stringwriter.h" +#include + +StringWriter strstr(StringWriter& haystack, const char *needle) +{ + auto idx = haystack.str.find(needle, haystack.offset); + return StringWriter(haystack.str, idx); +} diff --git a/stringwriter.h b/stringwriter.h new file mode 100644 index 0000000..4f40509 --- /dev/null +++ b/stringwriter.h @@ -0,0 +1,66 @@ +#ifndef STRCLASS_H +#define STRCLASS_H + +#include +#include +#include +#include + +/** StringWriter wraps a std::string into an object which looks like a c-string char* */ +class StringWriter +{ +public: + using size_type = std::string::size_type; + static const size_type npos = std::string::npos; + friend StringWriter strstr(StringWriter& haystack, const char *needle); +private: + std::string& str; //< the string we working on + size_type offset; //< the current offset in this string +public: + StringWriter(std::string& s, size_type i =0) + : str(s), offset(i) + {} + StringWriter operator[](size_type i) + { + assert(i <= str.size()); + return StringWriter(this->str, offset+i); + } + + StringWriter operator+=(size_type i) + { + offset += i; + return *this; + } + + StringWriter operator+(size_type i) + { + return StringWriter(this->str, offset+i); + } + + StringWriter& operator*() + { + return *this; + } + + StringWriter& operator=(char c) + { + assert(offset < str.size()); + str[offset] = c; + return *this; + } + + bool operator==(char c) const + { + if (offset == str.size()) return c == 0; + else return str[offset] == c; + } + + explicit operator bool() const + { + return !operator==(0); + } +}; + +StringWriter strstr(StringWriter& haystack, const char *needle); + +#endif /* STRCLASS_H */ diff --git a/teststringwriter.cpp b/teststringwriter.cpp new file mode 100644 index 0000000..a2dbd4c --- /dev/null +++ b/teststringwriter.cpp @@ -0,0 +1,61 @@ +#define BOOST_TEST_MAIN +#include +#include +#include +#include +#include "stringwriter.h" + +using namespace std; + +template +T& strtransform(const std::string& ref, T& str, FromString fs, ToString ts, ToCharPtr ptr) +{ + cout << "transform" << endl; + fs(str,ref); + BOOST_CHECK(ts(str) == ref); + auto c1 = ptr(str); + c1 += 4; + auto c1x = c1 + 3; + *c1 = 'x'; + *c1x = 'y'; + for(unsigned i=0; c1[i]; ++i) + if (c1[i] == 'i') { + c1[i] = 'a'; + //cout << i << endl; + } + while (auto c = strstr(c1, "\n")) { + *c = '_'; + } + //c1x[100] = 'z'; <-- will crash with char*, will checked with StringWriter + BOOST_CHECK(ts(str) != ref); + return str; +} + +BOOST_AUTO_TEST_SUITE( StringWriter ) + +BOOST_AUTO_TEST_CASE(testStringWriter) +{ + std::string s{"This a text\nwith several line\nbreaks and some longer lines\n and shorter ones."}; + + std::string s2; + std::string s2x = strtransform(s, s2, + [](std::string& str, const std::string& s){ str = s; }, + [](const std::string& s){ return s; }, + [](std::string& s){ return StringWriter(s,0); } + ); + cout << s2 << endl; + + char *s3 = new char[s.size()+1]; + strtransform(s, s3, + [](char *str, const std::string& s){ strcpy(str,s.c_str()); }, + [](char *s){ return std::string(s); }, + [](char *s){ return s; } + ); + cout << s3 << endl; + + BOOST_CHECK(std::string(s3) == s2); + BOOST_CHECK(s2 == s2x); +} + +BOOST_AUTO_TEST_SUITE_END() +