顯示具有 Boost 標籤的文章。 顯示所有文章
顯示具有 Boost 標籤的文章。 顯示所有文章

boost.test BOOST_CHECK_EXCEPTION 竟然不支援 lambda

如題 BOOST_CHECK_EXCEPTION 竟然不支援用 lambda 寫 predicator ...
	
    BOOST_CHECK_EXCEPTION(
        p.parseString("---\n---"),
        durin::yaml::ParserException, 
        []( const durin::yaml::ParserException& ex ) {
        	return ex.what() == std::string( "Double DocBegin" );
        });
	
Feel so sad ...

BoostPro 要關門了?!

在 Boost mail list 上看到的消息:

http://lists.boost.org/Archives/boost/2013/01/200634.php


Subject: [boost] Future of Boost Windows Installers
From: Dave Abrahams (dave_at_[hidden])
Date: 2013-01-31 14:42:33

Hi,

As many of you already know, I'm going to work at Apple in late
February, and BoostPro is closing its doors. For many years, the Boost
Getting Started Guide has suggested that Windows users pop over to
BoostPro's website and use the latest installer to get Windows binaries.
We'd like to donate to the community the technology used to build those
installers. If anyone would like to pick up the job of creating them,
we'd be happy to offer guidance.

Right now I'm on a plane where an uplink to GitHub is creeping along at
4KB/s, so I've been pushing the stuff up in bits and pieces and the
latest stuff isn't up there, but it's going to
http://github.com/boostpro/installer and will be complete within 24 hours.

Whatever happens with this installer code, someone is going to need to
update the Getting Started Guide, either to point at the installer's new
home, or to remove references to it.

-- 
Dave Abrahams
BoostPro Computing                  Software Development        Training
http://www.boostpro.com             Clang/LLVM/EDG Compilers  C++  Boost

BoostPro 是幾位 C++ 大師組成的教學顧問團隊,BoostPro 上有他們的黃金陣容的介紹:

  • Dave Abrahams
    多年來致力於 C++ 標準制定和 Boost 推廣維護,貢獻了很多 Boost libraries、2001 年創辦 BoostPro 、
  • Joel de Guzman
    Boost.Spirit 、 Boost.Fusion 和 Boost.Phoneix 的作者。看過 Spirit 精妙的 C++ expression templates 魔術後,很難不對作者留下深刻印象。
  • Jeremy Siek
    六個 Boost libraries 的作者,很早就在 Boost 裡頭提供一套 concept check 的人。

嗯, Apple 這幾年應該算是最力挺 native code 的大型軟體公司(硬體公司?!),旗下的 LLVM、Clang 等 open source projects 不說,還雇用了 Doug Gregor (Modules for C++)、Howard Hinnant(libcxx 作者) 等神人在為更底層的基礎扎根,曾幾何時,竟然要喊聲: Apple 加油啊~

Boost.Program_options – Tutorial – Option Details and Multiples Sources

Vocabulary

  1. Program options, options
  2. pair. (name, value)
  3. Token
  4. Position options
  5. Composing options

Option Details

沒錯,你得到它了!option value 不僅只侷限於 int 型別,此外還可以有其它下面的屬性(proerties)。完整程式可以在

example/options_description.cpp

找到。

想像你在寫一個 compiler ,你可以設定它的 options:

  1. Otimization level
  2. Include paths
  3. Input files
  4. 其它做些有趣的事。

下面的程式碼試著描述這些 options :

int opt;
po::options_description desc("Allowed options");
desc.add_options()
    ("help", "produce help message")
    ("optimization", po::value<int>(&opt)->default_value(10), 
  "optimization level")
    ("include-path,I", po::value< vector<string> >(), 
  "include path")
    ("input-file", po::value< vector<string> >(), "input file")
