summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile18
-rw-r--r--README.md140
-rw-r--r--future-example.cpp26
-rw-r--r--random-example.cpp36
-rw-r--r--regex-match-example.cpp42
-rw-r--r--regex-replace-example.cpp38
-rw-r--r--regex-search-example.cpp34
7 files changed, 334 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..ac95c73
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,18 @@
+# G++ version 4.9 or later required for
+# all these to work, see README.
+CXX=g++-4.9
+CXXFLAGS=-g -O0 -Wall -Wextra -std=c++11
+
+SRC=\
+ future-example.cpp \
+ regex-match-example.cpp \
+ regex-search-example.cpp \
+ regex-replace-example.cpp \
+ random-example.cpp
+
+PROG=$(SRC:.cpp=)
+
+all: $(PROG)
+
+clean:
+ rm -f $(PROG)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..29eb65b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,140 @@
+C++11 Examples
+--------------
+
+This repository contains short examples of some
+of the modern (c++11/14) features in C++/STL.
+
+
+Regular Expressions
+-------------------
+
+Note:
+At the time of this writing (July-2015), not all compilers
+can handle all regex functionality (also depends on the
+used libstdc++ version).
+
+1. g++ v4.8 - regex_match works.
+ regex_search compiles but crashes.
+ regex_replace does not compile.
+
+2. g++ v4.9 - regex_{match,search,replace} compile and work.
+
+3. clang 3.5 (build based on the libstdc++ for g++-4.8) -
+ same issues as g++ v4.8.
+
+
+Building and testing
+====================
+
+run `make` to compile and run all tests.
+If all worked, the output should be:
+
+
+To build using a different compiler, run `make CXX=g++-4.8` (or
+`make CXX=clang++-3.5`, etc.).
+
+To clean run `make clean`.
+
+
+Compilation Errors - regex_replace
+==================================
+
+If you get the following compilation error when compiling `test-replace.cpp`:
+
+ test-replace.cpp:13:16: error: no matching function for call to 'regex_replace'
+ std::cout << std::regex_replace (s,e,"sub-$2");
+ ^~~~~~~~~~~~~~~~~~
+ /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/regex.h:2182:5: note:
+ candidate template ignored: could not match 'basic_string<type-parameter-0-1,
+ char_traits<type-parameter-0-1>, allocator<type-parameter-0-1> >' against
+ 'char const[7]'
+ regex_replace(const basic_string<_Ch_type>& __s,
+
+It means the compiler/libstdc does *not* support `regex_replace` function.
+Upgrade compiler/libstdc or don't use this function.
+
+
+Abort errors - regex_search
+===========================
+
+If you get the following error when running `test-search`:
+
+ $ ./test-search
+ terminate called after throwing an instance of 'std::regex_error'
+ what(): regex_error
+ Aborted (core dumped)
+
+It means the compiler/libstdc++ does *not* implement `regex_search`
+(it only contains the stub declarations).
+Upgrade compiler/libstdc or don't use this function.
+
+
+Runtime errors - wrong GLIBC versions
+=====================================
+
+If you get the following errors when running `test-replace`:
+
+ $ ./test-replace
+ ./test-replace: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./test-replace)
+
+It means the program was compiled using a newer compiler (and non-default libstdc++)
+and requires additional settings to locate and use the correct one.
+
+To see which versions of the C++ standand library are available on your
+system, search for `libstdc++.so` file, like so (you might need to
+use `locate` instead of `mlocate`, depending on your sysystem):
+
+ $ mlocate libstdc++.so | grep '\.so$'
+ /usr/lib/gcc/mips-linux-gnu/4.3.5/libstdc++.so
+ /usr/lib/gcc/mips-linux-gnu/4.3.5/64/libstdc++.so
+ /usr/lib/gcc/mips-linux-gnu/4.3.5/n32/libstdc++.so
+ /usr/lib/gcc/x86_64-linux-gnu/4.4/libstdc++.so
+ /usr/lib/gcc/x86_64-linux-gnu/4.4/32/libstdc++.so
+ /usr/lib/gcc/x86_64-linux-gnu/4.6/libstdc++.so
+ /usr/lib/gcc/x86_64-linux-gnu/4.6/32/libstdc++.so
+ /usr/lib/gcc/x86_64-linux-gnu/4.8/libstdc++.so
+ /usr/lib/gcc/x86_64-linux-gnu/4.8/32/libstdc++.so
+ /usr/lib/gcc/x86_64-linux-gnu/4.8/x32/libstdc++.so
+ /usr/local/lib32/libstdc++.so
+ /usr/local/lib64/libstdc++.so
+
+Often, files in `/usr/lib/*` are automatically searched for and
+used by default, but the ones under `/usr/local/*` are not.
+
+1. check which `libstdc++` file is used by default:
+
+ $ ldd ./test-replace | grep libstdc
+ libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f8deb6b9000)
+
+2. check which version is the default library ('version' is checked
+ indirectly: The GNU standard library exports symbols that corresponds to the
+ implemented version):
+
+ $ nm -D /usr/lib/x86_64-linux-gnu/libstdc++.so.6 \
+ | grep GLIBCXX | sort -K3V,3 | tail -n1
+ 0000000000000000 A GLIBCXX_3.4.19
+
+ As shown, the default library implements upto version 3.4.19,
+ and the compiled binary requires version 3.4.20.
+
+ It is very likely that the libraries under `/usr/local/lib64/` provide this
+ newer version (on my system, they were compiled from source, and therefor
+ installed under `/usr/local`):
+
+ $ nm -D /usr/local/lib64/libstdc++.so.6 \
+ | grep GLIBCXX | sort -k3V,3 | tail -n1
+ 0000000000000000 A GLIBCXX_3.4.20
+
+3. Use `LD_LIBRARY_PATH` to load a different library than the default:
+
+ $ LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH ./test-replace
+
+4. To permanently include these libraries, consider adding a new file
+ to `/etc/ld.so.conf.d/` and re-run `ldconfig`.
+ NOTE: this might have adverse effect on your system, as the these
+ libraries will might override the system's default libraries -
+ only do so if you know what you're doing.
+
+ $ echo '/usr/local/lib64' | sudo tee /etc/ld.so.conf.d/local-lib64.conf
+ $ sudo ldconfig -v
+
diff --git a/future-example.cpp b/future-example.cpp
new file mode 100644
index 0000000..e5df3a5
--- /dev/null
+++ b/future-example.cpp
@@ -0,0 +1,26 @@
+// async example
+#include <iostream> // std::cout
+#include <future> // std::async, std::future
+
+// a non-optimized way of checking for prime numbers:
+bool is_prime (int x) {
+ std::cout << "Calculating. Please, wait...\n";
+ for (int i=2; i<x; ++i) if (x%i==0) return false;
+ return true;
+}
+
+int main ()
+{
+ // call is_prime(313222313) asynchronously:
+ std::future<bool> fut = std::async (is_prime,313222313);
+
+ std::cout << "Checking whether 313222313 is prime.\n";
+ // ...
+
+ bool ret = fut.get(); // waits for is_prime to return
+
+ if (ret) std::cout << "It is prime!\n";
+ else std::cout << "It is not prime.\n";
+
+ return 0;
+}
diff --git a/random-example.cpp b/random-example.cpp
new file mode 100644
index 0000000..484bc6f
--- /dev/null
+++ b/random-example.cpp
@@ -0,0 +1,36 @@
+#include <iostream>
+#include <random>
+
+using namespace std;
+
+int main()
+{
+ const int iterations = 1000;
+
+ mt19937 gen;
+ normal_distribution<double> norm(5.0,2.0);
+ exponential_distribution<double> expo(3.5);
+ negative_binomial_distribution<int> negbin(3,0.5);
+ uniform_int_distribution<int> uint(0,9);
+ uniform_real_distribution<double> ureal(0.0,5.0);
+
+
+ cout << "x\t"
+ << "normal\t"
+ << "exponential\t"
+ << "Neg-Binomial\t"
+ << "Unif-Int\t"
+ << "Unif-Real"
+ << endl;
+
+ for (int i=0;i<iterations;++i) {
+ cout << (i+1) << "\t"
+ << norm(gen) << "\t"
+ << expo(gen) << "\t"
+ << negbin(gen) << "\t"
+ << uint(gen) << "\t"
+ << ureal(gen) << "\t"
+ << endl;
+ }
+ return 0;
+}
diff --git a/regex-match-example.cpp b/regex-match-example.cpp
new file mode 100644
index 0000000..ab71e66
--- /dev/null
+++ b/regex-match-example.cpp
@@ -0,0 +1,42 @@
+// regex_match example
+// NOTE:
+// std::regex_match matches the ENTIRE string
+// (as if with '^' and '$' anchors).
+// Use std::regex_search to match partial strings.
+#include <iostream>
+#include <string>
+#include <regex>
+#include <cassert>
+
+using namespace std;
+
+int main ()
+{
+ // should match - regex accepts the entire string
+ bool b = regex_match("chromium",regex("chr.*"));
+ assert(b);
+
+ // should not match - regex does not accept entire
+ // string, yet 'regex_match' requires entire input to match
+ // (unlike regex_search).
+ b = regex_match("chromium",regex("chr"));
+ assert (!b);
+
+
+ // match on 'char*' - use 'cmatch'
+ const char cstr[] = "hello world 42";
+ cmatch cm;
+ regex re(".*?(\\d+)");
+ b = regex_match (cstr,cm,re);
+ assert(b);
+ cout << "const char - matched number: " << cm[1] << endl;
+
+ // match on 'string' - use 'smatch'
+ const string s("hello world 41");
+ smatch sm;
+ b = regex_match (s,sm,re);
+ assert(b);
+ cout << "string - matched number: " << sm[1] << endl;
+
+ return 0;
+}
diff --git a/regex-replace-example.cpp b/regex-replace-example.cpp
new file mode 100644
index 0000000..08c2420
--- /dev/null
+++ b/regex-replace-example.cpp
@@ -0,0 +1,38 @@
+// regex_replace example
+#include <iostream>
+#include <string>
+#include <regex>
+#include <iterator>
+
+using namespace std;
+
+int main ()
+{
+ string s ("hello wherever wholly heroic howlling herring");
+
+ // find words starting with 'he'.
+ // words containing 'he' not at the beginning should not be replaced.
+ regex e ("\\bhe");
+
+ // replace ALL 'he' with 'HE'
+ // (only in
+ cout << "upper-case HE (all): "
+ << regex_replace(s,e,"HE")
+ << endl;
+
+ // replace just one (the first) 'he with 'HE'
+ cout << "upper-case HE (one): "
+ << regex_replace(s,e,"HE", regex_constants::format_first_only)
+ << endl;
+
+
+ string s2("hello world");
+ // find two words separated by spaces
+ regex e2("(\\w+)\\s+(\\w+)");
+ // Replace their order
+ cout << "swapped words: "
+ << regex_replace (s2,e2,"$2 $1")
+ << endl;
+
+ return 0;
+}
diff --git a/regex-search-example.cpp b/regex-search-example.cpp
new file mode 100644
index 0000000..f77a566
--- /dev/null
+++ b/regex-search-example.cpp
@@ -0,0 +1,34 @@
+// regex_search example
+// NOTE:
+// std::regex_match matches the ENTIRE string
+// (as if with '^' and '$' anchors).
+// Use std::regex_search to match partial strings.
+#include <iostream>
+#include <string>
+#include <regex>
+
+using namespace std;
+
+int main ()
+{
+ string s ("synchronized chrysalis monochrome chromium chrX");
+ smatch m;
+ regex e ("\\b(chr)([^ ]*)");
+
+ cout << "words starting with 'chr':" << endl;
+
+ while (regex_search (s,m,e)) {
+ // The regex contained 2 groups, hence 'm' will contain
+ // Three items: [0] = Entire match
+ // [1] = The content of the first group ('chr')
+ // [2] = The content of the second group
+ cout << "word: '" << m[0] << "'"
+ << " suffix: '" << m[2] << "'" << endl;
+
+ // To find the next match, search in the suffix
+ // (the characters left after this match)
+ s = m.suffix().str();
+ }
+
+ return 0;
+}