Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Mathias Waack authored and Mathias Waack committed Sep 13, 2014
0 parents commit 27ec58c
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 0 deletions.
22 changes: 22 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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})

8 changes: 8 additions & 0 deletions stringwriter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "stringwriter.h"
#include <sstream>

StringWriter strstr(StringWriter& haystack, const char *needle)
{
auto idx = haystack.str.find(needle, haystack.offset);
return StringWriter(haystack.str, idx);
}
66 changes: 66 additions & 0 deletions stringwriter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#ifndef STRCLASS_H
#define STRCLASS_H

#include <string>
#include <string.h>
#include <iosfwd>
#include <cassert>

/** 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 */
61 changes: 61 additions & 0 deletions teststringwriter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#define BOOST_TEST_MAIN
#include <boost/test/included/unit_test.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <iostream>
#include <cstring>
#include "stringwriter.h"

using namespace std;

template<typename T, typename FromString, typename ToString, typename ToCharPtr>
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()

0 comments on commit 27ec58c

Please sign in to comment.