;
  1. help:就像上個範例一樣。最好讓每個 case 都有自己的 help option。
  2. optimization:這裡的 optimization 有兩個特點:
    1. 我們在程式裡頭指定了變數的位址(&opt)。如此一來,當 values 被分析儲存後,我們就可以透過該變數取得 optimization 的 value。
    2. 我們指定了變數的 default value 為 10 。因此,當使用者沒有給 optimization 指定一個 value 時, value 會是 10。
  3. include-path:include-path 在這裡是一個特殊的例子,它只從 command line 讀入資料來使用 options_description。(原文是:The "include-path" option is an example of the only case where the interface of the options_description class serves only one source -- the command line.  看了上下文,總覺得這句有點詭異、跳 tone)。對於常用到的 options,使用者往往喜歡使用它們的 short option name 形式,而這也就是程式碼裡頭 "include-path,I" option name 想表達的意思:"I" 是 include-path 的 short name。
    另外,值得注意的是 "include-path" 的型別是 std::vector。Boost.Program_options 對於 vectors 有特別的支援,它可以多次出現在 option 輸入中,而所有的 values 都會被存放在一個 vector 裡頭。
  4. input-file:描述了一連串、將被處理的檔案。當然,一開始的時候像下面的方式指定 input file 是可以的:
    compiler --input-file=a.cpp
    但,如果和下面的方法相比,上面的方式似乎就有點不標準囉!
    compiler a.cpp

    我們將針對這問題來探討一下:

像 a.cpp 這種在 parsing 的時候找不到 option name 的 token 的,在 Boost.Program_options 裡頭稱為 positional options。透過一些使用者的幫助,Boost.Program_options 有辦法可以知道 a.cpp 實際上就是 "--input-file=a.cpp" ,下面是妳/你需要的額外程式碼:

po::positional_options_description p;
p.add("input-file", -1);

po::variables_map vm;
po::store(po::command_line_parser(ac, av).
          options(desc).positional(p).run(), vm);
po::notify(vm);

開始兩行程式碼的意思是:所有的 positional options 需要被轉會成 "input-file" options。此外,這邊我們使用 command_line_parser 類別,而不是 parse_command_line function。parse_command_line 是一個只在簡單情況下會用到的 wrapper function 而已,但我們現在需要更多的資訊來做正確分析。

現在,所有的 options 都已經被描述和分析了,我們就饒了自己吧,不要去管怎麼實作 compiler 的邏輯、細節,先用 print 的方式來表示各個 options。

if (vm.count("include-path"))
{
    cout << "Include paths are: " 
         << vm["include-path"].as< vector<string> >() << "\n";
}

if (vm.count("input-file"))
{
    cout << "Input files are: " 
         << vm["input-file"].as< vector<string> >() << "\n";
}

cout << "Optimization level is " << opt << "\n";     

下面是個編譯、執行這個範例的方法:

$bin/gcc/debug/options_description --help
Usage: options_description [options]
Allowed options:
  --help                 : produce help message
  --optimization arg     : optimization level
  -I [ --include-path ] arg : include path
  --input-file arg       : input file
$bin/gcc/debug/options_description
Optimization level is 10
$bin/gcc/debug/options_description --optimization 4 -I foo a.cpp
Include paths are: foo
Input files are: a.cpp
Optimization level is 4

歐喔,還有一個小問題!我們還是可以使用"input-file"來指定,而 Usage 也是這樣寫的,這可能會混淆了我們的使用者,如果能把這資訊隱藏應該會不錯,不過就留到下一個例子吧。

Multiptles Sources

很快地,妳/你就會發現都得把所有的 compiler options 填好是一件令人抓狂的事。想想看,難道妳/你希望使用者裝了一個新的 library 後每次使用妳/你的 compiler 都得一個一個把 options 填好嗎?如果能她/他決定了一些選項是每次都要使用到的呢?最好的情況是產生一個 common settings 然後搭配 command line 來使用。

當然,把 config file 跟 command line 搭配使用是有必要的。舉例來說:config file 的 optimization level 會被 command line 的輸入蓋過;然而 include path 卻是需要有累加效果的。

