C++の組み込み型はクラスとして扱える

タイトル通り。

doubleという名前のクラスと思って以下でdoubleの値を生成できる。

double a = double()
double b = double(1.0)

ポインタも同様のことが可能だがtypedefが必要

double* a = double*(); //error
double* b = (double*)(); //error
typedef double* pointer;
double* c = pointer();

#include <iostream>

struct Test {
    typedef double value_type;
    typedef double* pointer_type;
};

void test(double test) {
    std::cout << "double" << std::endl;
}

void test(Test::value_type*) {
    std::cout << "pointer" << std::endl;
}

int main(int argc, char const* argv[])
{
    double a = double();
    double b = double(1.0);
    double c = double(b);
    std::cout << a << ", " << b << ", " << c<< std::endl;
    //実行結果
    //0, 1, 1
    
    test(Test::value_type());
    test(Test::pointer_type());
    //実行結果
    //double
    //pointer

    //double *d = (double*)(); //error
    double *d = Test::pointer_type();
    double *e = Test::pointer_type(&a);

    std::cout << d << ", " << e << std::endl;
    //実行結果
    //0, 0x7fff57530970


    return 0;
}

ディレクトリ以下の特定ディレクトリを除外しファイル列挙

特定のディレクトリを除外して、カレントディレクトリ以下のファイルを列挙する。例えば、includeを除いて、.hファイルを全部列挙。

findを使って以下のようにかける。

find . -type d -name "include" -prune -o -name "*.h" -print

列挙したファイルのファイル名とカレントディレクトリからの相対パスbasenamedirnameで得られる。

#!/bin/sh

FILEPATHS=`find . -type d -name "include" -prune -o -name "*.h" -print` 
for filepath in $FILEPATHS; do
    BASEPATH=`basename $filepath`
    DIRNAME=`dirname $filepath`
    echo $BASEPATH
    echo $DIRNAME
done

参考

findコマンドで特定のディレクトリ以下を無視する方法 - mollifier delta blog

boost::bindとboost::functionをメンバ関数に使う

タイトル通り。

boost::bindメンバ関数を指定すると、第一引数にクラスを引数に取る関数として解釈される。

#include <iostream>

#include <boost/function.hpp>
#include <boost/bind.hpp>

struct LinearExtrapolation {
    LinearExtrapolation(
        const double leftPoint,
        const double leftValue,
        const double rightPoint,
        const double rightValue)
        :
        _leftPoint(leftPoint),
        _leftValue(leftValue),
        _slope((rightValue - leftValue) / (rightPoint - leftPoint)){}
    ~LinearExtrapolation(){};

    //! linear extrapolation.
    double operator() (const double x) const {
        return (x - _leftPoint) * _slope + _leftValue;
    }

    //! differentail of operator()
    double differential(const double x) const {
        return x * _slope;
    }

private:
    const double _leftPoint;
    const double _leftValue;
    const double _slope;
};

/**
 * @brief Functor example.
 */
struct Functor1 {
    double operator() (
        const double time,
        const double state,
        const LinearExtrapolation& extrapolation) const {
        return time * extrapolation(state);
    }
};

/**
 * @brief differetinal of Functor1 w.r.t. state variable.
 */
struct Functor2 {
    double operator() (
        const double time,
        const double state, 
        const LinearExtrapolation& extrapolation) const {
        return time * extrapolation.differential(state);
    }
};


int main(int argc, char const* argv[])
{
    LinearExtrapolation extrapolation(-10.0, -20.0, 10.0, 20.0);
    Functor1 functor1;
    Functor2 functor2;

    boost::function<double (double, double)> function1 = 
        boost::bind(&Functor1::operator(), &functor1, _1, _2, extrapolation);
    boost::function<double (double, double)> function2 = 
        boost::bind(&Functor2::operator(), &functor2, _1, _2, extrapolation);

    std::cout << function1(1.0, 0.0) << std::endl;//output 0
    std::cout << function2(1.0, 2.0) << std::endl;//output 4

    return 0;
}

MacでHaskell

Haskellを使えるようにする。

haskell-platformというのがあるのでそれをインストールすればHaskellを使うのに必要なものが一通りインストールされる。

Macportsがあれば以下でおっけー。

sudo port install haskell-platform

で良い。

haskellのパッケージ管理ツールcabalもインストールされるので、これで必要なライブラリをインストールする。

C++でClass内のtypedefにもpublic, privateは適用される

タイトル通りだが、以下がサンプル。

テンプレートを使う時に重要になるのでメモ。

class Test {
private:
    typedef double private_real;

public:
    typedef double public_real;
};


int main(int argc, char const* argv[])
{   

    Test::public_real public_real = 1.0;
    //Test::private_real private_real = 2.0; //compile error
    
    return 0;
}

Macportsでcppunitのインストール

Macportscppunitをインストールする。幸いなことに、最新版がインストールできそう。

sudo port install cppunit

でOK。

サンプルを実行

正しくインストールされているかサンプルを実行する。

サンプルはcppunitのソースファイルのexampleを利用するので、下記からDLする。

CppUnit - C++ port of JUnit - Browse /cppunit/1.12.1 at SourceForge.net

cppunit1.12.1をDLしたとする。適当なディレクトリに以下のコマンドで解凍。

tar xjvf cppunit-1.12.1.tar.gz

解凍したディレクトリに移動しconfigureを実行する。

cd cppunit-1.12.1
./configure

次にサンプルのディレクトリに移動する。ここではcppunittestを例にする。

やや強引であるが次の手順でコンパイルする。

cd examples/cppunittest
make cppunittestmain

を実行するとライブラリがビルドできないと起こられるが、cppunittestのコンパイルは全て通り、カレントディレクトリに*.oのオブジェクトファイルが生成されている。

cppunitのライブラリはmacportsでインストールされているので後はライブラリをリンクして実行ファイルを作る。

g++ *.o -o cppunittest -lcppunit
./cppunittest

これで実行可能。他のexamplesも同様の方法で実行できる。