mmap with Boost IOStreams: A minimalist’s example

The following C++ program uses boost::iostreams to memory-map a file, read it’s content into a std::string and print it to cout.

It provides a minimal example of how to use the boost::iostream portable mmap functionality.

//Compile like this: g++ -o mmap mmap.cpp -lboost_iostreams
#include <boost/iostreams/device/mapped_file.hpp>
#include <iostream>
#include <string>
using namespace std;
using namespace boost::iostreams;

int main(int argc, char** argv) {
   //Initialize the memory-mapped file
   mapped_file_source file(argv[1]);
   //Read the entire file into a string
   string fileContent(file.data(), file.size());
   //Print the string
   cout << fileContent;
   //Cleanup
   file.close();
}

How to compile & install libc++ on Linux

Problem:

You want to compile and install libc++ (sometimes also named libcxx), but CMake complains with this error message

CMake Error at cmake/Modules/MacroEnsureOutOfSourceBuild.cmake:7 (message):
libcxx requires an out of source build. Please create a separate</em>

build directory and run 'cmake /path/to/libcxx [options]' there.
Call Stack (most recent call first):
 CMakeLists.txt:24 (MACRO_ENSURE_OUT_OF_SOURCE_BUILD)
CMake Error at cmake/Modules/MacroEnsureOutOfSourceBuild.cmake:8 (message):
 In-source builds are not allowed.

CMake would overwrite the makefiles distributed with Compiler-RT.
 Please create a directory and run cmake from there, passing the path
 to this source directory as the last argument.
 This process created the file `CMakeCache.txt' and the directory `CMakeFiles'.
 Please delete them.
Call Stack (most recent call first):
 CMakeLists.txt:24 (MACRO_ENSURE_OUT_OF_SOURCE_BUILD)

Read more

Compiling LevelDB as LLVM binary on Linux

Some time ago I wrote a guide on how to compile and install LevelDB on Linux.

Recently I’m desperately trying to get into LLVM and a tutorial series on how to use LLVM with C/C++ is coming shortly.

As I’m using LevelDB in many of my projects I’d like a way of generating a LLVM IR (intermediate representation) of the LevelDB C++ source – I could link a LLVM program to the native binary, but in order to profit from LLVMs features I suppose using IRs for as many dependencies as possible is the way to go.

Generally there are two ways to go:

  1. Use the g++ LLVM backend
  2. Use clang++

I usually tend to use clang++ for LLVM tasks because even with colorgcc and some recent improvements in gcc error message generation I prefer the clang++ error messages, even if I have way more experience with gcc error messages. Additionally the g++ with LLVM backend does seem to have some bugs, including interpreting -emit-llvm as -e -m -i …, plus recent distribution versions don’t work too well with the LLVM gold plugin and it has proved difficult to tell GCC reliably that it shall use llvm-ld as linker.

Read more

A text-to-Brainfuck/RNA converter in ANSI C99

Brainfuck encoder

The following small ANSI C99 program reads a String from stdin and prints out a Brainfuck program that prints the same String on stdout.

Compile using gcc -o bf bf.c

Use it like this:

cat my.txt | ./bf > my.bf

Source code:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
    unsigned char c;
    unsigned char curval = 0;
    //Initialize reg+1 with 8
    while(1) {
        c = getchar();
        if(feof(stdin)) {break;}
        while(curval != c) {
            if(curval < c) {
                putchar('+');
                curval++;
            } else if(curval > c) {
                putchar('-');
                curval--;
            }
        }
        putchar('.');
    }
}

How does it work?

Basically it uses just one of the registers of the Brainfuck Turing machine and incremets or decrements the register to be able to print out the next byte. It doesn’t use any of the more ‘advanced’ features in Brainfuck like loops.

Read more

C++11 : Iterate over smart pointers using foreach loop

Problem:

In C++11 you want to iterate over a smart pointer (auto_ptr, shared_ptr, …). collection, say a std::vector, using the new for loop syntax.

Let’s try it out:

using namespace std;
shared_ptr<vector<int> > smartptr(/* A ptr to your vector */);
for(int s : smartptr) {
    /* do something useful */
}

When trying to compile this code, GCC emits the following error message (other lines are omitted for the sake of simplicity)

error: no matching function for call to 'begin(std::shared_ptr<std::vector<int> >&)'
error: no matching function for call to 'end(std::shared_ptr<std::vector<int> >&)'

or, when LANG=de is set:

Fehler: keine passende Funktion für Aufruf von »begin(std::shared_ptr<std::vector<int> >&)«
Fehler: keine passende Funktion für Aufruf von »end(std::shared_ptr<std::vector<int> >&)«

Read more