來看個 code 先,完整的程式可以在

example/multiple_sources.cpp

找到。option 定義有兩個有趣的點:

  1. 我們宣告了多個 options_descriptions 實體(instances)。為什麼呢?因為不是所有的 options 都是相近的,有些 options,像是 input-file 不應該出現在自動化 help message 裡頭;有些 options 只在 config files 裡頭才有意義。
  2. 最後,讓 help message 有點結構化、而不只是串列表是不錯的主意。

下面讓我們宣告幾個 option groups 吧:

// Declare a group of options that will be 
// allowed only on command line
po::options_description generic("Generic options");
generic.add_options()
    ("version,v", "print version string")
    ("help", "produce help message")    
    ;
    
// Declare a group of options that will be 
// allowed both on command line and in
// config file
po::options_description config("Configuration");
config.add_options()
    ("optimization", po::value<int>(&opt)->default_value(10), 
          "optimization level")
    ("include-path,I", 
         po::value< vector<string> >()->composing(), 
         "include path")
    ;

// Hidden options, will be allowed both on command line and
// in config file, but will not be shown to the user.
po::options_description hidden("Hidden options");
hidden.add_options()
    ("input-file", po::value< vector<string> >(), "input file")
    ;        

請注意到宣告 include-path option 時呼叫的 composing method,這告訴了 library 不同來源的 values 應該被組合在一起(composed together)。

我們可以用 options_description 的 add method 來進一步的組織 option groups 中:

po::options_description cmdline_options;
cmdline_options.add(generic).add(config).add(hidden);

po::options_description config_file_options;
config_file_options.add(config).add(hidden);

po::options_description visible("Allowed options");
visible.add(generic).add(config);

分析和儲存 values 跟以往的作法相同,除了我們得額外呼叫了 parse_config_file 和呼叫 store 兩次之外。如果有些 value 在 command line 和 config file 中都出現了,那會發生什麼事?通常來說,先儲存下來的 value 會被視為優先,這也是 -optimization option 的設計,而對於 composing options 來說(像是 include-file ),這些 values 則是會被合併。

下面是個編譯、執行這個範例的方法:

$bin/gcc/debug/multiple_sources
Include paths are: /opt
Optimization level is 1
$bin/gcc/debug/multiple_sources --help
Allows options:

Generic options:
  -v [ --version ]       : print version string
  --help                 : produce help message

Configuration:
  --optimization n       : optimization level
  -I [ --include-path ] path : include path

$bin/gcc/debug/multiple_sources --optimization=4 -I foo a.cpp b.cpp
Include paths are: foo /opt
Input files are: a.cpp b.cpp
Optimization level is 4

第一個呼叫是使用 config file。第二個則多使用了 command line 的輸入。正如我們所看到的,include path 的 value 是從 command line 和 config file 合併來的,而 optimization 則是從 command line 取得。

Reference

  1. Boost 1.39.0 Doc: Chapter 13. Boost.Program_options

See Also

  1. Boost.Program_options – Introduction and Tutorial 

Boost.Program_options – Introduction and Tutorial

最近因為需要一些自動化的程式看了 Boost.Program_options 這個 library ,這系列文章主要內容都是翻譯Boost 1.39.0 Doc 裡頭,希望還有點時間可以加上一些 trace 的心得和紀錄,希望沒有誤人子弟、教壞仔大小、對大家有幫助~

Vocabulary

  1. Program options, options
  2. Config file
  3. Command line
  4. pair. (name, value)

Introduction

Boost.Program_options 是個可以讓程式設計師獲得 program options 的函式庫,什麼是 program options 呢?就是那種由使用者提供,可能是 command line 或是 config file 的 (name, value) 組合(pairs)

