ちょっとした関数
をテンプレートにして作成
[
トップ
|
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
]
開始行:
ちょっとした処理を行う関数,クラス(C,C++)
----
#contents
----
*ストリーム出力 [#pa375ee7]
**テキストファイルへも同時に出力するカスタムストリーム出...
#code(C){{
#include <iostream>
#include <fstream>
#include <sstream>
template<typename T>
inline std::string RX_TO_STRING(const T &x)
{
std::stringstream ss;
ss << x;
return ss.str();
}
// カスタムストリーム出力
class rxLog
{
std::fstream m_ofLog;
public:
rxLog(const char *filename)
{
m_ofLog.open(filename, std::ios::out);
if(!m_ofLog || !m_ofLog.is_open() || m_ofLog.bad() || m...
return;
}
}
~rxLog()
{
if(m_ofLog && m_ofLog.is_open()) m_ofLog.close();
}
//! <<オペレータを設定
template<typename T>
rxLog& operator<<(const T &a)
{
std::cout << a;
if(m_ofLog) m_ofLog << RX_TO_STRING(a);
return *this;
}
// std::coutの型
typedef std::basic_ostream<char, std::char_traits<char> ...
// std::endlのためのオペレータ<<を定義
// (std::endlはstd::coutを引数としてとる関数)
rxLog& operator<<(TypeCout& (*manip)(TypeCout&))
{
manip(std::cout);
if(m_ofLog) m_ofLog << std::endl;
return *this;
}
};
static rxLog RXCOUT("test.log");
}}
数値や文字列の出力だけならば<<オペレータのオーバーロード...
endlにも対応させるために追加の<<オペレータを定義している.
使用例:
RXCOUT << "x = " << x << std::endl;
**ヘルプテキスト表示サンプル [#vfe664d7]
#code(C){{
//! ヘルプテキストを表示
void help(void)
{
static const char* help = "[help]\n"
" ESC : quit the program\n"
" 's' : toggle animation on/off\n"
" Shift+'f' : toggle fullscreen mode\n"
" 'h' : show this help";
std::cout << help << std::endl;
}
}}
*テキストストリーム [#ga611790]
**テキストファイルストリームを開く [#i6fbb432]
#code(C){{
/*!
* ファイルストリームを開く
* @param[out] file ファイルストリーム
* @param[in] path ファイルパス
* @param[in] rw 入出力フラグ (1:読込専用, 2:書込専用,...
* @return ファイルオープン成功:1, 失敗:0
*/
static inline int OpenFileStream(fstream &file, const str...
{
file.open(path.c_str(), (rw & 0x01 ? ios::in : 0)|(rw & ...
if(!file || !file.is_open() || file.bad() || file.fail()){
return 0;
}
return 1;
}
}}
**テキストファイルから文字列リストを読み込む [#hb15c4c1]
空行やコメント行を除いて,各行を文字列として配列に格納す...
#code(C){{
/*!
* テキストファイルストリームから文字列リストを読み込む
* - コメント(%,#,//),空行は無視する
* @param[in] file ファイルストリーム
* @param[out] lines 各行の文字列を格納した配列
* @return 読み込んだ行数
*/
static inline int ReadTextStream(fstream &file, vector<st...
{
int k = 0;
string buf;
string::size_type comment_start = 0;
while(!file.eof()){
getline(file, buf);
// '%'以降はコメントとして無視
if( (comment_start = buf.find('%')) != string::size_typ...
buf = buf.substr(0, comment_start);
}
// '//'以降はコメントとして無視
if( (comment_start = buf.find("//")) != string::size_ty...
buf = buf.substr(0, comment_start);
}
// '#'以降はコメントとして無視
if( (comment_start = buf.find("#")) != string::size_typ...
buf = buf.substr(0, comment_start);
}
// 行頭のスペース,タブを削除
size_t stpos;
while((stpos = buf.find_first_of(" \t")) == 0){
buf.erase(buf.begin());
if(buf.empty()) break;
}
// 空行は無視
if(buf.empty()){
continue;
}
lines.push_back(buf);
k++;
}
return k;
}
/*!
* テキストファイルから文字列リストを読み込む
* - コメント(%,#,//),空行は無視する
* @param[in] file ファイルパス
* @param[out] path 各行の文字列を格納した配列
* @return 読み込んだ行数
*/
static inline int ReadTextStream(const string path, vecto...
{
fstream file;
file.open(path.c_str(), ios::in);
if(!file || !file.is_open() || file.bad() || file.fail()){
return 0;
}
int nlines = ReadTextStream(file, lines);
file.close();
return nlines;
}
}}
*ビット演算 [#v7e4cca7]
**2進数文字列の生成 [#u76e62a3]
#code(C){{
/*!
* 整数を2進数文字列に変換
* @param[in] x 元の整数
* @param[in] bit 2進数桁数
* @return 2進数文字列
*/
string GetBitArray(int x, int bit)
{
string s;
s.resize(bit, '0');
for(int i = 0; i < bit; ++i){
s[bit-i-1] = ((x >> i) & 0x01) ? '1' : '0';
}
return s;
}
}}
**ビット演算によるフラグ管理 [#q9aa11fd]
#code(C){{
enum
{
RX_BIT_A = 0x0001,
RX_BIT_B = 0x0002,
RX_BIT_C = 0x0004,
RX_BIT_D = 0x0008,
RX_BIT_E = 0x0010,
RX_ALL = 0xffff,
};
int main(void)
{
int flag = 0; // 00000
// フラグON
flag |= RX_BIT_B; // 00010
flag |= (RX_BIT_A | RX_BIT_D); // 01011
// フラグOFF
flag &= ~RX_BIT_B; // 01001
flag &= ~(RX_BIT_A | RX_BIT_D); // 00000
// フラグ反転
flag ^= RX_BIT_E; // 10000
// 全フラグ反転
flag ^= RX_ALL; // 01111
// 要素参照
if(flag & RX_BIT_A) cout << "A";
if(flag & RX_BIT_B) cout << "B";
if(flag & RX_BIT_C) cout << "C";
if(flag & RX_BIT_D) cout << "D";
if(flag & RX_BIT_E) cout << "E";
cout << endl; // ABCD
return 0;
}
}}
*画面出力 [#t1d1606b]
**可変引数リストを用いたカスタム版printf [#y9463dcd]
#code(C){{
#include <stdarg.h>
struct Vec2
{
double data[2];
double& operator[](int i){ return data[i]; }
};
struct Vec3
{
double data[3];
double& operator[](int i){ return data[i]; }
};
/*!
* 可変引数リスト"..."を使ったテキストファイル出力
* @param[in] fn 出力ファイル名
* @param[in] mode ファイルオープンモード("w" or "a")
* @param[in] fmt 出力フォーマット
* @param[in] ... 可変引数リスト(フォーマットにより数が異...
*/
bool FPrintf(const string fn, const string mode, char *fm...
{
FILE* fp;
if((fp = fopen(fn.c_str(), mode.c_str())) == NULL){
return 0;
}
va_list ap; // 各引数を順々に参照する変数
char *p, *sval;
int ival;
double dval;
Vec2 v2val;
Vec3 v3val;
va_start(ap, fmt); // apを最初の引数を指すようにする
for(p = fmt; *p; ++p){
if(*p != '%'){
putc(*p, fp);
continue;
}
switch(*(++p)){
case 'd':
ival = va_arg(ap, int);
fprintf(fp, "%d", ival);
break;
case 'f':
dval = va_arg(ap, double);
fprintf(fp, "%f", dval);
break;
case 's':
for(sval = va_arg(ap, char*); *sval; ++sval)
putc(*sval, fp);
break;
case 'v':
switch(*(++p)){
case '2':
v2val = va_arg(ap, Vec2);
fprintf(fp, "(%f, %f)", v2val[0], v2val[1]);
break;
case '3':
v3val = va_arg(ap, Vec3);
fprintf(fp, "(%f, %f, %f)", v3val[0], v3val[1], v3val...
break;
default:
v3val = va_arg(ap, Vec3);
fprintf(fp, "(%f, %f, %f)", v3val[0], v3val[1], v3val...
break;
}
break;
default:
putc(*p, fp);
break;
}
}
va_end(ap);
//char *n = "\n";
//putc(*n, fp);
fclose(fp);
return true;
}
}}
例えば,
#code(C){{
int i = 123;
double x = 4.56;
Vec2 v2;
v2[0] = 7.8; v2[1] = 9.0;
Vec3 v3;
v3[0] = 1.0; v3[1] = 2.0; v3[2] = 3.0;
Printf("test.txt", "w", "%s : %d, %f\n", "val", i, x);
Printf("test.txt", "a", "vec : %v2, %v3\n", v2, v3);
}}
のようなコードを実行すると,test.txtが作られて,
val : 123, 4.560000
vec : (7.800000, 9.000000), (1.000000, 2.000000, 3.000000)
が書き込まれる.
**コマンドプロンプトに表示すると共にログファイルにも保存(...
#code(C){{
#include <boost/iostreams/stream.hpp>
#include <boost/algorithm/string.hpp>
//! テキストストリーム - コマンドプロンプトに表示すると共...
class rxCout : public boost::iostreams::sink
{
string m_strLog;
public:
rxCout(string fn)
{
m_strLog = fn;
}
std::streamsize write(const char* s, std::streamsize n)
{
string str;;
str.resize(n);
for(int i = 0; i < n; ++i){
str[i] = s[i];
}
cout << str;
boost::algorithm::replace_all(str, "\n", "");
static std::ofstream fout(m_strLog, std::ios::out);
fout << str << endl;
return n;
}
};
}}
使うときは,
static boost::iostreams::stream<rxCout> RXCOUT("_log.txt...
などとして,
RXCOUT << "test" << endl;
として用いる.
*vector関連 [#na613a89]
#code(C){{
//! vector型に<<オペレータを設定
template<typename T>
inline std::ostream &operator<<(std::ostream &out, const ...
{
for(size_t i = 0; i < x.size(); ++i){
out << x[i] << (i == x.size()-1 ? "" : ", ");
}
return out;
}
/*!
* vectorのidx番目の要素を削除(0スタート)
* @param[in] src vectorコンテナ
* @param[in] idx 削除要素インデックス
* @return 削除の可否
*/
template<class T>
inline void EraseSTLVectori(vector<T> &src, int idx)
{
src.erase(src.begin()+idx);
}
/*!
* vectorの特定の要素を削除
* @param[in] src vectorコンテナ
* @param[in] comp_func 削除条件関数
* @return 削除の可否
*/
template<class T>
inline int EraseSTLVector(vector<T> &src, boost::function...
{
int cnt = 0;
vector<T>::iterator itr = src.begin();
while(itr != src.end()){
if(comp_func(*itr)){
itr = src.erase(itr);
cnt++;
}
else{
++itr;
}
}
return cnt;
}
}}
*配列 [#k55289e4]
**ランダムシャッフル [#w19a563c]
STLの[[algorithm]]のrandom_shuffle
([[algorithm#zf86514c]]参照)の存在に気づく前に作ったもの.
#code(C){{
/*!
* ランダムソート
* @param[inout] arr 配列
* @param[in] n 配列の大きさ
*/
template<typename T>
inline void RandomSort(T arr[], int n)
{
int rnd;
T temp;
srand(time(NULL));
for(int i = 0; i < n; ++i){
rnd = rand()%n;
temp = arr[i];
arr[i] = arr[rnd];
arr[rnd] = temp;
}
}
/*!
* ランダムソート
* @param[inout] arr 配列
* @param[in] n 配列の大きさ
*/
template<typename T>
inline void RandomSortV(vector<T> &arr)
{
int n = (int)arr.size();
int rnd;
T temp;
srand(time(NULL));
for(int i = 0; i < n; ++i){
rnd = rand()%n;
temp = arr[i];
arr[i] = arr[rnd];
arr[rnd] = temp;
}
}
}}
*ファイル処理 [#d3add900]
**フォルダ生成 [#vba50cb0]
処理系に依存して使えない場合あり.
#code(C){{
#include <direct.h>
/*!
* ディレクトリ作成(多階層対応)
* @param[in] dir 作成ディレクトリパス
* @return 成功で1,失敗で0 (ディレクトリがすでにある場合...
*/
static int MkDir(string dir)
{
if(_mkdir(dir.c_str()) != 0){
char cur_dir[512];
_getcwd(cur_dir, 512); // カレントフォルダを確保しておく
if(_chdir(dir.c_str()) == 0){ // chdirでフォルダ存在チ...
cout << "MkDir : " << dir << " is already exist." << e...
_chdir(cur_dir); // カレントフォルダを元に戻す
return 1;
}
else{
size_t pos = dir.find_last_of("\\/");
if(pos != string::npos){ // 多階層の可能性有り
int parent = MkDir(dir.substr(0, pos+1)); // 親ディレ...
if(parent){
if(_mkdir(dir.c_str()) == 0){
return 1;
}
else{
return 0;
}
}
}
else{
return 0;
}
}
}
return 1;
}
}}
**ファイル名生成 [#f8f2ca63]
#code(C){{
/*!
* 拡張子を変更したファイル名を生成
* @param[in] fn 元ファイル名
* @param[in] ext 変更後の拡張子名
* @return 拡張子を変更したファイル名
*/
inline string GetFileNameWithExt(const string &fn, const ...
{
string new_fn = fn;
size_t pos1 = fn.rfind('.');
if(pos1 != string::npos){
new_fn = fn.substr(0, pos1);
}
return new_fn+"."+ext;
}
/*!
* ファイル名生成
* @param head : 基本ファイル名
* @param ext : 拡張子
* @param n : 連番
* @param d : 連番桁数
* @return 生成したファイル名
*/
inline string CreateFileName(const string &head, const st...
{
string file_name = head;
int dn = d-1;
if(n > 0){
dn = (int)(log10((double)n))+1;
}
else if(n == 0){
dn = 1;
}
else{
n = 0;
dn = 1;
}
for(int i = 0; i < d-dn; ++i){
file_name += "0";
}
file_name += boost::lexical_cast<std::string>(n);
file_name += ".";
file_name += ext;
return file_name;
}
}}
**ファイル探索 [#kd67d500]
boost::filesystem使用版
#code(C){{
#include <boost/function.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/fstream.hpp>
/*!
* 再帰的に全ファイルを取り出す
* @param[in] fpath フォルダパス
* @param[out] paths 見つかったファイル一覧
*/
static void SearchFiles(const boost::filesystem::path &dp...
{
// カレントディレクトリのファイル一覧
boost::filesystem::directory_iterator end;
for(boost::filesystem::directory_iterator it(dpath); it!...
if(boost::filesystem::is_directory(*it)){
SearchFiles(it->path(), paths);
}
else{
paths.push_back(it->path().file_string());
}
}
}
/*!
* 再帰的に全ファイルを取り出す
* @param[in] fpath フォルダパス
* @param[out] paths 見つかったファイル一覧
* @param[in] fpComp 検索条件
*/
static void SearchFiles(const boost::filesystem::path &dp...
{
// カレントディレクトリのファイル一覧
boost::filesystem::directory_iterator end;
for(boost::filesystem::directory_iterator it(dpath); it!...
if(boost::filesystem::is_directory(*it)){
SearchFiles(it->path(), paths);
}
else{
string fpath = it->path().file_string();
if(fpComp(fpath)){
paths.push_back(fpath);
}
}
}
}
/*!
* 指定したディレクトリ以下に指定したファイルがあるかどう...
* (サブディレクトリ以下も検索)
* @param[in] dpath ディレクトリパス
* @param[in] fname 検索ファイル名
* @param[out] found_path 見つかったパス
* @return
*/
static bool FindFile(const boost::filesystem::path &dpath...
{
if(!boost::filesystem::exists(dpath)) return false;
boost::filesystem::directory_iterator end_itr;
for(boost::filesystem::directory_iterator itr(dpath); it...
if(boost::filesystem::is_directory(itr->status())){
if(FindFile(itr->path(), fname, found_path)) return tr...
}
else if(itr->leaf() == fname){
found_path = itr->path();
return true;
}
}
return false;
}
/*!
* ファイル名比較関数(拡張子)
* @param[in] fn 比較したいファイル名
* @param[in] ext 拡張子
* @return fnの拡張子がextと同じならtrue
*/
inline bool SearchCompExt(const string &fn, const string ...
{
return (fn.find(ext, 0) != string::npos);
}
}}
Windows API使用版.RX_S2W,RX_W2Sはプロジェクトの設定でUni...
マルチバイト文字セットにしている場合は必要なし.
#code(C){{
#include <cstdlib>
#include <windows.h>
#include <tchar.h>
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
/*!
* ワイド文字列(wstring)からマルチバイト文字列(string)へ...
* - 用いる前に setlocale(LC_CTYPE, ""); としておくこと
* @param[in] src ワイド文字列(wstring)
* @return マルチバイト文字列(string)
*/
inline static std::string RX_W2S(const std::wstring &src)
{
char *mbs = new char[src.length() * MB_CUR_MAX + 1];
wcstombs(mbs, src.c_str(), src.length() * MB_CUR_MAX + 1);
std::string dst = mbs;
delete [] mbs;
return dst;
}
/*!
* マルチバイト文字列(string)からワイド文字列(wstring)へ...
* - 用いる前に setlocale(LC_CTYPE, ""); としておくこと
* @param[in] src マルチバイト文字列(string)
* @return ワイド文字列(wstring)
*/
inline static std::wstring RX_S2W(const std::string &src)
{
wchar_t *wcs = new wchar_t[src.length() + 1];
mbstowcs(wcs, src.c_str(), src.length() + 1);
std::wstring dst = wcs;
delete [] wcs;
return dst;
}
/*!
* 再帰的に全ファイル(拡張子指定)を取り出す
* @param[in] dpath フォルダパス
* @param[out] paths 見つかったファイル一覧
* @param[inout] d 現在の階層数
* @param[in] n 最大階層数
* @param[in] exts 拡張子指定
*/
static void SearchFiles(const std::string &dpath, std::ve...
const std::vector<std::string> &exts)
{
HANDLE handle;
WIN32_FIND_DATA fd;
// search first file with the wildcard "*" to find the a...
handle = FindFirstFile(RX_S2W(dpath+"\\*").c_str(), &fd);
// if fail to find the file
if(handle == INVALID_HANDLE_VALUE){
return;
}
// search next files
do{
// file name
std::string name = RX_W2S(static_cast<LPCTSTR>(fd.cFile...
std::string fpath = dpath+"\\"+name;
if(name == "." || name == "..") continue;
if((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && ...
// if the path is directory, recursively search in the...
SearchFiles(fpath, paths, d+1, n, exts);
}
else{
vector<std::string>::const_iterator i;
for(i = exts.begin(); i != exts.end(); ++i){
if(fpath.find(*i, 0) != std::string::npos) break;
}
// store the file path if the extension was matched
if(i != exts.end()){
paths.push_back(fpath);
}
}
}while(FindNextFile(handle, &fd));
// terminate the search
FindClose(handle);
}
static void SearchFiles(const std::string &dir, std::vect...
std::vector<std::string> exts, const int n = 0)
{
if(PathIsDirectory(RX_S2W(dir).c_str())){ // dirがディレ...
int d = 0;
SearchFiles(dir, paths, d, n, exts);
}
}
}}
**ファイルの存在確認 [#df246793]
boost::filesystemを用いた場合,
#code(C){{
/*!
* ファイル,フォルダの存在確認
* @param[in] path_str ファイル・フォルダパス
*/
bool ExistFile(const string &path_str)
{
fspath fnph(path_str);
return boost::filesystem::exists(fnph);
}
}}
fopenを用いる場合,
#code(C){{
int FileExist(const char *fn)
{
FILE *fp;
if( (fp = fopen(fn, "r")) == NULL ){
return 0;
}
fclose(fp);
return 1;
}
}}
**fstreamでバイナリファイルの読み書き [#h63f6121]
#code(C){{
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
using namespace std;
int main(void)
{
srand(12345);
// ランダムなデータ
const int N = 10;
double a[N];
for(int i = 0; i < N; ++i) a[i] = rand()/(double)RAND_MAX;
// バイナリファイルの書き込み
ofstream fout;
fout.open("binary_test.dat", ios::out|ios::binary); // ...
if(!fout){
cout << "file couldn't open." << endl;
return 1;
}
for(int i = 0; i < N; ++i){
//fout << a[i];
fout.write((char*)&a[i], sizeof(double));
cout << a[i] << ", "; // 確認用
}
cout << endl;
fout.close();
// バイナリファイルの読み込み
ifstream fin;
fin.open("binary_test.dat", ios::in|ios::binary); // フ...
if(!fin){
cout << "file couldn't find." << endl;
return 1;
}
double x;
for(int i = 0; i < N; ++i){
//fin >> x;
fin.read((char*)&x, sizeof(double));
cout << x << ", "; // 確認用
}
cout << endl;
fin.close();
// ファイルの一分部のみ読み取り
fin.open("binary_test.dat", ios::in|ios::binary); // フ...
if(!fin){
cout << "file couldn't find." << endl;
return 1;
}
int j = 3;
fin.seekg(j*sizeof(double)); // 読み込み場所の移動
fin.read((char*)&x, sizeof(double));
cout << j << " : " << x << endl;
fin.close();
}
}}
*数字処理 [#c2eae1de]
**数字の桁数を数える [#e6783e27]
#code(C){{
/*!
* 数字の桁数をカウント
* @param[in] n 数字
* @return 桁数
*/
inline int CountDigit(int n)
{
int d = 0;
if(n > 0){
return (int)(log10((double)n))+1;
}
else if(n == 0){
return 1;
}
else{
return (int)(log10((double)(-n)))+1;
}
}
}}
**整数値の下一桁の値を抽出 [#me2573b6]
#code(C){{
/*!
* 整数値の下一桁を返す
* @param[in] x 整数値
* @return xの下一桁
*/
inline int ExtractLastDigit(const int &x)
{
int x1 = (x < 0) ? -x : x;
return x1-(int)(x1/10)*10;
}
}}
**整数値の任意桁の値を抽出 [#l89917cb]
#code(C){{
/*!
* 整数値の任意の桁の値を抽出して返す
* @param[in] x 整数値
* @param[in] d 桁(1<=d<=xの桁数,それ以外では0を返す)
* @return 任意の桁の値
*/
inline int ExtractAnyDigit(const int &x, const int &d)
{
if(d <= 0) return 0;
int x1 = (x < 0) ? -x : x;
int c = (int)log((double)x1); // xの桁数
if(d > c) return 0;
int a = (int)pow(10.0, (double)d); // 10^d
return (x1-(int)(x1/a)*a)/(a/10);
}
}}
**0付き数字の生成 [#xf14031b]
#code(C){{
/*!
* 0付きの数字を生成
* @param[in] n 数字
* @param[in] d 桁数
* @return 0付きの数字(string)
*/
inline string GenZeroNo(int n, const int &d)
{
string zero_no = "";
int dn = d-1;
if(n > 0){
dn = (int)(log10((double)n))+1;
}
else if(n == 0){
dn = 1;
}
else{
n = 0;
dn = 1;
}
for(int i = 0; i < d-dn; ++i){
zero_no += "0";
}
zero_no += boost::lexical_cast<std::string>(n);
return zero_no;
}
}}
*時間計測 [#c0e4f172]
**ストップウォッチクラス [#l93ce153]
#code(C){{
//-------------------------------------------------------...
// インクルードファイル
//-------------------------------------------------------...
#include <iostream>
#include <vector>
#include <string>
#define RX_USE_MM
#ifdef WIN32
#include <windows.h>
#ifdef RX_USE_MM
#include <mmsystem.h>
#pragma comment (lib, "winmm.lib")
#endif
#endif
#ifdef WIN32
#ifdef RX_USE_MM
#define RXTIME DWORD
#define RXGETTIME timeGetTime
#define RXTIME2SEC 1.0e-3
//#define RXTIME2SEC 1.0
#else
#define RXTIME DWORD
#define RXGETTIME GetTickCount
#define RXTIME2SEC 1.0e-3
//#define RXTIME2SEC 1.0
#endif
#else
#define RXTIME clock_t
#define RXGETTIME clock
#define RXTIME2SEC (1.0/CLOCKS_PER_SEC)
#endif
using namespace std;
//-------------------------------------------------------...
// 時間計測クラス
//-------------------------------------------------------...
class rxTimer
{
RXTIME m_tStart, m_tEnd;
vector<double> m_vTimes;
vector<string> m_vComments;
public:
//! コンストラクタ
rxTimer(){}
//! デストラクタ
~rxTimer(){}
//! 計測開始
void Start(void)
{
m_tStart = RXGETTIME();
}
//! 計測
void Split(const string &cmnt = "", bool restart = fa...
{
m_tEnd = RXGETTIME();
double time = (double)(m_tEnd-m_tStart)*RXTIME2SEC;
m_vTimes.push_back(time);
m_vComments.push_back(cmnt);
if(restart) m_tStart = RXGETTIME();
}
//! 計測終了
void Stop(const string &cmnt = "")
{
m_tEnd = RXGETTIME();
double time = (double)(m_tEnd-m_tStart)*RXTIME2SEC;
m_vTimes.push_back(time);
m_vComments.push_back(cmnt);
m_tStart = m_tEnd = 0;
}
//! リセット
void Reset(void)
{
m_vTimes.clear();
m_vComments.clear();
m_tStart = m_tEnd = 0;
}
// 最後に記録された時間を削除
void PopBackTime(void)
{
m_vTimes.pop_back();
m_vComments.pop_back();
}
//! 時間をセット(他の計測方法で計測した結果など)
void SetTime(const double &t, const string &cmnt = "")
{
m_vTimes.push_back(t);
m_vComments.push_back(cmnt);
}
//! 時間の取得
double GetTime(int i)
{
if(i >= (int)m_vTimes.size()) return 0.0;
return m_vTimes[i];
}
//! 記録された時間数の取得
int GetTimeNum(void)
{
return (int)m_vTimes.size();
}
//! 記録された時間を画面出力
double Print(void)
{
int m = 0, mi;
if(m_vTimes.empty()){
return 0.0;
}
else{
// 総計測時間を計算
double total = 0.0;
for(int i = 0; i < (int)m_vTimes.size(); ++i){
mi = (int)m_vComments[i].size();
if(mi > m) m = mi;
total += m_vTimes[i];
}
SetTime(total, "total");
}
int cur_p = cout.precision();
cout.precision(3);
cout.setf(ios::fixed);
for(int i = 0; i < (int)m_vTimes.size(); ++i){
string spc;
for(int k = 0; k < m-(int)m_vComments[i].size(); ++k) ...
cout << m_vComments[i] << spc << " : " << m_v...
}
cout.unsetf(ios::fixed);
cout.precision(cur_p);
double t = m_vTimes.back();
PopBackTime(); // 格納した合計時間を次の計算に備...
return t;
}
//! 記録された時間を文字列に出力
double PrintToString(string &str)
{
int m = 0, mi;
if(m_vTimes.empty()){
return 0.0;
}
else{
// 総計測時間を計算
double total = 0.0;
for(int i = 0; i < (int)m_vTimes.size(); ++i){
mi = (int)m_vComments[i].size();
if(mi > m) m = mi;
total += m_vTimes[i];
}
SetTime(total, "total");
}
stringstream ss;
ss.precision(3);
ss.setf(ios::fixed);
int n = (int)m_vTimes.size();
for(int i = 0; i < n; ++i){
string spc;
for(int k = 0; k < m-(int)m_vComments[i].size(); ++k) ...
ss << m_vComments[i] << spc << " : " << m_vTi...
}
ss << "\n";
str = ss.str();
double t = m_vTimes.back();
PopBackTime(); // 格納した合計時間を次の計算に備...
return t;
}
};
}}
**平均値の計測 [#wd7a901f]
#code(C){{
class rxTimerAvg
{
public:
// 時間と計測回数
struct rxTimeAndCount
{
double time;
int count;
int idx;
};
// 時間と計測回数を文字列と関連づけるマップ
typedef map<string, rxTimeAndCount> RXMAPTC;
private:
rxTimer m_Tmr; //!< 時間計測クラス
RXMAPTC m_TimeMap; //!< 時間と計測回数を文字列と関連づけ...
public:
//! コンストラクタ
rxTimerAvg()
{
Clear();
ResetTime();
ClearTime();
}
/*!
* すべてクリア
*/
void Clear(void)
{
m_TimeMap.clear();
}
/*!
* 蓄積時間の初期化
*/
void ClearTime(void)
{
for(RXMAPTC::iterator it = m_TimeMap.begin(); it != m_T...
it->second.time = 0.0;
it->second.count = 0;
//it->second.idx = -1;
}
}
/*!
* リセット
*/
void ResetTime(void)
{
m_Tmr.Reset();
m_Tmr.Start();
}
/*!
* 計測
* @param[in] cmnt 時間蓄積用の名前
*/
void Split(const string &cmnt)
{
RXMAPTC::iterator i = m_TimeMap.find(cmnt);
m_Tmr.Stop();
if(i == m_TimeMap.end()){
m_TimeMap[cmnt].time = m_Tmr.GetTime(0);
m_TimeMap[cmnt].count = 1;
m_TimeMap[cmnt].idx = m_TimeMap.size()-1;
}
else{
m_TimeMap[cmnt].time += m_Tmr.GetTime(0);
m_TimeMap[cmnt].count++;
}
m_Tmr.Reset();
m_Tmr.Start();
}
/*!
* 総時間の取得
* @return 総時間
*/
double GetTotalTime(void)
{
if(m_TimeMap.empty()){
m_Tmr.Stop();
return m_Tmr.GetTime(0);
}
else{
double total = 0.0;
for(RXMAPTC::iterator it = m_TimeMap.begin(); it != m_...
total += it->second.time/it->second.count;
}
return total;
}
}
/*!
* 記録された時間を画面出力
*/
void Print(void)
{
int m = 0, mi;
double total = 0.0;
for(RXMAPTC::iterator it = m_TimeMap.begin(); it != m_T...
mi = (int)it->first.size();
if(mi > m) m = mi;
total += it->second.time/it->second.count;
}
int cur_p = cout.precision();
cout.precision(3);
cout.setf(ios::fixed);
for(RXMAPTC::iterator it = m_TimeMap.begin(); it != m_T...
string spc = RXFunc::GenSpace( m-(int)(it->first.size(...
RXCOUT << it->first << spc << " : " << (it->second.tim...
}
cout.unsetf(ios::fixed);
cout.precision(cur_p);
string spc = RXFunc::GenSpace(m-5);
RXCOUT << "total" << spc << " : " << total << endl;
}
/*!
* 記録された時間を文字列に出力
* @param[out] str 出力文字列
*/
void PrintToString(string &str)
{
int m = 0, mi;
double total = 0.0;
for(RXMAPTC::iterator it = m_TimeMap.begin(); it != m_T...
mi = (int)it->first.size();
if(mi > m) m = mi;
total += it->second.time/it->second.count;
}
stringstream ss;
ss.precision(3);
ss.setf(ios::fixed);
for(int i = 0; i < (int)m_TimeMap.size(); ++i){
RXMAPTC::iterator it = m_TimeMap.begin();
for(it = m_TimeMap.begin(); it != m_TimeMap.end(); ++i...
if(it->second.idx == i){
break;
}
}
string spc = RXFunc::GenSpace(m-(int)(it->first.size()...
ss << it->first << spc << " : " << (it->second.time/it...
}
string spc = RXFunc::GenSpace(m-5);
ss << "total" << spc << " : " << total << "[s]\n";
str = ss.str();
}
};
}}
**現在時刻の取得 [#r6488c77]
#code(C){{
#include <iostream>
#include <string>
#include <ctime>
const std::string WEEK[7] = { "Sunday", "Monday", "Tuesda...
int main(void)
{
time_t timer;
tm *time_st;
// 現在時刻の取得
time(&timer);
// 文字列で表示
cout << "現在時刻 : " << ctime(&timer) << endl;
// 構造体に変換
time_st = localtime(&timer);
// 日付(年は西暦年-1900,月は1月=0)
cout << "日付 : " << time_st->tm_year+1900 << "/" << tim...
// 時刻
cout << "時刻 : " << time_st->tm_hour << ":" << time_st-...
// 曜日(日曜日=0)
cout << "曜日 : " << WEEK[time_st->tm_wday] << endl;
// 年間日
cout << "年間日 : " << time_st->tm_yday << endl;
// サマータイムラグ
cout << "サマータイムラグ : " << time_st->tm_isdst << en...
return 0;
}
}}
実行結果の例
現在時刻 : Wed Aug 31 13:11:31 2011
日付 : 2011/8/31
時刻 : 13:11:31
曜日 : Wednesday
年間日 : 242
サマータイムラグ : 0
*行列 [#a81ffbad]
**行列とベクトルの積 [#jdc78fe4]
#code(C){{
/*!
* 4x4行列と4次元ベクトルのかけ算(d = m x v)
* @param[out] d 結果のベクトル
* @param[in] m 4x4行列
* @param[in] v 4次元ベクトル
*/
template<class T>
inline void MulMatVec4(T d[4], const T m[4][4], const T v...
{
d[0] = (v[0]*m[0][0]+v[1]*m[0][1]+v[2]*m[0][2]+v[3]*m[0]...
d[1] = (v[0]*m[1][0]+v[1]*m[1][1]+v[2]*m[1][2]+v[3]*m[1]...
d[2] = (v[0]*m[2][0]+v[1]*m[2][1]+v[2]*m[2][2]+v[3]*m[2]...
d[3] = (v[0]*m[3][0]+v[1]*m[3][1]+v[2]*m[3][2]+v[3]*m[3]...
}
/*!
* 4次元ベクトルと4x4行列のかけ算(d = v x m)
* @param[out] d 結果のベクトル
* @param[in] v 4次元ベクトル
* @param[in] m 4x4行列
*/
template<class T>
inline void MulVecMat4(T d[4], const T v[4], const T m[4]...
{
d[0] = (v[0]*m[0][0]+v[1]*m[1][0]+v[2]*m[2][0]+v[3]*m[3]...
d[1] = (v[0]*m[0][1]+v[1]*m[1][1]+v[2]*m[2][1]+v[3]*m[3]...
d[2] = (v[0]*m[0][2]+v[1]*m[1][2]+v[2]*m[2][2]+v[3]*m[3]...
d[3] = (v[0]*m[0][3]+v[1]*m[1][3]+v[2]*m[2][3]+v[3]*m[3]...
}
/*!
* nxn行列とn次元ベクトルのかけ算(d = m x v)
* @param[out] d 結果のベクトル
* @param[in] m nxn行列(2次元配列)
* @param[in] v n次元ベクトル
* @param[in] n ベクトル,行列のサイズ
*/
template<class T>
inline void MulMatVec(T *d, T **m, T *v, int n)
{
for(int i = 0; i < n; ++i){
d[i] = (T)0;
for(int j = 0; j < n; ++j){
d[i] += v[j]*m[i][j];
}
}
}
/*!
* nxn行列とn次元ベクトルのかけ算(d = v x m)
* @param[out] d 結果のベクトル
* @param[in] v n次元ベクトル
* @param[in] m nxn行列(2次元配列)
* @param[in] n ベクトル,行列のサイズ
*/
template<class T>
inline void MulVecMat(T *d, T *v, T **m, int n)
{
for(int i = 0; i < n; ++i){
d[i] = (T)0;
for(int j = 0; j < n; ++j){
d[i] += v[j]*m[j][i];
}
}
}
}}
**行列の画面出力 [#w69e7c75]
#code(C){{
/*!
* 行列の画面出力
* @param[in] header 出力の文字列部分
* @param[in] matrix 行列を格納した配列
* @param[in] nx,ny 行列の大きさ
* @return
*/
static void PrintMatrix(string header, double *matrix, in...
{
int n = (int)header.size();
string disp = "%f ";
for(int j = 0; j < ny; ++j){
if(j == 0){
printf("%s", header.c_str());
}
else{
for(int k = 0; k < n; ++k) printf(" ");
}
printf("| ");
for (int i = 0; i < nx; ++i){
printf(disp.c_str(), matrix[j*nx+i]);
}
printf(" |\n");
}
// printf("\n");
}
/*!
* 行列のファイル出力
* @param[in] fp ファイルポインタ
* @param[in] header 出力の文字列部分
* @param[in] matrix 行列を格納した配列
* @param[in] nx,ny 行列の大きさ
* @return
*/
static void FPrintMatrix(FILE *fp, string header, double ...
{
int n = (int)header.size();
string disp = "%f ";
for(int j = 0; j < ny; ++j){
if(j == 0){
fprintf(fp, "%s", header.c_str());
}
else{
for(int k = 0; k < n; ++k) fprintf(fp, " ");
}
fprintf(fp, "| ");
for (int i = 0; i < nx; ++i){
fprintf(fp, disp.c_str(), matrix[j*nx+i]);
}
fprintf(fp, " |\n");
}
}
/*!
* 行列のファイル出力
* @param[in] fp ファイルポインタ
* @param[in] frame フレーム番号
* @param[in] matrix 行列を格納した配列
* @param[in] nx,ny 行列の大きさ
* @return
*/
static void OutputMatrix(FILE *fp, int frame, double *mat...
{
fprintf(fp, "%d ", frame);
for(int j = 0; j < ny; ++j){
for (int i = 0; i < nx; ++i){
fprintf(fp, "%f ", matrix[j*nx+i]);
}
}
fprintf(fp, "\n");
}
}}
*グリッドの線型補間 [#s14d41d1]
#code(C){{
//-------------------------------------------------------...
// 補間関数
//-------------------------------------------------------...
inline int GET_INDEX(int i, int j, int k, int nx, int ny)...
inline int GET_INDEX_2D(int i, int j, int nx){ return j*n...
/*!
* 座標値から対応するグリッドを求める
* @param[in] x,y 座標
* @param[in] dx,dy グリッド幅
* @param[in] nx,ny グリッド数
* @param[out] i0,i1 x方向対応グリッド
* @param[out] j0,j1 y方向対応グリッド
* @param[out] s,t グリッド境界からの距離
*/
inline void GRID2D(const double &x, const double &y, cons...
int &i0, int &i1, int &j0, int &j1, double &s, dou...
{
double x0 = x/dx, y0 = y/dx;
// (x,y)のグリッド位置
i0 = (int)x0; i1 = i0+1;
j0 = (int)y0; j1 = j0+1;
s = (x0-i0);
t = (y0-j0);
// xがグリッド外のときの処理
if(i0 < 0){
i0 = 0; i1 = 1;
s = 0.0;
}
if(i1 >= nx2){
i0 = nx2-2; i1 = nx2-1;
s = 1.0;
}
// yがグリッド外のときの処理
if(j0 < 0){
j0 = 0; j1 = 1;
t = 0.0;
}
if(j1 >= ny2){
j0 = ny2-2; j1 = ny2-1;
t = 1.0;
}
}
/*!
* 座標値から対応するグリッドを求める
* @param[in] x,y 座標
* @param[in] dx,dy グリッド幅
* @param[in] nx,ny グリッド数
* @param[out] i0,i1 x方向対応グリッド
* @param[out] j0,j1 y方向対応グリッド
* @param[out] s,t グリッド境界からの距離
*/
inline void GRID3D(const double &x, const double &y, cons...
const int &nx, const int &ny, const int &nz, int &...
{
double x0 = x/dx, y0 = y/dx, z0 = z/dz;
if(x0 < 0.0) x0 = 0.0;
if(y0 < 0.0) y0 = 0.0;
if(z0 < 0.0) z0 = 0.0;
// (x,y)のグリッド位置
i0 = (int)x0; i1 = i0+1;
j0 = (int)y0; j1 = j0+1;
k0 = (int)z0; k1 = k0+1;
s = (x0-i0);
t = (y0-j0);
u = (z0-k0);
// xがグリッド外のときの処理
if(i0 < 0){
i0 = 0; i1 = 1;
s = 0.0;
}
if(i1 > nx+1){
i0 = nx; i1 = nx+1;
s = 1.0;
}
// yがグリッド外のときの処理
if(j0 < 0){
j0 = 0; j1 = 1;
t = 0.0;
}
if(j1 > ny+1){
j0 = ny; j1 = ny+1;
t = 1.0;
}
// zがグリッド外のときの処理
if(k0 < 0){
k0 = 0; k1 = 1;
u = 0.0;
}
if(k1 > nz+1){
k0 = nz; k1 = nz+1;
u = 1.0;
}
}
/*!
* 線形補間による値の取得
* @param[in] x,y 座標
* @param[in] f フィールド値(double)が格納されている配列
* @param[in] dx,dy グリッド幅
* @param[in] nx,ny グリッド数
* @return 線形補間値
*/
inline double LINEAR_INTERPOLATE_2D(const double &x, cons...
{
int i0, j0, i1, j1;
double s0, t0, s1, t1;
GRID2D(x, y, dx, dy, nx2, ny2, i0, i1, j0, j1, s1, t1);
s0 = 1.0-s1;
t0 = 1.0-t1;
// (x0,y0)における値を線形補間で求める
return s0*(t0*f[GET_INDEX_2D(i0, j0, nx2)]+t1*f[GET_INDE...
s1*(t0*f[GET_INDEX_2D(i1, j0, nx2)]+t1*f[GET_INDEX_2...
}
/*!
* 線形補間による値の取得(3D)
* @param[in] x,y,z 座標
* @param[in] f フィールド値(double)が格納されている配列
* @param[in] dx,dy,dz グリッド幅
* @param[in] nx,ny,nz グリッド数
* @return 線形補間値
*/
inline double LINEAR_INTERPOLATE_3D(const double &x, cons...
const double &dx, const double &dy, const double...
const int &nx, const int &ny, const int &nz)
{
int i0, i1, j0, j1, k0, k1;
double s0, s1, t0, t1, u0, u1;
GRID3D(x, y, z, dx, dy, dz, nx, ny, nz, i0, i1, j0, j1, ...
s0 = 1.0-s1;
t0 = 1.0-t1;
u0 = 1.0-u1;
// (x0,y0,z0)における値を線形補間で求める
return u0*(s0*(t0*f[GET_INDEX(i0, j0, k0, nx+2, ny+2)]+t...
s1*(t0*f[GET_INDEX(i1, j0, k0, nx+2, ny+2)]+t1*f[GE...
u1*(s0*(t0*f[GET_INDEX(i0, j0, k1, nx+2, ny+2)]+t1*f...
s1*(t0*f[GET_INDEX(i1, j0, k1, nx+2, ny+2)]+t1*f[GE...
}
}}
*データ構造 [#e045abd6]
**ラベルとデータのマッピングクラス [#gbd579d2]
stl::mapのラッパ.
#code(C){{
//-------------------------------------------------------...
//! ラベルとデータのマッピングを行うテンプレートクラス
//-------------------------------------------------------...
template<class Type>
class MapData
{
protected:
map<string, Type> m_Map; //!< ラベルとデータのマップ
string m_strCurrentMap; //!< 現在のデータを示すラベル
public:
/*!
* ラベルnameのデータを検索して返す
* @param[in] name ラベル名
* @return nameに対応するデータ
*/
Type LookupData(const char *name)
{
map<string, Type>::iterator i = m_Map.find(name);
if(i == m_Map.end())
return NULL;
else
return m_Map[name];
}
/*!
* 現在のデータを取得
* @return 現在のデータ
*/
Type GetCurrentData()
{
return m_Map[m_strCurrentMap];
}
/*!
* 現在のラベルを取得
* @return 現在のラベル
*/
string GetCurrentLabel()
{
return m_strCurrentMap;
}
/*!
* 現在のデータの設定
* @param[in] name 設定したいラベル
* @return 設定したデータ
*/
Type SetCurrentData(const char *name)
{
Type data = LookupData(name);
if(data){
m_strCurrentMap = name;
}
return data;
}
/*!
* データ作成
* @param[in] name ラベル
* @param[in] data データ
*/
void CreateData(const char *name, Type data)
{
Type data0 = LookupData(name);
if(!data0){
m_Map[name] = data;
m_strCurrentMap = name;
}
}
/*!
* 全データ削除
*/
void Clear(void)
{
m_Map.clear();
m_strCurrentMap = "";
}
/*!
* キー文字列リストの取得
* @param[out] strs キー文字列リスト
*/
void GetStrings(vector<string> &strs)
{
map<string, Type>::iterator it;
for(it = m_Map.begin(); it != m_Map.end(); ++it){
strs.push_back(it->first);
}
}
};
}}
終了行:
ちょっとした処理を行う関数,クラス(C,C++)
----
#contents
----
*ストリーム出力 [#pa375ee7]
**テキストファイルへも同時に出力するカスタムストリーム出...
#code(C){{
#include <iostream>
#include <fstream>
#include <sstream>
template<typename T>
inline std::string RX_TO_STRING(const T &x)
{
std::stringstream ss;
ss << x;
return ss.str();
}
// カスタムストリーム出力
class rxLog
{
std::fstream m_ofLog;
public:
rxLog(const char *filename)
{
m_ofLog.open(filename, std::ios::out);
if(!m_ofLog || !m_ofLog.is_open() || m_ofLog.bad() || m...
return;
}
}
~rxLog()
{
if(m_ofLog && m_ofLog.is_open()) m_ofLog.close();
}
//! <<オペレータを設定
template<typename T>
rxLog& operator<<(const T &a)
{
std::cout << a;
if(m_ofLog) m_ofLog << RX_TO_STRING(a);
return *this;
}
// std::coutの型
typedef std::basic_ostream<char, std::char_traits<char> ...
// std::endlのためのオペレータ<<を定義
// (std::endlはstd::coutを引数としてとる関数)
rxLog& operator<<(TypeCout& (*manip)(TypeCout&))
{
manip(std::cout);
if(m_ofLog) m_ofLog << std::endl;
return *this;
}
};
static rxLog RXCOUT("test.log");
}}
数値や文字列の出力だけならば<<オペレータのオーバーロード...
endlにも対応させるために追加の<<オペレータを定義している.
使用例:
RXCOUT << "x = " << x << std::endl;
**ヘルプテキスト表示サンプル [#vfe664d7]
#code(C){{
//! ヘルプテキストを表示
void help(void)
{
static const char* help = "[help]\n"
" ESC : quit the program\n"
" 's' : toggle animation on/off\n"
" Shift+'f' : toggle fullscreen mode\n"
" 'h' : show this help";
std::cout << help << std::endl;
}
}}
*テキストストリーム [#ga611790]
**テキストファイルストリームを開く [#i6fbb432]
#code(C){{
/*!
* ファイルストリームを開く
* @param[out] file ファイルストリーム
* @param[in] path ファイルパス
* @param[in] rw 入出力フラグ (1:読込専用, 2:書込専用,...
* @return ファイルオープン成功:1, 失敗:0
*/
static inline int OpenFileStream(fstream &file, const str...
{
file.open(path.c_str(), (rw & 0x01 ? ios::in : 0)|(rw & ...
if(!file || !file.is_open() || file.bad() || file.fail()){
return 0;
}
return 1;
}
}}
**テキストファイルから文字列リストを読み込む [#hb15c4c1]
空行やコメント行を除いて,各行を文字列として配列に格納す...
#code(C){{
/*!
* テキストファイルストリームから文字列リストを読み込む
* - コメント(%,#,//),空行は無視する
* @param[in] file ファイルストリーム
* @param[out] lines 各行の文字列を格納した配列
* @return 読み込んだ行数
*/
static inline int ReadTextStream(fstream &file, vector<st...
{
int k = 0;
string buf;
string::size_type comment_start = 0;
while(!file.eof()){
getline(file, buf);
// '%'以降はコメントとして無視
if( (comment_start = buf.find('%')) != string::size_typ...
buf = buf.substr(0, comment_start);
}
// '//'以降はコメントとして無視
if( (comment_start = buf.find("//")) != string::size_ty...
buf = buf.substr(0, comment_start);
}
// '#'以降はコメントとして無視
if( (comment_start = buf.find("#")) != string::size_typ...
buf = buf.substr(0, comment_start);
}
// 行頭のスペース,タブを削除
size_t stpos;
while((stpos = buf.find_first_of(" \t")) == 0){
buf.erase(buf.begin());
if(buf.empty()) break;
}
// 空行は無視
if(buf.empty()){
continue;
}
lines.push_back(buf);
k++;
}
return k;
}
/*!
* テキストファイルから文字列リストを読み込む
* - コメント(%,#,//),空行は無視する
* @param[in] file ファイルパス
* @param[out] path 各行の文字列を格納した配列
* @return 読み込んだ行数
*/
static inline int ReadTextStream(const string path, vecto...
{
fstream file;
file.open(path.c_str(), ios::in);
if(!file || !file.is_open() || file.bad() || file.fail()){
return 0;
}
int nlines = ReadTextStream(file, lines);
file.close();
return nlines;
}
}}
*ビット演算 [#v7e4cca7]
**2進数文字列の生成 [#u76e62a3]
#code(C){{
/*!
* 整数を2進数文字列に変換
* @param[in] x 元の整数
* @param[in] bit 2進数桁数
* @return 2進数文字列
*/
string GetBitArray(int x, int bit)
{
string s;
s.resize(bit, '0');
for(int i = 0; i < bit; ++i){
s[bit-i-1] = ((x >> i) & 0x01) ? '1' : '0';
}
return s;
}
}}
**ビット演算によるフラグ管理 [#q9aa11fd]
#code(C){{
enum
{
RX_BIT_A = 0x0001,
RX_BIT_B = 0x0002,
RX_BIT_C = 0x0004,
RX_BIT_D = 0x0008,
RX_BIT_E = 0x0010,
RX_ALL = 0xffff,
};
int main(void)
{
int flag = 0; // 00000
// フラグON
flag |= RX_BIT_B; // 00010
flag |= (RX_BIT_A | RX_BIT_D); // 01011
// フラグOFF
flag &= ~RX_BIT_B; // 01001
flag &= ~(RX_BIT_A | RX_BIT_D); // 00000
// フラグ反転
flag ^= RX_BIT_E; // 10000
// 全フラグ反転
flag ^= RX_ALL; // 01111
// 要素参照
if(flag & RX_BIT_A) cout << "A";
if(flag & RX_BIT_B) cout << "B";
if(flag & RX_BIT_C) cout << "C";
if(flag & RX_BIT_D) cout << "D";
if(flag & RX_BIT_E) cout << "E";
cout << endl; // ABCD
return 0;
}
}}
*画面出力 [#t1d1606b]
**可変引数リストを用いたカスタム版printf [#y9463dcd]
#code(C){{
#include <stdarg.h>
struct Vec2
{
double data[2];
double& operator[](int i){ return data[i]; }
};
struct Vec3
{
double data[3];
double& operator[](int i){ return data[i]; }
};
/*!
* 可変引数リスト"..."を使ったテキストファイル出力
* @param[in] fn 出力ファイル名
* @param[in] mode ファイルオープンモード("w" or "a")
* @param[in] fmt 出力フォーマット
* @param[in] ... 可変引数リスト(フォーマットにより数が異...
*/
bool FPrintf(const string fn, const string mode, char *fm...
{
FILE* fp;
if((fp = fopen(fn.c_str(), mode.c_str())) == NULL){
return 0;
}
va_list ap; // 各引数を順々に参照する変数
char *p, *sval;
int ival;
double dval;
Vec2 v2val;
Vec3 v3val;
va_start(ap, fmt); // apを最初の引数を指すようにする
for(p = fmt; *p; ++p){
if(*p != '%'){
putc(*p, fp);
continue;
}
switch(*(++p)){
case 'd':
ival = va_arg(ap, int);
fprintf(fp, "%d", ival);
break;
case 'f':
dval = va_arg(ap, double);
fprintf(fp, "%f", dval);
break;
case 's':
for(sval = va_arg(ap, char*); *sval; ++sval)
putc(*sval, fp);
break;
case 'v':
switch(*(++p)){
case '2':
v2val = va_arg(ap, Vec2);
fprintf(fp, "(%f, %f)", v2val[0], v2val[1]);
break;
case '3':
v3val = va_arg(ap, Vec3);
fprintf(fp, "(%f, %f, %f)", v3val[0], v3val[1], v3val...
break;
default:
v3val = va_arg(ap, Vec3);
fprintf(fp, "(%f, %f, %f)", v3val[0], v3val[1], v3val...
break;
}
break;
default:
putc(*p, fp);
break;
}
}
va_end(ap);
//char *n = "\n";
//putc(*n, fp);
fclose(fp);
return true;
}
}}
例えば,
#code(C){{
int i = 123;
double x = 4.56;
Vec2 v2;
v2[0] = 7.8; v2[1] = 9.0;
Vec3 v3;
v3[0] = 1.0; v3[1] = 2.0; v3[2] = 3.0;
Printf("test.txt", "w", "%s : %d, %f\n", "val", i, x);
Printf("test.txt", "a", "vec : %v2, %v3\n", v2, v3);
}}
のようなコードを実行すると,test.txtが作られて,
val : 123, 4.560000
vec : (7.800000, 9.000000), (1.000000, 2.000000, 3.000000)
が書き込まれる.
**コマンドプロンプトに表示すると共にログファイルにも保存(...
#code(C){{
#include <boost/iostreams/stream.hpp>
#include <boost/algorithm/string.hpp>
//! テキストストリーム - コマンドプロンプトに表示すると共...
class rxCout : public boost::iostreams::sink
{
string m_strLog;
public:
rxCout(string fn)
{
m_strLog = fn;
}
std::streamsize write(const char* s, std::streamsize n)
{
string str;;
str.resize(n);
for(int i = 0; i < n; ++i){
str[i] = s[i];
}
cout << str;
boost::algorithm::replace_all(str, "\n", "");
static std::ofstream fout(m_strLog, std::ios::out);
fout << str << endl;
return n;
}
};
}}
使うときは,
static boost::iostreams::stream<rxCout> RXCOUT("_log.txt...
などとして,
RXCOUT << "test" << endl;
として用いる.
*vector関連 [#na613a89]
#code(C){{
//! vector型に<<オペレータを設定
template<typename T>
inline std::ostream &operator<<(std::ostream &out, const ...
{
for(size_t i = 0; i < x.size(); ++i){
out << x[i] << (i == x.size()-1 ? "" : ", ");
}
return out;
}
/*!
* vectorのidx番目の要素を削除(0スタート)
* @param[in] src vectorコンテナ
* @param[in] idx 削除要素インデックス
* @return 削除の可否
*/
template<class T>
inline void EraseSTLVectori(vector<T> &src, int idx)
{
src.erase(src.begin()+idx);
}
/*!
* vectorの特定の要素を削除
* @param[in] src vectorコンテナ
* @param[in] comp_func 削除条件関数
* @return 削除の可否
*/
template<class T>
inline int EraseSTLVector(vector<T> &src, boost::function...
{
int cnt = 0;
vector<T>::iterator itr = src.begin();
while(itr != src.end()){
if(comp_func(*itr)){
itr = src.erase(itr);
cnt++;
}
else{
++itr;
}
}
return cnt;
}
}}
*配列 [#k55289e4]
**ランダムシャッフル [#w19a563c]
STLの[[algorithm]]のrandom_shuffle
([[algorithm#zf86514c]]参照)の存在に気づく前に作ったもの.
#code(C){{
/*!
* ランダムソート
* @param[inout] arr 配列
* @param[in] n 配列の大きさ
*/
template<typename T>
inline void RandomSort(T arr[], int n)
{
int rnd;
T temp;
srand(time(NULL));
for(int i = 0; i < n; ++i){
rnd = rand()%n;
temp = arr[i];
arr[i] = arr[rnd];
arr[rnd] = temp;
}
}
/*!
* ランダムソート
* @param[inout] arr 配列
* @param[in] n 配列の大きさ
*/
template<typename T>
inline void RandomSortV(vector<T> &arr)
{
int n = (int)arr.size();
int rnd;
T temp;
srand(time(NULL));
for(int i = 0; i < n; ++i){
rnd = rand()%n;
temp = arr[i];
arr[i] = arr[rnd];
arr[rnd] = temp;
}
}
}}
*ファイル処理 [#d3add900]
**フォルダ生成 [#vba50cb0]
処理系に依存して使えない場合あり.
#code(C){{
#include <direct.h>
/*!
* ディレクトリ作成(多階層対応)
* @param[in] dir 作成ディレクトリパス
* @return 成功で1,失敗で0 (ディレクトリがすでにある場合...
*/
static int MkDir(string dir)
{
if(_mkdir(dir.c_str()) != 0){
char cur_dir[512];
_getcwd(cur_dir, 512); // カレントフォルダを確保しておく
if(_chdir(dir.c_str()) == 0){ // chdirでフォルダ存在チ...
cout << "MkDir : " << dir << " is already exist." << e...
_chdir(cur_dir); // カレントフォルダを元に戻す
return 1;
}
else{
size_t pos = dir.find_last_of("\\/");
if(pos != string::npos){ // 多階層の可能性有り
int parent = MkDir(dir.substr(0, pos+1)); // 親ディレ...
if(parent){
if(_mkdir(dir.c_str()) == 0){
return 1;
}
else{
return 0;
}
}
}
else{
return 0;
}
}
}
return 1;
}
}}
**ファイル名生成 [#f8f2ca63]
#code(C){{
/*!
* 拡張子を変更したファイル名を生成
* @param[in] fn 元ファイル名
* @param[in] ext 変更後の拡張子名
* @return 拡張子を変更したファイル名
*/
inline string GetFileNameWithExt(const string &fn, const ...
{
string new_fn = fn;
size_t pos1 = fn.rfind('.');
if(pos1 != string::npos){
new_fn = fn.substr(0, pos1);
}
return new_fn+"."+ext;
}
/*!
* ファイル名生成
* @param head : 基本ファイル名
* @param ext : 拡張子
* @param n : 連番
* @param d : 連番桁数
* @return 生成したファイル名
*/
inline string CreateFileName(const string &head, const st...
{
string file_name = head;
int dn = d-1;
if(n > 0){
dn = (int)(log10((double)n))+1;
}
else if(n == 0){
dn = 1;
}
else{
n = 0;
dn = 1;
}
for(int i = 0; i < d-dn; ++i){
file_name += "0";
}
file_name += boost::lexical_cast<std::string>(n);
file_name += ".";
file_name += ext;
return file_name;
}
}}
**ファイル探索 [#kd67d500]
boost::filesystem使用版
#code(C){{
#include <boost/function.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/fstream.hpp>
/*!
* 再帰的に全ファイルを取り出す
* @param[in] fpath フォルダパス
* @param[out] paths 見つかったファイル一覧
*/
static void SearchFiles(const boost::filesystem::path &dp...
{
// カレントディレクトリのファイル一覧
boost::filesystem::directory_iterator end;
for(boost::filesystem::directory_iterator it(dpath); it!...
if(boost::filesystem::is_directory(*it)){
SearchFiles(it->path(), paths);
}
else{
paths.push_back(it->path().file_string());
}
}
}
/*!
* 再帰的に全ファイルを取り出す
* @param[in] fpath フォルダパス
* @param[out] paths 見つかったファイル一覧
* @param[in] fpComp 検索条件
*/
static void SearchFiles(const boost::filesystem::path &dp...
{
// カレントディレクトリのファイル一覧
boost::filesystem::directory_iterator end;
for(boost::filesystem::directory_iterator it(dpath); it!...
if(boost::filesystem::is_directory(*it)){
SearchFiles(it->path(), paths);
}
else{
string fpath = it->path().file_string();
if(fpComp(fpath)){
paths.push_back(fpath);
}
}
}
}
/*!
* 指定したディレクトリ以下に指定したファイルがあるかどう...
* (サブディレクトリ以下も検索)
* @param[in] dpath ディレクトリパス
* @param[in] fname 検索ファイル名
* @param[out] found_path 見つかったパス
* @return
*/
static bool FindFile(const boost::filesystem::path &dpath...
{
if(!boost::filesystem::exists(dpath)) return false;
boost::filesystem::directory_iterator end_itr;
for(boost::filesystem::directory_iterator itr(dpath); it...
if(boost::filesystem::is_directory(itr->status())){
if(FindFile(itr->path(), fname, found_path)) return tr...
}
else if(itr->leaf() == fname){
found_path = itr->path();
return true;
}
}
return false;
}
/*!
* ファイル名比較関数(拡張子)
* @param[in] fn 比較したいファイル名
* @param[in] ext 拡張子
* @return fnの拡張子がextと同じならtrue
*/
inline bool SearchCompExt(const string &fn, const string ...
{
return (fn.find(ext, 0) != string::npos);
}
}}
Windows API使用版.RX_S2W,RX_W2Sはプロジェクトの設定でUni...
マルチバイト文字セットにしている場合は必要なし.
#code(C){{
#include <cstdlib>
#include <windows.h>
#include <tchar.h>
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
/*!
* ワイド文字列(wstring)からマルチバイト文字列(string)へ...
* - 用いる前に setlocale(LC_CTYPE, ""); としておくこと
* @param[in] src ワイド文字列(wstring)
* @return マルチバイト文字列(string)
*/
inline static std::string RX_W2S(const std::wstring &src)
{
char *mbs = new char[src.length() * MB_CUR_MAX + 1];
wcstombs(mbs, src.c_str(), src.length() * MB_CUR_MAX + 1);
std::string dst = mbs;
delete [] mbs;
return dst;
}
/*!
* マルチバイト文字列(string)からワイド文字列(wstring)へ...
* - 用いる前に setlocale(LC_CTYPE, ""); としておくこと
* @param[in] src マルチバイト文字列(string)
* @return ワイド文字列(wstring)
*/
inline static std::wstring RX_S2W(const std::string &src)
{
wchar_t *wcs = new wchar_t[src.length() + 1];
mbstowcs(wcs, src.c_str(), src.length() + 1);
std::wstring dst = wcs;
delete [] wcs;
return dst;
}
/*!
* 再帰的に全ファイル(拡張子指定)を取り出す
* @param[in] dpath フォルダパス
* @param[out] paths 見つかったファイル一覧
* @param[inout] d 現在の階層数
* @param[in] n 最大階層数
* @param[in] exts 拡張子指定
*/
static void SearchFiles(const std::string &dpath, std::ve...
const std::vector<std::string> &exts)
{
HANDLE handle;
WIN32_FIND_DATA fd;
// search first file with the wildcard "*" to find the a...
handle = FindFirstFile(RX_S2W(dpath+"\\*").c_str(), &fd);
// if fail to find the file
if(handle == INVALID_HANDLE_VALUE){
return;
}
// search next files
do{
// file name
std::string name = RX_W2S(static_cast<LPCTSTR>(fd.cFile...
std::string fpath = dpath+"\\"+name;
if(name == "." || name == "..") continue;
if((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && ...
// if the path is directory, recursively search in the...
SearchFiles(fpath, paths, d+1, n, exts);
}
else{
vector<std::string>::const_iterator i;
for(i = exts.begin(); i != exts.end(); ++i){
if(fpath.find(*i, 0) != std::string::npos) break;
}
// store the file path if the extension was matched
if(i != exts.end()){
paths.push_back(fpath);
}
}
}while(FindNextFile(handle, &fd));
// terminate the search
FindClose(handle);
}
static void SearchFiles(const std::string &dir, std::vect...
std::vector<std::string> exts, const int n = 0)
{
if(PathIsDirectory(RX_S2W(dir).c_str())){ // dirがディレ...
int d = 0;
SearchFiles(dir, paths, d, n, exts);
}
}
}}
**ファイルの存在確認 [#df246793]
boost::filesystemを用いた場合,
#code(C){{
/*!
* ファイル,フォルダの存在確認
* @param[in] path_str ファイル・フォルダパス
*/
bool ExistFile(const string &path_str)
{
fspath fnph(path_str);
return boost::filesystem::exists(fnph);
}
}}
fopenを用いる場合,
#code(C){{
int FileExist(const char *fn)
{
FILE *fp;
if( (fp = fopen(fn, "r")) == NULL ){
return 0;
}
fclose(fp);
return 1;
}
}}
**fstreamでバイナリファイルの読み書き [#h63f6121]
#code(C){{
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
using namespace std;
int main(void)
{
srand(12345);
// ランダムなデータ
const int N = 10;
double a[N];
for(int i = 0; i < N; ++i) a[i] = rand()/(double)RAND_MAX;
// バイナリファイルの書き込み
ofstream fout;
fout.open("binary_test.dat", ios::out|ios::binary); // ...
if(!fout){
cout << "file couldn't open." << endl;
return 1;
}
for(int i = 0; i < N; ++i){
//fout << a[i];
fout.write((char*)&a[i], sizeof(double));
cout << a[i] << ", "; // 確認用
}
cout << endl;
fout.close();
// バイナリファイルの読み込み
ifstream fin;
fin.open("binary_test.dat", ios::in|ios::binary); // フ...
if(!fin){
cout << "file couldn't find." << endl;
return 1;
}
double x;
for(int i = 0; i < N; ++i){
//fin >> x;
fin.read((char*)&x, sizeof(double));
cout << x << ", "; // 確認用
}
cout << endl;
fin.close();
// ファイルの一分部のみ読み取り
fin.open("binary_test.dat", ios::in|ios::binary); // フ...
if(!fin){
cout << "file couldn't find." << endl;
return 1;
}
int j = 3;
fin.seekg(j*sizeof(double)); // 読み込み場所の移動
fin.read((char*)&x, sizeof(double));
cout << j << " : " << x << endl;
fin.close();
}
}}
*数字処理 [#c2eae1de]
**数字の桁数を数える [#e6783e27]
#code(C){{
/*!
* 数字の桁数をカウント
* @param[in] n 数字
* @return 桁数
*/
inline int CountDigit(int n)
{
int d = 0;
if(n > 0){
return (int)(log10((double)n))+1;
}
else if(n == 0){
return 1;
}
else{
return (int)(log10((double)(-n)))+1;
}
}
}}
**整数値の下一桁の値を抽出 [#me2573b6]
#code(C){{
/*!
* 整数値の下一桁を返す
* @param[in] x 整数値
* @return xの下一桁
*/
inline int ExtractLastDigit(const int &x)
{
int x1 = (x < 0) ? -x : x;
return x1-(int)(x1/10)*10;
}
}}
**整数値の任意桁の値を抽出 [#l89917cb]
#code(C){{
/*!
* 整数値の任意の桁の値を抽出して返す
* @param[in] x 整数値
* @param[in] d 桁(1<=d<=xの桁数,それ以外では0を返す)
* @return 任意の桁の値
*/
inline int ExtractAnyDigit(const int &x, const int &d)
{
if(d <= 0) return 0;
int x1 = (x < 0) ? -x : x;
int c = (int)log((double)x1); // xの桁数
if(d > c) return 0;
int a = (int)pow(10.0, (double)d); // 10^d
return (x1-(int)(x1/a)*a)/(a/10);
}
}}
**0付き数字の生成 [#xf14031b]
#code(C){{
/*!
* 0付きの数字を生成
* @param[in] n 数字
* @param[in] d 桁数
* @return 0付きの数字(string)
*/
inline string GenZeroNo(int n, const int &d)
{
string zero_no = "";
int dn = d-1;
if(n > 0){
dn = (int)(log10((double)n))+1;
}
else if(n == 0){
dn = 1;
}
else{
n = 0;
dn = 1;
}
for(int i = 0; i < d-dn; ++i){
zero_no += "0";
}
zero_no += boost::lexical_cast<std::string>(n);
return zero_no;
}
}}
*時間計測 [#c0e4f172]
**ストップウォッチクラス [#l93ce153]
#code(C){{
//-------------------------------------------------------...
// インクルードファイル
//-------------------------------------------------------...
#include <iostream>
#include <vector>
#include <string>
#define RX_USE_MM
#ifdef WIN32
#include <windows.h>
#ifdef RX_USE_MM
#include <mmsystem.h>
#pragma comment (lib, "winmm.lib")
#endif
#endif
#ifdef WIN32
#ifdef RX_USE_MM
#define RXTIME DWORD
#define RXGETTIME timeGetTime
#define RXTIME2SEC 1.0e-3
//#define RXTIME2SEC 1.0
#else
#define RXTIME DWORD
#define RXGETTIME GetTickCount
#define RXTIME2SEC 1.0e-3
//#define RXTIME2SEC 1.0
#endif
#else
#define RXTIME clock_t
#define RXGETTIME clock
#define RXTIME2SEC (1.0/CLOCKS_PER_SEC)
#endif
using namespace std;
//-------------------------------------------------------...
// 時間計測クラス
//-------------------------------------------------------...
class rxTimer
{
RXTIME m_tStart, m_tEnd;
vector<double> m_vTimes;
vector<string> m_vComments;
public:
//! コンストラクタ
rxTimer(){}
//! デストラクタ
~rxTimer(){}
//! 計測開始
void Start(void)
{
m_tStart = RXGETTIME();
}
//! 計測
void Split(const string &cmnt = "", bool restart = fa...
{
m_tEnd = RXGETTIME();
double time = (double)(m_tEnd-m_tStart)*RXTIME2SEC;
m_vTimes.push_back(time);
m_vComments.push_back(cmnt);
if(restart) m_tStart = RXGETTIME();
}
//! 計測終了
void Stop(const string &cmnt = "")
{
m_tEnd = RXGETTIME();
double time = (double)(m_tEnd-m_tStart)*RXTIME2SEC;
m_vTimes.push_back(time);
m_vComments.push_back(cmnt);
m_tStart = m_tEnd = 0;
}
//! リセット
void Reset(void)
{
m_vTimes.clear();
m_vComments.clear();
m_tStart = m_tEnd = 0;
}
// 最後に記録された時間を削除
void PopBackTime(void)
{
m_vTimes.pop_back();
m_vComments.pop_back();
}
//! 時間をセット(他の計測方法で計測した結果など)
void SetTime(const double &t, const string &cmnt = "")
{
m_vTimes.push_back(t);
m_vComments.push_back(cmnt);
}
//! 時間の取得
double GetTime(int i)
{
if(i >= (int)m_vTimes.size()) return 0.0;
return m_vTimes[i];
}
//! 記録された時間数の取得
int GetTimeNum(void)
{
return (int)m_vTimes.size();
}
//! 記録された時間を画面出力
double Print(void)
{
int m = 0, mi;
if(m_vTimes.empty()){
return 0.0;
}
else{
// 総計測時間を計算
double total = 0.0;
for(int i = 0; i < (int)m_vTimes.size(); ++i){
mi = (int)m_vComments[i].size();
if(mi > m) m = mi;
total += m_vTimes[i];
}
SetTime(total, "total");
}
int cur_p = cout.precision();
cout.precision(3);
cout.setf(ios::fixed);
for(int i = 0; i < (int)m_vTimes.size(); ++i){
string spc;
for(int k = 0; k < m-(int)m_vComments[i].size(); ++k) ...
cout << m_vComments[i] << spc << " : " << m_v...
}
cout.unsetf(ios::fixed);
cout.precision(cur_p);
double t = m_vTimes.back();
PopBackTime(); // 格納した合計時間を次の計算に備...
return t;
}
//! 記録された時間を文字列に出力
double PrintToString(string &str)
{
int m = 0, mi;
if(m_vTimes.empty()){
return 0.0;
}
else{
// 総計測時間を計算
double total = 0.0;
for(int i = 0; i < (int)m_vTimes.size(); ++i){
mi = (int)m_vComments[i].size();
if(mi > m) m = mi;
total += m_vTimes[i];
}
SetTime(total, "total");
}
stringstream ss;
ss.precision(3);
ss.setf(ios::fixed);
int n = (int)m_vTimes.size();
for(int i = 0; i < n; ++i){
string spc;
for(int k = 0; k < m-(int)m_vComments[i].size(); ++k) ...
ss << m_vComments[i] << spc << " : " << m_vTi...
}
ss << "\n";
str = ss.str();
double t = m_vTimes.back();
PopBackTime(); // 格納した合計時間を次の計算に備...
return t;
}
};
}}
**平均値の計測 [#wd7a901f]
#code(C){{
class rxTimerAvg
{
public:
// 時間と計測回数
struct rxTimeAndCount
{
double time;
int count;
int idx;
};
// 時間と計測回数を文字列と関連づけるマップ
typedef map<string, rxTimeAndCount> RXMAPTC;
private:
rxTimer m_Tmr; //!< 時間計測クラス
RXMAPTC m_TimeMap; //!< 時間と計測回数を文字列と関連づけ...
public:
//! コンストラクタ
rxTimerAvg()
{
Clear();
ResetTime();
ClearTime();
}
/*!
* すべてクリア
*/
void Clear(void)
{
m_TimeMap.clear();
}
/*!
* 蓄積時間の初期化
*/
void ClearTime(void)
{
for(RXMAPTC::iterator it = m_TimeMap.begin(); it != m_T...
it->second.time = 0.0;
it->second.count = 0;
//it->second.idx = -1;
}
}
/*!
* リセット
*/
void ResetTime(void)
{
m_Tmr.Reset();
m_Tmr.Start();
}
/*!
* 計測
* @param[in] cmnt 時間蓄積用の名前
*/
void Split(const string &cmnt)
{
RXMAPTC::iterator i = m_TimeMap.find(cmnt);
m_Tmr.Stop();
if(i == m_TimeMap.end()){
m_TimeMap[cmnt].time = m_Tmr.GetTime(0);
m_TimeMap[cmnt].count = 1;
m_TimeMap[cmnt].idx = m_TimeMap.size()-1;
}
else{
m_TimeMap[cmnt].time += m_Tmr.GetTime(0);
m_TimeMap[cmnt].count++;
}
m_Tmr.Reset();
m_Tmr.Start();
}
/*!
* 総時間の取得
* @return 総時間
*/
double GetTotalTime(void)
{
if(m_TimeMap.empty()){
m_Tmr.Stop();
return m_Tmr.GetTime(0);
}
else{
double total = 0.0;
for(RXMAPTC::iterator it = m_TimeMap.begin(); it != m_...
total += it->second.time/it->second.count;
}
return total;
}
}
/*!
* 記録された時間を画面出力
*/
void Print(void)
{
int m = 0, mi;
double total = 0.0;
for(RXMAPTC::iterator it = m_TimeMap.begin(); it != m_T...
mi = (int)it->first.size();
if(mi > m) m = mi;
total += it->second.time/it->second.count;
}
int cur_p = cout.precision();
cout.precision(3);
cout.setf(ios::fixed);
for(RXMAPTC::iterator it = m_TimeMap.begin(); it != m_T...
string spc = RXFunc::GenSpace( m-(int)(it->first.size(...
RXCOUT << it->first << spc << " : " << (it->second.tim...
}
cout.unsetf(ios::fixed);
cout.precision(cur_p);
string spc = RXFunc::GenSpace(m-5);
RXCOUT << "total" << spc << " : " << total << endl;
}
/*!
* 記録された時間を文字列に出力
* @param[out] str 出力文字列
*/
void PrintToString(string &str)
{
int m = 0, mi;
double total = 0.0;
for(RXMAPTC::iterator it = m_TimeMap.begin(); it != m_T...
mi = (int)it->first.size();
if(mi > m) m = mi;
total += it->second.time/it->second.count;
}
stringstream ss;
ss.precision(3);
ss.setf(ios::fixed);
for(int i = 0; i < (int)m_TimeMap.size(); ++i){
RXMAPTC::iterator it = m_TimeMap.begin();
for(it = m_TimeMap.begin(); it != m_TimeMap.end(); ++i...
if(it->second.idx == i){
break;
}
}
string spc = RXFunc::GenSpace(m-(int)(it->first.size()...
ss << it->first << spc << " : " << (it->second.time/it...
}
string spc = RXFunc::GenSpace(m-5);
ss << "total" << spc << " : " << total << "[s]\n";
str = ss.str();
}
};
}}
**現在時刻の取得 [#r6488c77]
#code(C){{
#include <iostream>
#include <string>
#include <ctime>
const std::string WEEK[7] = { "Sunday", "Monday", "Tuesda...
int main(void)
{
time_t timer;
tm *time_st;
// 現在時刻の取得
time(&timer);
// 文字列で表示
cout << "現在時刻 : " << ctime(&timer) << endl;
// 構造体に変換
time_st = localtime(&timer);
// 日付(年は西暦年-1900,月は1月=0)
cout << "日付 : " << time_st->tm_year+1900 << "/" << tim...
// 時刻
cout << "時刻 : " << time_st->tm_hour << ":" << time_st-...
// 曜日(日曜日=0)
cout << "曜日 : " << WEEK[time_st->tm_wday] << endl;
// 年間日
cout << "年間日 : " << time_st->tm_yday << endl;
// サマータイムラグ
cout << "サマータイムラグ : " << time_st->tm_isdst << en...
return 0;
}
}}
実行結果の例
現在時刻 : Wed Aug 31 13:11:31 2011
日付 : 2011/8/31
時刻 : 13:11:31
曜日 : Wednesday
年間日 : 242
サマータイムラグ : 0
*行列 [#a81ffbad]
**行列とベクトルの積 [#jdc78fe4]
#code(C){{
/*!
* 4x4行列と4次元ベクトルのかけ算(d = m x v)
* @param[out] d 結果のベクトル
* @param[in] m 4x4行列
* @param[in] v 4次元ベクトル
*/
template<class T>
inline void MulMatVec4(T d[4], const T m[4][4], const T v...
{
d[0] = (v[0]*m[0][0]+v[1]*m[0][1]+v[2]*m[0][2]+v[3]*m[0]...
d[1] = (v[0]*m[1][0]+v[1]*m[1][1]+v[2]*m[1][2]+v[3]*m[1]...
d[2] = (v[0]*m[2][0]+v[1]*m[2][1]+v[2]*m[2][2]+v[3]*m[2]...
d[3] = (v[0]*m[3][0]+v[1]*m[3][1]+v[2]*m[3][2]+v[3]*m[3]...
}
/*!
* 4次元ベクトルと4x4行列のかけ算(d = v x m)
* @param[out] d 結果のベクトル
* @param[in] v 4次元ベクトル
* @param[in] m 4x4行列
*/
template<class T>
inline void MulVecMat4(T d[4], const T v[4], const T m[4]...
{
d[0] = (v[0]*m[0][0]+v[1]*m[1][0]+v[2]*m[2][0]+v[3]*m[3]...
d[1] = (v[0]*m[0][1]+v[1]*m[1][1]+v[2]*m[2][1]+v[3]*m[3]...
d[2] = (v[0]*m[0][2]+v[1]*m[1][2]+v[2]*m[2][2]+v[3]*m[3]...
d[3] = (v[0]*m[0][3]+v[1]*m[1][3]+v[2]*m[2][3]+v[3]*m[3]...
}
/*!
* nxn行列とn次元ベクトルのかけ算(d = m x v)
* @param[out] d 結果のベクトル
* @param[in] m nxn行列(2次元配列)
* @param[in] v n次元ベクトル
* @param[in] n ベクトル,行列のサイズ
*/
template<class T>
inline void MulMatVec(T *d, T **m, T *v, int n)
{
for(int i = 0; i < n; ++i){
d[i] = (T)0;
for(int j = 0; j < n; ++j){
d[i] += v[j]*m[i][j];
}
}
}
/*!
* nxn行列とn次元ベクトルのかけ算(d = v x m)
* @param[out] d 結果のベクトル
* @param[in] v n次元ベクトル
* @param[in] m nxn行列(2次元配列)
* @param[in] n ベクトル,行列のサイズ
*/
template<class T>
inline void MulVecMat(T *d, T *v, T **m, int n)
{
for(int i = 0; i < n; ++i){
d[i] = (T)0;
for(int j = 0; j < n; ++j){
d[i] += v[j]*m[j][i];
}
}
}
}}
**行列の画面出力 [#w69e7c75]
#code(C){{
/*!
* 行列の画面出力
* @param[in] header 出力の文字列部分
* @param[in] matrix 行列を格納した配列
* @param[in] nx,ny 行列の大きさ
* @return
*/
static void PrintMatrix(string header, double *matrix, in...
{
int n = (int)header.size();
string disp = "%f ";
for(int j = 0; j < ny; ++j){
if(j == 0){
printf("%s", header.c_str());
}
else{
for(int k = 0; k < n; ++k) printf(" ");
}
printf("| ");
for (int i = 0; i < nx; ++i){
printf(disp.c_str(), matrix[j*nx+i]);
}
printf(" |\n");
}
// printf("\n");
}
/*!
* 行列のファイル出力
* @param[in] fp ファイルポインタ
* @param[in] header 出力の文字列部分
* @param[in] matrix 行列を格納した配列
* @param[in] nx,ny 行列の大きさ
* @return
*/
static void FPrintMatrix(FILE *fp, string header, double ...
{
int n = (int)header.size();
string disp = "%f ";
for(int j = 0; j < ny; ++j){
if(j == 0){
fprintf(fp, "%s", header.c_str());
}
else{
for(int k = 0; k < n; ++k) fprintf(fp, " ");
}
fprintf(fp, "| ");
for (int i = 0; i < nx; ++i){
fprintf(fp, disp.c_str(), matrix[j*nx+i]);
}
fprintf(fp, " |\n");
}
}
/*!
* 行列のファイル出力
* @param[in] fp ファイルポインタ
* @param[in] frame フレーム番号
* @param[in] matrix 行列を格納した配列
* @param[in] nx,ny 行列の大きさ
* @return
*/
static void OutputMatrix(FILE *fp, int frame, double *mat...
{
fprintf(fp, "%d ", frame);
for(int j = 0; j < ny; ++j){
for (int i = 0; i < nx; ++i){
fprintf(fp, "%f ", matrix[j*nx+i]);
}
}
fprintf(fp, "\n");
}
}}
*グリッドの線型補間 [#s14d41d1]
#code(C){{
//-------------------------------------------------------...
// 補間関数
//-------------------------------------------------------...
inline int GET_INDEX(int i, int j, int k, int nx, int ny)...
inline int GET_INDEX_2D(int i, int j, int nx){ return j*n...
/*!
* 座標値から対応するグリッドを求める
* @param[in] x,y 座標
* @param[in] dx,dy グリッド幅
* @param[in] nx,ny グリッド数
* @param[out] i0,i1 x方向対応グリッド
* @param[out] j0,j1 y方向対応グリッド
* @param[out] s,t グリッド境界からの距離
*/
inline void GRID2D(const double &x, const double &y, cons...
int &i0, int &i1, int &j0, int &j1, double &s, dou...
{
double x0 = x/dx, y0 = y/dx;
// (x,y)のグリッド位置
i0 = (int)x0; i1 = i0+1;
j0 = (int)y0; j1 = j0+1;
s = (x0-i0);
t = (y0-j0);
// xがグリッド外のときの処理
if(i0 < 0){
i0 = 0; i1 = 1;
s = 0.0;
}
if(i1 >= nx2){
i0 = nx2-2; i1 = nx2-1;
s = 1.0;
}
// yがグリッド外のときの処理
if(j0 < 0){
j0 = 0; j1 = 1;
t = 0.0;
}
if(j1 >= ny2){
j0 = ny2-2; j1 = ny2-1;
t = 1.0;
}
}
/*!
* 座標値から対応するグリッドを求める
* @param[in] x,y 座標
* @param[in] dx,dy グリッド幅
* @param[in] nx,ny グリッド数
* @param[out] i0,i1 x方向対応グリッド
* @param[out] j0,j1 y方向対応グリッド
* @param[out] s,t グリッド境界からの距離
*/
inline void GRID3D(const double &x, const double &y, cons...
const int &nx, const int &ny, const int &nz, int &...
{
double x0 = x/dx, y0 = y/dx, z0 = z/dz;
if(x0 < 0.0) x0 = 0.0;
if(y0 < 0.0) y0 = 0.0;
if(z0 < 0.0) z0 = 0.0;
// (x,y)のグリッド位置
i0 = (int)x0; i1 = i0+1;
j0 = (int)y0; j1 = j0+1;
k0 = (int)z0; k1 = k0+1;
s = (x0-i0);
t = (y0-j0);
u = (z0-k0);
// xがグリッド外のときの処理
if(i0 < 0){
i0 = 0; i1 = 1;
s = 0.0;
}
if(i1 > nx+1){
i0 = nx; i1 = nx+1;
s = 1.0;
}
// yがグリッド外のときの処理
if(j0 < 0){
j0 = 0; j1 = 1;
t = 0.0;
}
if(j1 > ny+1){
j0 = ny; j1 = ny+1;
t = 1.0;
}
// zがグリッド外のときの処理
if(k0 < 0){
k0 = 0; k1 = 1;
u = 0.0;
}
if(k1 > nz+1){
k0 = nz; k1 = nz+1;
u = 1.0;
}
}
/*!
* 線形補間による値の取得
* @param[in] x,y 座標
* @param[in] f フィールド値(double)が格納されている配列
* @param[in] dx,dy グリッド幅
* @param[in] nx,ny グリッド数
* @return 線形補間値
*/
inline double LINEAR_INTERPOLATE_2D(const double &x, cons...
{
int i0, j0, i1, j1;
double s0, t0, s1, t1;
GRID2D(x, y, dx, dy, nx2, ny2, i0, i1, j0, j1, s1, t1);
s0 = 1.0-s1;
t0 = 1.0-t1;
// (x0,y0)における値を線形補間で求める
return s0*(t0*f[GET_INDEX_2D(i0, j0, nx2)]+t1*f[GET_INDE...
s1*(t0*f[GET_INDEX_2D(i1, j0, nx2)]+t1*f[GET_INDEX_2...
}
/*!
* 線形補間による値の取得(3D)
* @param[in] x,y,z 座標
* @param[in] f フィールド値(double)が格納されている配列
* @param[in] dx,dy,dz グリッド幅
* @param[in] nx,ny,nz グリッド数
* @return 線形補間値
*/
inline double LINEAR_INTERPOLATE_3D(const double &x, cons...
const double &dx, const double &dy, const double...
const int &nx, const int &ny, const int &nz)
{
int i0, i1, j0, j1, k0, k1;
double s0, s1, t0, t1, u0, u1;
GRID3D(x, y, z, dx, dy, dz, nx, ny, nz, i0, i1, j0, j1, ...
s0 = 1.0-s1;
t0 = 1.0-t1;
u0 = 1.0-u1;
// (x0,y0,z0)における値を線形補間で求める
return u0*(s0*(t0*f[GET_INDEX(i0, j0, k0, nx+2, ny+2)]+t...
s1*(t0*f[GET_INDEX(i1, j0, k0, nx+2, ny+2)]+t1*f[GE...
u1*(s0*(t0*f[GET_INDEX(i0, j0, k1, nx+2, ny+2)]+t1*f...
s1*(t0*f[GET_INDEX(i1, j0, k1, nx+2, ny+2)]+t1*f[GE...
}
}}
*データ構造 [#e045abd6]
**ラベルとデータのマッピングクラス [#gbd579d2]
stl::mapのラッパ.
#code(C){{
//-------------------------------------------------------...
//! ラベルとデータのマッピングを行うテンプレートクラス
//-------------------------------------------------------...
template<class Type>
class MapData
{
protected:
map<string, Type> m_Map; //!< ラベルとデータのマップ
string m_strCurrentMap; //!< 現在のデータを示すラベル
public:
/*!
* ラベルnameのデータを検索して返す
* @param[in] name ラベル名
* @return nameに対応するデータ
*/
Type LookupData(const char *name)
{
map<string, Type>::iterator i = m_Map.find(name);
if(i == m_Map.end())
return NULL;
else
return m_Map[name];
}
/*!
* 現在のデータを取得
* @return 現在のデータ
*/
Type GetCurrentData()
{
return m_Map[m_strCurrentMap];
}
/*!
* 現在のラベルを取得
* @return 現在のラベル
*/
string GetCurrentLabel()
{
return m_strCurrentMap;
}
/*!
* 現在のデータの設定
* @param[in] name 設定したいラベル
* @return 設定したデータ
*/
Type SetCurrentData(const char *name)
{
Type data = LookupData(name);
if(data){
m_strCurrentMap = name;
}
return data;
}
/*!
* データ作成
* @param[in] name ラベル
* @param[in] data データ
*/
void CreateData(const char *name, Type data)
{
Type data0 = LookupData(name);
if(!data0){
m_Map[name] = data;
m_strCurrentMap = name;
}
}
/*!
* 全データ削除
*/
void Clear(void)
{
m_Map.clear();
m_strCurrentMap = "";
}
/*!
* キー文字列リストの取得
* @param[out] strs キー文字列リスト
*/
void GetStrings(vector<string> &strs)
{
map<string, Type>::iterator it;
for(it = m_Map.begin(); it != m_Map.end(); ++it){
strs.push_back(it->first);
}
}
};
}}
ページ名: