summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile44
-rw-r--r--main.cpp29
-rw-r--r--string.cpp146
-rw-r--r--string.h73
4 files changed, 292 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..e3f62e8
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,44 @@
+BIN = string
+SRC = main.cpp string.cpp
+CC = g++
+CFLAGS = -Wall -std=gnu++98 -pedantic -MD
+DBGFLAGS = -g -O0
+ifdef DEBUG
+ CFLAGS += $(DBGFLAGS)
+else
+ CFLAGS += -O2 -march=native -mtune=native
+endif
+LDFLAGS = -lm
+
+OBJ_DIR = obj
+DEPS_DIR = obj
+BIN_DIR = bin
+
+CPP_FILES = $(filter %.cpp, $(SRC))
+DEP_FILES = $(addprefix $(DEPS_DIR)/, $(addsuffix .d, $(notdir $(subst .cpp,,$(SRC)))))
+OBJ_FILES = $(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(notdir $(subst .cpp,,$(SRC)))))
+
+INCL = -I/include
+
+define CPP_template
+$(1): $(2)
+ @mkdir -p $$(OBJ_DIR)
+ @mkdir -p $$(DEPS_DIR)
+ $$(CC) -c $$(CFLAGS) $$(INCL) $$< -o $$@
+endef
+
+all: $(BIN)
+
+$(foreach cppfile, $(CPP_FILES), $(eval $(call CPP_template, $(OBJ_DIR)/$(notdir $(subst .cpp,,$(cppfile))).o, $(cppfile))))
+
+$(BIN): $(OBJ_FILES)
+ @mkdir -p $(BIN_DIR)
+ $(CC) $(LDFLAGS) $(OBJ_FILES) -o $(BIN_DIR)/$@
+
+.PHONY: clean
+
+clean:
+ rm -rf $(OBJ_DIR)
+ rm -f $(BIN_DIR)/$(BIN)
+
+-include $(DEP_FILES)
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..b951358
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,29 @@
+#include "string.h"
+
+int main(int argc, char **argv)
+{
+ MyString mystr("alpha");
+ if (mystr.isSubstring("ph"))
+ {
+ cout << "true" << endl;
+ }
+ else
+ cout << "false" << endl;
+
+ MyString mystr1 = ", beta";
+ MyString mystr2 = ", charlie";
+ MyString mystr3 = ", delta";
+
+ mystr.concat(mystr1).concat(mystr2).concat(mystr3);
+ cout << mystr << endl;
+
+ MyString mystr4 = "hello";
+ mystr4.concat(", world!").concat(" goodbye");
+ cout << mystr4 << endl;
+
+ MyString mystr5 = "bro";
+ cout << mystr5 << endl;
+
+ return 0;
+}
+
diff --git a/string.cpp b/string.cpp
new file mode 100644
index 0000000..393368f
--- /dev/null
+++ b/string.cpp
@@ -0,0 +1,146 @@
+/* string.cpp
+ *
+ * Note: http://msdn.microsoft.com/en-us/magazine/cc163742.aspx
+ *
+ */
+
+#include "string.h"
+#include <sstream>
+
+MyString::MyString(int len) : str_(new char[len + 1]), length_(len)
+{
+}
+
+MyString::MyString(const char *str) : length_(strlen(str))
+{
+ str_ = new char[length_ + 1];
+ strcpy(str_, str);
+}
+
+MyString::MyString(const MyString& str) : str_(new char[str.length_ + 1]),
+ length_(str.length_)
+{
+ strcpy(str_, str.str_);
+}
+
+MyString::~MyString()
+{
+ delete[] str_;
+}
+
+int MyString::indexOf(char ch, int pos) const
+{
+ while (pos < length_)
+ {
+ if (str_[pos] == ch)
+ return pos;
+
+ pos++;
+ }
+
+ return -1;
+}
+
+bool MyString::isSubstring(const MyString& str) const
+{
+ if (length_ < str.length_)
+ return false;
+
+ int i, j, temp;
+
+ for (i = 0; i < length_; i++)
+ {
+ j = 0;
+ temp = i;
+ while ((j < str.length_) && (str_[temp] == str.str_[j]))
+ {
+ temp++;
+ j++;
+ }
+
+ if (j == str.length_)
+ return true;
+ }
+
+ return false;
+}
+
+bool MyString::isSubstring(const char *str) const
+{
+ int i, j, k;
+ for (i = 0; i < length_; i++)
+ {
+ j = i;
+ k = 0;
+ while (str_[j++] == str[k++])
+ ;
+
+ if (str[k-1] == '\0')
+ return true;
+ }
+
+ return false;
+}
+
+/* there are few ways to implement this */
+MyString& MyString::concat(const MyString& str)
+{
+ /* right way to do this would be to use realloc and double the buffer each
+ * we append something (if it's full)
+ */
+ MyString ret(length_ + str.length_);
+ strcpy(ret.str_, str_);
+ strcat(ret.str_, str.str_);
+
+ return (*this = ret);
+}
+
+MyString& MyString::concat(const char *str)
+{
+ char *newstr = new char[length_ + strlen(str) + 1];
+
+ strcpy(newstr, str_);
+ strcpy(newstr + length_, str);
+ delete[] str_;
+
+ length_ += strlen(str);
+ str_ = newstr;
+
+ return *this;
+}
+
+MyString& MyString::operator=(const MyString& rhs)
+{
+ /* don't do anything if object assigns itself */
+ if (this == &rhs)
+ return *this;
+
+ length_ = rhs.length_;
+ delete[] str_;
+ str_ = new char[ length_ + 1];
+ strcpy(str_, rhs.str_);
+
+ /* assignment operator requires this */
+ return *this;
+}
+
+bool operator==(const MyString& lhs, const MyString& rhs)
+{
+ if (lhs.length_ != rhs.length_)
+ return false;
+
+ if (strcmp(lhs.str_, rhs.str_) == 0)
+ return true;
+ else
+ return false;
+}
+
+/* seems like the ostream& in front has nothing to do with dereferencing a pointer,
+ * but it seems like the & is placed there so we can make consecutive overloaded
+ * calls to cout, effectively chaining all of the calls
+ */
+ostream& operator<<(ostream& ostr, const MyString& rhs)
+{
+ return (ostr << rhs.str_);
+}
+
diff --git a/string.h b/string.h
new file mode 100644
index 0000000..dc9ebfc
--- /dev/null
+++ b/string.h
@@ -0,0 +1,73 @@
+/* string.h
+ *
+ */
+
+#ifndef _MYSTRING_
+#define _MYSTRING_
+
+#include <cstring>
+#include <iostream>
+
+using namespace std;
+
+class MyString
+{
+ friend bool operator==(const MyString&, const MyString &);
+ friend ostream& operator<<(ostream&, const MyString &);
+
+ private:
+ char *str_;
+ int length_;
+ MyString(int);
+
+ public:
+ MyString();
+ MyString(char);
+ MyString(const char *);
+ MyString(const MyString &);
+ MyString& operator=(const MyString &);
+ ~MyString();
+
+ int length() const;
+ int indexOf(char, int = 0) const;
+ bool isSubstring(const MyString &) const;
+ bool isSubstring(const char *) const;
+ MyString& concat(const MyString &);
+ MyString& concat(const char *);
+ void printStr(void) const;
+
+ MyString operator!() const;
+ char& operator[](int);
+ char operator[](int) const;
+};
+
+bool operator==(const MyString&, const MyString &);
+ostream& operator<<(ostream&, const MyString &);
+
+inline MyString::MyString()
+{
+ length_ = 0;
+ str_ = new char[1];
+ str_[0] = '\0';
+}
+
+inline MyString::MyString(char ch)
+{
+ length_ = 1;
+ str_ = new char[2];
+ str_[0] = ch;
+ str_[1] = '\0';
+}
+
+inline int MyString::length() const
+{
+ return length_;
+}
+
+inline void MyString::printStr(void) const
+{
+ cout << "length: " << length_ << ", value: \"" << str_ <<"\"";
+}
+
+#endif
+