那為什麼需要使用 Boost.Program_options 呢?為什麼說它比我們依靠直覺寫出來的程式碼還好呢?

  • 簡單。Boost.Program_options 很小、提供的新增 options 的語法也簡單。像是自動化的 option value 的型別轉換(type conversion)、變數存放。
  • 比較好的錯誤回報。 當分析(parsing)command line input 出錯時,Boost.Program_options 會回報所有的錯誤,但 hand-written code 可能會誤判。
  • Options 可以來自任何地方。當使用者可能對你的程式只能藉由 command line 輸入感到不滿,妳/你很快就會用到 config file 或是 environment variables 了。這些都可以幾乎無痛得透過 Boost.Program_options 來擴充。

Tutorial

在這個 section ,我們將從最簡單的地方開始,之後逐漸知道大部分 Boost.Program_options 的 usage scenarios 。這部份的文件都只有部份的、重要的程式碼,完整的範例可以在:

BOOST_ROOT/libs/program_options/example

資料夾找到。此外整個範例,都假設下面的 namesapce alias 是有效的!

namespace po = boost::program_options

Getting Started

第一個也可能是最簡單的一個範例是:

處理兩個 options

下面是程式碼部份(完整程式可以在 example/first.cpp 找到)

// Declare the supported options.
po::options_description desc("Allowed options");
desc.add_options()
    ("help", "produce help message")
    ("compression", po::value<int>(), "set compression level")
;

一開始的地方宣告了一個 options_descriptions 來存放允許的 options。呼叫 options_description class 的 add_options method 會回傳一個提供了 operator() 操作的 proxy object 。呼叫 operator() 就是宣告了 options 。參數分別是:

(option name, information about value, option description)

這個範例裡頭,第一個 option 沒有 value,第二個 options 有一個型別是 int 的 value 。

po::variables_map vm;
po::store(po::parse_command_line(ac, av, desc), vm);
po::notify(vm);    

之後,宣告一個型別為 variables_map 的 object -- vm。variables_map 是用來存放任意型別的 value 。接著呼叫:

  1. store
  2. parse_command_line
  3. notify

去讓 vm 獲得所有 command line 來的 value。

if (vm.count("help")) {
    cout << desc << "\n";
    return 1;
}

if (vm.count("compression")) {
    cout << "Compression level was set to " 
 << vm["compression"].as<int>() << ".\n";
} else {
    cout << "Compression level was not set.\n";
}

最後我們可以任意地使用 options 了,variable_map 提供了像是 std::map 的操作,除了取得 value 時,必須使用 as method外。(要是你不小心誤用了 as 中的型別參數,使得 as 參數想取出的型別和實際不合時,會出一個 exception)

試著 compile 你的程式吧,下面是個範例:

$bin/gcc/debug/first
Compression level was not set.
$bin/gcc/debug/first --help
Allowed options:
  --help                 : produce help message
  --compression arg      : set compression level
$bin/gcc/debug/first --compression 10
Compression level was set to 10.

Reference

  1. Boost 1.39.0 Doc: Chapter 13. Boost.Program_options

See Also

  1. Boost.Program_options – Option Details and Multiple Sources

為什麼 Boost 這麼大?

今天 kane 哥跟我說,Boost 編出來有 1 GB,想起來以前在醉資心也聽過有人這麼說…

那到底為什麼這麼大?

身為傳教士,當然不能回答說:

你問我!我擲交!

這種答案可是天理不容啊~啊~啊~啊~

套句聖主播說的話:揪竟~這個 boost 的背後,又有什麼不為人知的血淚因緣呢?文章的第一集,我們使用下面的指令來編譯:

bjam.exe --build-dir="your_dir\boost_1_35_0" --build-type=complete --toolset=msvc install

由於我們選擇 complete build type,所以 bjam 會產生出 12 個sublibrary,而 sublibrary 下又因為 vc 編譯組態可分為 single/multi-thread、dynamic/static link or debug/release mode、是否包含standard libary 四種不同,再檔名是否加上版本號碼的部份。算一算沒有七七四十九種,卻也大概一個 sublibrary 會有 18 種檔案。但檔案重複率很高就是了,像是下面以 Boost.DateTime 為例:

18 個檔案只有 10 種版本

下面則是 Boost.DateTime 各版本的名稱及檔案大小,單項下內字體顏色一樣者表示檔案內容一樣(用 vim diff 測試)。

Linking Type Mode Name Size
Dynamic Link Debug boost_date_time-vc80-mt-gd-1_35.dll
84.0 KB
(86,016 bytes)
boost_date_time-vc80-mt-gd-1_35.lib
26.6 KB
(27,278 bytes)
boost_date_time-vc80-mt-gd.lib
Release boost_date_time-vc80-mt-1_35.dll
48.0 KB
(49,152 bytes)
boost_date_time-vc80-mt-1_35.dll
26.4 KB
(27,120
bytes) 
boost_date_time-vc80-mt.dll
Static Link debug libboost_date_time-vc80-mt-gd-1_35.lib  
1.50 MB
(1,577,314
bytes)
libboost_date_time-vc80-mt-gd.lib
libboost_date_time-vc80-mt-sgd-1_35.lib 
1.66 MB
(1,747,582 bytes)

libboost_date_time-vc80-mt-sgd.lib
libboost_date_time-vc80-sgd-1_35.lib
1.66 MB
(1,747,486 bytes)

libboost_date_time-vc80-sgd.lib
Release libboost_date_time-vc80-mt-1_35.lib
523 KB
(535,964
bytes)
libboost_date_time-vc80-mt.lib
libboost_date_time-vc80-mt-s-1_35.lib
661 KB
(677,130
bytes)
libboost_date_time-vc80-mt-s.lib
libboost_date_time-vc80-s-1_35.lib
661 KB
(677,034
bytes)
libboost_date_time-vc80-s.lib

 

例外,若是想瞭解這些檔案的命名規則,可以參考
http://www.boost.org/doc/libs/1_35_0/more/getting_started/windows.html

基本規則是這樣的:
[prefix]boost_sublibrary-name-toolset-version-options-[version-number]

  1. prefix
    lib 開頭代表 static link library ,沒有的則是 dll 和 import library
  2. sublibrary-name 
    顧名思義
  3. toolset-version
    顧名思義
  4. option
    1. mt -> multithread
    2. s  -> static link with C++ Standard Library & runtime library
    3. d  -> sublibrary 的 code 有 debug information
    4. g  -> C++ Standard Library & runtime library 都含 debug information
  5. version number 
    boost 的 version number

Boost.Test 的新文件

Boost 1.37.0 也出了好一陣子了,不過公司不比實驗室,總是不能隨意看有興趣的東西,指派的工作或 reading 還是得擺在第一位,更何況直屬老闆跟大頭都做我後頭和旁邊,有時還是會有點壓力!

不過最近被指派一個工作,跟 unit test 有關,趁著機會有時間可以看看新的 Boost.Test ,不過好像有點囧,怎麼 document 好像越寫越爛了…是我英文太爛嗎?還好舊電腦上還有舊版的 Boost.Test Doc !

哎呀,這個…程式設計師果然很討厭寫 document…果然古今中外都是…

編譯 Boost 1.35.0 (Visual Studio 2005 (VC 8.0) + Windows XP)

簡介

  1. Boost 的原始碼可以在官網 http://www.boost.org 找到,或是直接到 sourceforge 下載,網址是:http://tinyurl.com/m7jqo
  2. Boost 有著自己一套的建置系統,叫做 Boost.Build [1],可用在編譯、 安裝、測試等功能上。Boost.Build 則是架構於 Boost.Jam, Boost.Jam 又是 Perforce Jam[2] 的衍生,更詳細的介紹可以在 [3] 看到。
  3. 通常在 Windows 上安裝 Boost ,最快速、簡易的方法是去 Boost Consulting 下載 installer [4],不過到今天為止, Boost 1.35.0 的 installer 都還沒 release。所以大家來學學自己編譯吧 : )
  4. Boost Getting Started on Windows [5] 是一篇官方的教學文件,有簡易的 bjam 使用方法,但無註明完整安裝的步驟,另外它也簡介了Boost Project 的 layout, simple usage 等等。
  5. Boost 身為最先進、標準的 C++ library ,它大量使用了 generic programming, metaprogramming 等技巧,使得實際上需要編譯成函式庫(.lib, .dll)的部份反而少了,根據 Boost Getting Started on Windows [5] 的說明,只有以下幾個 library 使用時,一定需要先編譯成函式庫(.lib, .dll):
    1. Boost.Filesystem
    2. Boost.IOStreams
    3. Boost.ProgramOptions
    4. Boost.Python
    5. Boost.Regex
    6. Boost.Serialization
    7. Boost.Signals
    8. Boost.Thread
    9. Boost.Wave

    還有幾個則是 optional:

    1. Boost.DateTime
    2. Boost.Graph
    3. Boost.Test

安裝步驟

  1. 下載 source code 並解壓縮。
  2. 使用 Open Visual Studio 2005 Command Prompt 進入 cmd。利用 Open Visual Studio 2005 Command Prompt 的原因有兩點:
    1. 方便呼叫 namke, cl 等 vc toolchain。
    2. 若是電腦上安裝多個編譯器,使用 Open Visual Studio 2005 Command Prompt 通常可透過環境變數,讓 bjam 使用正確的 toolchain。
  3. 取得 bjam.exe。
    1. 可以選擇到 Boost 提供的預先編譯好的 binary,可在http://tinyurl.com/2q36f 下載。
    2. 或是自行編譯,以下是編譯步驟:
      1. $> cd your_dir\boost_1_35_0\tools\jam\src
      2. $> build.bat
      3. 執行完後,boost_1_35_0\tools\jam\src\bin.ntx86 下就放著編譯完後的 bjam.exe 了!
  4. 將上一個步驟的 bjam.exe 放入 PATH 環境變數或是使用絕對路徑呼叫 bjam,並搭配以下的 options 就可開始編譯並安裝 boost:
    • $> bjam.exe --build-dir="your_dir\boost_1_35_0" --build-type=complete --toolset=msvc install
    • --build-dir: boost 解壓縮的檔案,記得 = 前後不可有空白!
    • --build-type: complete 會產生 release, debug ,以及各種設定的對應:如 multithread, debug, 等等。
    • install: 編譯完後,將 header, lib 安裝到指定目錄,預設目錄是:C:\Boost,大小約 2 G。
  5. 更多的客製化安裝,可以使用 bjam --help 查看 options。
    • bjam 是個有趣的東西,當我在 your_idr\boost_1_35_0\tools\jam\src\bin.ntx86 下執行 bjam --help 時,它跑出的訊息並不多,而切換到 your_idr\boost_1_35_0 時卻又是另一回事,它跑出豐富的 Boost 的編譯資訊,後來發現它會去讀取 Jamroot 這個檔案,這是格外要注意的一點。

Reference

  1. Boost.Build: http://www.boost.org/doc/libs/1_35_0/tools/build/v2/index.html
  2. Perforce Jam: http://www.perforce.com/jam/jam.html
  3. Install Boost: http://www.boost.org/doc/libs/1_35_0/doc/html/bbv2/installation.html
  4. Free Download on Boost Consulting: http://www.boost-consulting.com/products/free
  5. Boost Getting Started on Windows: http://www.boost.org/doc/libs/1_35_0/more/getting_started/windows.html
  6. Boost 提供的 bjam binary 下載點(包含許多種平台): http://tinyurl.com/2q36f
  7. Boost Source on Sourceforge: http://tinyurl.com/m7jqo

MiniFilter InstanceSetupCallback is not called?

一般來說,MiniFilter 的 InstanceSetupCallback 會在 filter manager 把 minifilter attache 到 volume 後呼叫。如果沒有的話,可以檢查一下 minifilter 的 INF 是否把 instance fla...