Skip to content

Instantly share code, notes, and snippets.

@yossi-tahara
Last active June 6, 2017 15:29
Show Gist options
  • Save yossi-tahara/271c2ca24f9003fcd8cca47c05d59770 to your computer and use it in GitHub Desktop.
Save yossi-tahara/271c2ca24f9003fcd8cca47c05d59770 to your computer and use it in GitHub Desktop.
Theolizer技術解説(2016/09/08) 少し複雑なデータを保存/回復する(ポインタ保存/回復の巻)
#[[###########################################################################
Theolizer紹介用サンプルCMakeLists.txt
]]############################################################################
if("${CMAKE_VERSION}" STREQUAL "")
set(CMAKE_VERSION, 3.5.0)
endif()
cmake_minimum_required(VERSION ${CMAKE_VERSION})
message(STATUS "BOOST_ROOT=${BOOST_ROOT}")
#-----------------------------------------------------------------------------
# プロジェクト設定
#-----------------------------------------------------------------------------
set(TARGET_NAME sample)
set(SOURCE_LIST main.cpp sub.cpp)
set(HEADER_LIST common.h)
project(${TARGET_NAME} VERSION 1.0.0)
#-----------------------------------------------------------------------------
# ビルド設定
#-----------------------------------------------------------------------------
# MSVCの通常使わないビルド・モードとZERO_CHECKプロジェクトの削除
set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configs" FORCE)
set(CMAKE_SUPPRESS_REGENERATION TRUE)
# Theolizer
find_package(THEOLIZER)
# Options
if (${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
add_definitions(-D_UNICODE -DUNICODE)
set(CMAKE_DEBUG_POSTFIX "d")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# MinGWの不具合(https://sourceforge.net/p/mingw-w64/discussion/723797/thread/c6b70624/#7f0a)暫定対処
if((CMAKE_COMPILER_IS_MINGW) AND (CMAKE_SIZEOF_VOID_P EQUAL 8))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj")
endif()
endif()
# example
add_executable(${TARGET_NAME} ${SOURCE_LIST} ${HEADER_LIST})
setup_theolizer(${TARGET_NAME} StaticWithBoost)
#-----------------------------------------------------------------------------
# テスト実行
#-----------------------------------------------------------------------------
enable_testing()
add_test(NAME ${TARGET_NAME} COMMAND $<TARGET_FILE:${TARGET_NAME}>)
add_custom_target(BuildTest COMMAND "ctest" "-V" "-C" $<CONFIG>)
add_dependencies(BuildTest ${TARGET_NAME})
//############################################################################
// Theolizer解説用サンプル・プログラム2
//
// 簡単な家計簿用共通定義
//############################################################################
#if !defined(COMMON_H)
#define COMMON_H
// ***************************************************************************
// インクルード
// ***************************************************************************
// 標準ライブラリ
#include <string>
// Theolizerライブラリ
#include <theolizer/serializer_json.h>
#include <theolizer/list.h>
// ***************************************************************************
// 構造体定義
// ***************************************************************************
#define POINTEE THEOLIZER_ANNOTATE(FS:<>Pointee)
//----------------------------------------------------------------------------
// 科目管理
//----------------------------------------------------------------------------
struct Item
{
Item* mParent; // 親科目
std::string mName; // 科目名
bool mIsAssets; // 資産(財布や預金)
int mAssetsIncrease;// 増加した資産金額
bool mDoManage; // 残高管理の有無
int mAmount; // 残高
theolizer::ListPointee<Item> mChildren; // 子科目
};
typedef theolizer::ListPointee<Item>::iterator ChildIterator;
//----------------------------------------------------------------------------
// 取引記録
//----------------------------------------------------------------------------
struct Date
{
short mYear; // 年
char mMonth; // 月(1-12)
char mDay; // 日(1-31)
};
struct Trade
{
Date mDate; // 取引日
Item* mDebitItem; // 購入品(借方科目)
int mAmount; // 金額
Item* mCreditItem; // 財布 (貸方科目)
std::string mNote; // 備考
};
//----------------------------------------------------------------------------
// 家計簿
//----------------------------------------------------------------------------
struct HouseholdAccounts
{
Item mItemTree POINTEE; // 科目ツリー
std::list<Trade> mTradeList; // 取引のリスト
};
typedef std::list<Trade>::iterator TradeIterator;
// ***************************************************************************
// 関数群
// ***************************************************************************
//----------------------------------------------------------------------------
// 初期設定
//----------------------------------------------------------------------------
void initialize(HouseholdAccounts* oHouseholdAccounts);
void display( HouseholdAccounts* iHouseholdAccounts);
void calculate( HouseholdAccounts* ioHouseholdAccounts);
#endif
{
"SerialzierName":"JsonTheolizer",
"GlobalVersionNo":1,
"TypeInfoList":[1]
}
{
"mItemTree":[1,{
"mParent":0,
"mName":"家計",
"mIsAssets":0,
"mAssetsIncrease":0,
"mDoManage":0,
"mAmount":0,
"mChildren":[
3,
[2,{
"mParent":1,
"mName":"収入",
"mIsAssets":0,
"mAssetsIncrease":0,
"mDoManage":0,
"mAmount":0,
"mChildren":[
2,
[3,{
"mParent":2,
"mName":"給料",
"mIsAssets":0,
"mAssetsIncrease":0,
"mDoManage":0,
"mAmount":0,
"mChildren":[
0
]
}],
[4,{
"mParent":2,
"mName":"雑収入",
"mIsAssets":0,
"mAssetsIncrease":0,
"mDoManage":0,
"mAmount":0,
"mChildren":[
0
]
}]
]
}],
[5,{
"mParent":1,
"mName":"支出",
"mIsAssets":0,
"mAssetsIncrease":0,
"mDoManage":0,
"mAmount":0,
"mChildren":[
2,
[6,{
"mParent":5,
"mName":"主食",
"mIsAssets":0,
"mAssetsIncrease":0,
"mDoManage":0,
"mAmount":0,
"mChildren":[
2,
[7,{
"mParent":6,
"mName":"お米",
"mIsAssets":0,
"mAssetsIncrease":0,
"mDoManage":0,
"mAmount":0,
"mChildren":[
0
]
}],
[8,{
"mParent":6,
"mName":"パン",
"mIsAssets":0,
"mAssetsIncrease":0,
"mDoManage":0,
"mAmount":0,
"mChildren":[
0
]
}]
]
}],
[9,{
"mParent":5,
"mName":"副食",
"mIsAssets":0,
"mAssetsIncrease":0,
"mDoManage":0,
"mAmount":0,
"mChildren":[
3,
[10,{
"mParent":9,
"mName":"肉魚",
"mIsAssets":0,
"mAssetsIncrease":0,
"mDoManage":0,
"mAmount":0,
"mChildren":[
0
]
}],
[11,{
"mParent":9,
"mName":"野菜",
"mIsAssets":0,
"mAssetsIncrease":0,
"mDoManage":0,
"mAmount":0,
"mChildren":[
0
]
}],
[12,{
"mParent":9,
"mName":"果物",
"mIsAssets":0,
"mAssetsIncrease":0,
"mDoManage":0,
"mAmount":0,
"mChildren":[
0
]
}]
]
}]
]
}],
[13,{
"mParent":1,
"mName":"現金",
"mIsAssets":1,
"mAssetsIncrease":0,
"mDoManage":0,
"mAmount":0,
"mChildren":[
2,
[14,{
"mParent":13,
"mName":"財布",
"mIsAssets":1,
"mAssetsIncrease":0,
"mDoManage":1,
"mAmount":35592,
"mChildren":[
0
]
}],
[15,{
"mParent":13,
"mName":"預金",
"mIsAssets":1,
"mAssetsIncrease":0,
"mDoManage":1,
"mAmount":147135,
"mChildren":[
0
]
}]
]
}]
]
}],
"mTradeList":[
10,
{
"mDate":{
"mYear":2016,
"mMonth":8,
"mDay":22
},
"mDebitItem":8,
"mAmount":158,
"mCreditItem":14,
"mNote":"六切り1袋"
},
{
"mDate":{
"mYear":2016,
"mMonth":8,
"mDay":22
},
"mDebitItem":10,
"mAmount":269,
"mCreditItem":14,
"mNote":"鶏肉200g"
},
{
"mDate":{
"mYear":2016,
"mMonth":8,
"mDay":22
},
"mDebitItem":11,
"mAmount":182,
"mCreditItem":14,
"mNote":"キャベツ1玉"
},
{
"mDate":{
"mYear":2016,
"mMonth":8,
"mDay":22
},
"mDebitItem":12,
"mAmount":113,
"mCreditItem":14,
"mNote":"バナナ1房"
},
{
"mDate":{
"mYear":2016,
"mMonth":8,
"mDay":22
},
"mDebitItem":15,
"mAmount":254536,
"mCreditItem":3,
"mNote":"セオライド テクノロジー"
},
{
"mDate":{
"mYear":2016,
"mMonth":8,
"mDay":25
},
"mDebitItem":14,
"mAmount":50000,
"mCreditItem":15,
"mNote":"生活費"
},
{
"mDate":{
"mYear":2016,
"mMonth":8,
"mDay":25
},
"mDebitItem":7,
"mAmount":4652,
"mCreditItem":14,
"mNote":"こしひかり10Kg"
},
{
"mDate":{
"mYear":2016,
"mMonth":8,
"mDay":25
},
"mDebitItem":10,
"mAmount":685,
"mCreditItem":14,
"mNote":"豚肉500g"
},
{
"mDate":{
"mYear":2016,
"mMonth":8,
"mDay":25
},
"mDebitItem":11,
"mAmount":152,
"mCreditItem":14,
"mNote":"ほうれん草"
},
{
"mDate":{
"mYear":2016,
"mMonth":8,
"mDay":25
},
"mDebitItem":11,
"mAmount":136,
"mCreditItem":14,
"mNote":"人参"
}
]
}
//############################################################################
// Theolizer解説用サンプル・プログラム2
//
// メイン処理(データ保存/回復サンプル)
//############################################################################
// ***************************************************************************
// インクルード
// ***************************************************************************
// 標準ライブラリ
#include <iostream>
#include <fstream>
// 共通定義
#include "common.h"
// Theolizer自動生成先
#include "main.cpp.theolizer.hpp"
// ***************************************************************************
// メイン
// ***************************************************************************
int main(int argc, char* argv[])
{
//----------------------------------------------------------------------------
// 家計簿設定
//----------------------------------------------------------------------------
// 保存用家計簿
HouseholdAccounts aHouseholdAccountsSave;
// 初期設定(科目と取引データを設定している)
initialize(&aHouseholdAccountsSave);
//----------------------------------------------------------------------------
// 保存
//----------------------------------------------------------------------------
// 保存処理
{
// 保存先のファイルをオープンする
std::ofstream aStream("HouseholdAccounts.json");
// パラメータの意味
// aStream 出力先のファイル
// theolizer::CheckMode::NoTypeCheck 型チェック無し
// false PrettyPrintする(デフォルト)
// true 例外を発行しない
theolizer::JsonOSerializer<> js(aStream, theolizer::CheckMode::NoTypeCheck, false, true);
// 家計簿をHouseholdAccounts.jsonファイルへ保存する
THEOLIZER_PROCESS(js, aHouseholdAccountsSave);
// オブジェクト追跡の締め
js.clearTracking();
// エラー・チェック(例外を禁止している場合に必要)
theolizer::ErrorInfo aErrorInfo=js.getErrorInfo();
if (aErrorInfo)
{
std::cout << aErrorInfo.getMessage() << std::endl;
js.resetError(); // チェックしたことを通知する
}
}
//----------------------------------------------------------------------------
// 回復
//----------------------------------------------------------------------------
// 回復用家計簿(正確に回復できていることを示すため、保存用と別領域)
HouseholdAccounts aHouseholdAccountsLoad;
// 回復処理
{
// 回復元のファイルをオープンする
std::ifstream aStream("HouseholdAccounts.json");
// パラメータの意味
// aStream 入力元のファイル
// true 例外を発行しない
theolizer::JsonISerializer<> js(aStream, true);
// 家計簿をHouseholdAccounts.jsonファイルから回復する
THEOLIZER_PROCESS(js, aHouseholdAccountsLoad);
// オブジェクト追跡の締め
js.clearTracking();
// エラー・チェック(例外を禁止している場合に必要)
theolizer::ErrorInfo aErrorInfo = js.getErrorInfo();
if (aErrorInfo)
{
std::cout << aErrorInfo.getMessage() << std::endl;
js.resetError(); // チェックしたことを通知する
}
}
//----------------------------------------------------------------------------
// 内容表示と簡単な集計処理
//----------------------------------------------------------------------------
std::cout << u8"<<< 保存したサンプル・データ >>>\n";
display(&aHouseholdAccountsSave);
std::cout << u8"\n\n<<< 回復したサンプル・データ >>>\n";
display(&aHouseholdAccountsLoad);
std::cout << u8"\n\n<<< サンプルの集計結果 >>>\n";
calculate(&aHouseholdAccountsLoad);
return 0;
}
#ifdef THEOLIZER_WRITE_CODE // ###### Item ######
#define THEOLIZER_GENERATED_LAST_VERSION_NO THEOLIZER_INTERNAL_DEFINE(kLastVersionNo,1)
#define THEOLIZER_GENERATED_FULL_AUTO Item
// ---<<< Version.1 >>>---
#define THEOLIZER_GENERATED_VERSION_NO THEOLIZER_INTERNAL_DEFINE(kVersionNo,1)
#define THEOLIZER_GENERATED_CLASS_NAME()\
THEOLIZER_INTERNAL_CLASS_NAME((u8"Item"))
#define THEOLIZER_GENERATED_ELEMENT_MAP emName
#define THEOLIZER_GENERATED_ELEMENT_LIST()\
THEOLIZER_INTERNAL_ELEMENT_N((mParent),mParent,etmDefault,\
(theolizerD::All),\
(Item *))\
THEOLIZER_INTERNAL_ELEMENT_N((mName),mName,etmDefault,\
(theolizerD::All),\
(std::string))\
THEOLIZER_INTERNAL_ELEMENT_N((mIsAssets),mIsAssets,etmDefault,\
(theolizerD::All),\
(bool))\
THEOLIZER_INTERNAL_ELEMENT_N((mAssetsIncrease),mAssetsIncrease,etmDefault,\
(theolizerD::All),\
(int))\
THEOLIZER_INTERNAL_ELEMENT_N((mDoManage),mDoManage,etmDefault,\
(theolizerD::All),\
(bool))\
THEOLIZER_INTERNAL_ELEMENT_N((mAmount),mAmount,etmDefault,\
(theolizerD::All),\
(int))\
THEOLIZER_INTERNAL_ELEMENT_N((mChildren),mChildren,etmDefault,\
(theolizerD::All),\
(theolizer::ListPointee<Item>))
#include <theolizer/internal/version_auto.inc>
#undef THEOLIZER_GENERATED_VERSION_NO
#endif//THEOLIZER_WRITE_CODE // ###### Item ######
#ifdef THEOLIZER_WRITE_CODE // ###### Date ######
#define THEOLIZER_GENERATED_LAST_VERSION_NO THEOLIZER_INTERNAL_DEFINE(kLastVersionNo,1)
#define THEOLIZER_GENERATED_FULL_AUTO Date
// ---<<< Version.1 >>>---
#define THEOLIZER_GENERATED_VERSION_NO THEOLIZER_INTERNAL_DEFINE(kVersionNo,1)
#define THEOLIZER_GENERATED_CLASS_NAME()\
THEOLIZER_INTERNAL_CLASS_NAME((u8"Date"))
#define THEOLIZER_GENERATED_ELEMENT_MAP emName
#define THEOLIZER_GENERATED_ELEMENT_LIST()\
THEOLIZER_INTERNAL_ELEMENT_N((mYear),mYear,etmDefault,\
(theolizerD::All),\
(short))\
THEOLIZER_INTERNAL_ELEMENT_N((mMonth),mMonth,etmDefault,\
(theolizerD::All),\
(char))\
THEOLIZER_INTERNAL_ELEMENT_N((mDay),mDay,etmDefault,\
(theolizerD::All),\
(char))
#include <theolizer/internal/version_auto.inc>
#undef THEOLIZER_GENERATED_VERSION_NO
#endif//THEOLIZER_WRITE_CODE // ###### Date ######
#ifdef THEOLIZER_WRITE_CODE // ###### Trade ######
#define THEOLIZER_GENERATED_LAST_VERSION_NO THEOLIZER_INTERNAL_DEFINE(kLastVersionNo,1)
#define THEOLIZER_GENERATED_FULL_AUTO Trade
// ---<<< Version.1 >>>---
#define THEOLIZER_GENERATED_VERSION_NO THEOLIZER_INTERNAL_DEFINE(kVersionNo,1)
#define THEOLIZER_GENERATED_CLASS_NAME()\
THEOLIZER_INTERNAL_CLASS_NAME((u8"Trade"))
#define THEOLIZER_GENERATED_ELEMENT_MAP emName
#define THEOLIZER_GENERATED_ELEMENT_LIST()\
THEOLIZER_INTERNAL_ELEMENT_KN((mDate),mDate,etmDefault,\
(theolizerD::All),\
(Date),1)\
THEOLIZER_INTERNAL_ELEMENT_N((mDebitItem),mDebitItem,etmDefault,\
(theolizerD::All),\
(Item *))\
THEOLIZER_INTERNAL_ELEMENT_N((mAmount),mAmount,etmDefault,\
(theolizerD::All),\
(int))\
THEOLIZER_INTERNAL_ELEMENT_N((mCreditItem),mCreditItem,etmDefault,\
(theolizerD::All),\
(Item *))\
THEOLIZER_INTERNAL_ELEMENT_N((mNote),mNote,etmDefault,\
(theolizerD::All),\
(std::string))
#include <theolizer/internal/version_auto.inc>
#undef THEOLIZER_GENERATED_VERSION_NO
#endif//THEOLIZER_WRITE_CODE // ###### Trade ######
#ifdef THEOLIZER_WRITE_CODE // ###### HouseholdAccounts ######
#define THEOLIZER_GENERATED_LAST_VERSION_NO THEOLIZER_INTERNAL_DEFINE(kLastVersionNo,1)
#define THEOLIZER_GENERATED_FULL_AUTO HouseholdAccounts
// ---<<< Version.1 >>>---
#define THEOLIZER_GENERATED_VERSION_NO THEOLIZER_INTERNAL_DEFINE(kVersionNo,1)
#define THEOLIZER_GENERATED_CLASS_NAME()\
THEOLIZER_INTERNAL_CLASS_NAME((u8"HouseholdAccounts"))
#define THEOLIZER_GENERATED_ELEMENT_MAP emName
#define THEOLIZER_GENERATED_ELEMENT_LIST()\
THEOLIZER_INTERNAL_ELEMENT_KN((mItemTree),mItemTree,etmPointee,\
(theolizerD::All),\
(Item),1)\
THEOLIZER_INTERNAL_ELEMENT_N((mTradeList),mTradeList,etmDefault,\
(theolizerD::All),\
(std::list<Trade>))
#include <theolizer/internal/version_auto.inc>
#undef THEOLIZER_GENERATED_VERSION_NO
#endif//THEOLIZER_WRITE_CODE // ###### HouseholdAccounts ######
#ifdef THEOLIZER_WRITE_CODE // ###### Global VersionNo. Table ######
THEOLIZER_GENERATED_GLOBAL_TABLE();
#endif//THEOLIZER_WRITE_CODE // ###### Global VersionNo. Table ######
<<< 保存したサンプル・データ >>>
--- 科目 ---
家計
収入
給料
雑収入
支出
主食
お米
パン
副食
肉魚
野菜
果物
現金
財布 残高:35592
預金 残高:147135
--- 取引 ---
2016/08/22 家計/支出/主食/パン <- 家計/現金/財布( 158) : 六切り1袋
2016/08/22 家計/支出/副食/肉魚 <- 家計/現金/財布( 269) : 鶏肉200g
2016/08/22 家計/支出/副食/野菜 <- 家計/現金/財布( 182) : キャベツ1玉
2016/08/22 家計/支出/副食/果物 <- 家計/現金/財布( 113) : バナナ1房
2016/08/22 家計/現金/預金 <- 家計/収入/給料(254536) : セオライド テクノロジー
2016/08/25 家計/現金/財布 <- 家計/現金/預金( 50000) : 生活費
2016/08/25 家計/支出/主食/お米 <- 家計/現金/財布( 4652) : こしひかり10Kg
2016/08/25 家計/支出/副食/肉魚 <- 家計/現金/財布( 685) : 豚肉500g
2016/08/25 家計/支出/副食/野菜 <- 家計/現金/財布( 152) : ほうれん草
2016/08/25 家計/支出/副食/野菜 <- 家計/現金/財布( 136) : 人参
<<< 回復したサンプル・データ >>>
--- 科目 ---
家計
収入
給料
雑収入
支出
主食
お米
パン
副食
肉魚
野菜
果物
現金
財布 残高:35592
預金 残高:147135
--- 取引 ---
2016/08/22 家計/支出/主食/パン <- 家計/現金/財布( 158) : 六切り1袋
2016/08/22 家計/支出/副食/肉魚 <- 家計/現金/財布( 269) : 鶏肉200g
2016/08/22 家計/支出/副食/野菜 <- 家計/現金/財布( 182) : キャベツ1玉
2016/08/22 家計/支出/副食/果物 <- 家計/現金/財布( 113) : バナナ1房
2016/08/22 家計/現金/預金 <- 家計/収入/給料(254536) : セオライド テクノロジー
2016/08/25 家計/現金/財布 <- 家計/現金/預金( 50000) : 生活費
2016/08/25 家計/支出/主食/お米 <- 家計/現金/財布( 4652) : こしひかり10Kg
2016/08/25 家計/支出/副食/肉魚 <- 家計/現金/財布( 685) : 豚肉500g
2016/08/25 家計/支出/副食/野菜 <- 家計/現金/財布( 152) : ほうれん草
2016/08/25 家計/支出/副食/野菜 <- 家計/現金/財布( 136) : 人参
<<< サンプルの集計結果 >>>
家計 : 0円の収入
家計/収入 : 254536円の収入
家計/収入/給料 : 254536円の収入
家計/収入/雑収入 : 0円の収入
家計/支出 : 6347円の消費
家計/支出/主食 : 4810円の消費
家計/支出/主食/お米 : 4652円の消費
家計/支出/主食/パン : 158円の消費
家計/支出/副食 : 1537円の消費
家計/支出/副食/肉魚 : 954円の消費
家計/支出/副食/野菜 : 470円の消費
家計/支出/副食/果物 : 113円の消費
家計/現金 : 248189円の増加
家計/現金/財布 : 43653円の増加 残高は 79245円
家計/現金/預金 : 204536円の増加 残高は351671円
//############################################################################
// Theolizer解説用サンプル・プログラム2
//
// 補助関数群(家計簿にサンプル・データ設定/表示)
//############################################################################
// ***************************************************************************
// インクルード
// ***************************************************************************
// 標準ライブラリ
#include <iostream>
#include <fstream>
// 共通定義
#include "common.h"
// ***************************************************************************
// 家計簿にサンプル・データ設定
// ***************************************************************************
//----------------------------------------------------------------------------
// find 科目
//----------------------------------------------------------------------------
Item* find(Item* iItem, char const* iItemName)
{
if (iItem->mName == iItemName)
return iItem;
for (ChildIterator itr=iItem->mChildren.begin(); itr != iItem->mChildren.end(); ++itr)
{
Item* ret=find(&(*itr), iItemName);
if (ret)
return ret;
}
return NULL;
}
//----------------------------------------------------------------------------
// 科目ツリー設定
// 家計
// 収入
// 給料
// 雑収入
// 支出
// 食費
// 主食
// お米
// パン
// 副食
// 肉魚
// 野菜
// 果物
// 現金
// 財布
// 預金
//----------------------------------------------------------------------------
// ---<<< 子科目設定 >>>---
Item* pushItem
(
Item* oItem,
char const* iItemName,
bool iIsAssets=false,
bool iDoManage=false,
int iAmount=0
)
{
Item aItem;
aItem.mParent =oItem;
aItem.mName =iItemName;
aItem.mIsAssets =iIsAssets;
aItem.mAssetsIncrease =0;
aItem.mDoManage =iDoManage;
aItem.mAmount =iAmount;
oItem->mChildren.push_back(aItem);
return &(oItem->mChildren.back());
}
// ---<<< 科目ツリー設定 >>>---
void makeItems(Item* oItemTree)
{
oItemTree->mParent =NULL;
oItemTree->mName =u8"家計";
oItemTree->mIsAssets =false;
oItemTree->mAssetsIncrease =0;
oItemTree->mDoManage =false;
oItemTree->mAmount =0;
Item* aLayer0=oItemTree;
{
Item* aLayer1;
aLayer1=pushItem(aLayer0, u8"収入");
{
pushItem(aLayer1, u8"給料");
pushItem(aLayer1, u8"雑収入");
}
aLayer1=pushItem(aLayer0, u8"支出");
{
Item* aLayer2;
aLayer2=pushItem(aLayer1, u8"主食");
{
pushItem(aLayer2, u8"お米");
pushItem(aLayer2, u8"パン");
}
aLayer2=pushItem(aLayer1, u8"副食");
{
pushItem(aLayer2, u8"肉魚");
pushItem(aLayer2, u8"野菜");
pushItem(aLayer2, u8"果物");
}
}
aLayer1=pushItem(aLayer0, u8"現金", true);
{
pushItem(aLayer1, u8"財布", true, true, 35592);
pushItem(aLayer1, u8"預金", true, true, 147135);
}
}
}
//----------------------------------------------------------------------------
// 取引リスト設定
//----------------------------------------------------------------------------
// ---<<< 取引設定サブ >>>---
bool pushTrade
(
HouseholdAccounts* oHA,
short iYear,
char iMonth,
char iDay,
char const* iDebitName,
int iAmount,
char const* iCreditName,
char const* iNote
)
{
Trade aTrade;
aTrade.mDate.mYear = iYear;
aTrade.mDate.mMonth = iMonth;
aTrade.mDate.mDay = iDay;
aTrade.mDebitItem = find(&(oHA->mItemTree), iDebitName);
aTrade.mAmount = iAmount;
aTrade.mCreditItem = find(&(oHA->mItemTree), iCreditName);
aTrade.mNote = iNote;
if (aTrade.mDebitItem == NULL)
{
std::cerr << theolizer::print(u8"商品名(%s)が不正です。", iDebitName) << std::endl;
return false;
}
if (aTrade.mCreditItem == NULL)
{
std::cerr << theolizer::print(u8"商品名(%s)が不正です。", iCreditName) << std::endl;
return false;
}
oHA->mTradeList.push_back(aTrade);
return true;
}
// ---<<< 取引リスト設定 >>>---
void makeTrades(HouseholdAccounts* oHA)
{
pushTrade(oHA, 2016, 8,22, u8"パン", 158, u8"財布", u8"六切り1袋");
pushTrade(oHA, 2016, 8,22, u8"肉魚", 269, u8"財布", u8"鶏肉200g");
pushTrade(oHA, 2016, 8,22, u8"野菜", 182, u8"財布", u8"キャベツ1玉");
pushTrade(oHA, 2016, 8,22, u8"果物", 113, u8"財布", u8"バナナ1房");
pushTrade(oHA, 2016, 8,22, u8"預金", 254536, u8"給料", u8"セオライド テクノロジー");
pushTrade(oHA, 2016, 8,25, u8"財布", 50000, u8"預金", u8"生活費");
pushTrade(oHA, 2016, 8,25, u8"お米", 4652, u8"財布", u8"こしひかり10Kg");
pushTrade(oHA, 2016, 8,25, u8"肉魚", 685, u8"財布", u8"豚肉500g");
pushTrade(oHA, 2016, 8,25, u8"野菜", 152, u8"財布", u8"ほうれん草");
pushTrade(oHA, 2016, 8,25, u8"野菜", 136, u8"財布", u8"人参");
}
//----------------------------------------------------------------------------
// 設定
//----------------------------------------------------------------------------
void initialize(HouseholdAccounts* oHouseholdAccounts)
{
makeItems(&(oHouseholdAccounts->mItemTree));
makeTrades(oHouseholdAccounts);
}
// ***************************************************************************
// 家計簿表示
// ***************************************************************************
//----------------------------------------------------------------------------
// 科目名結合
//----------------------------------------------------------------------------
std::string getFullName(Item* iItem)
{
if (iItem->mParent != NULL)
{
return getFullName(iItem->mParent) + "/" + iItem->mName;
}
else
{
return iItem->mName;
}
}
//----------------------------------------------------------------------------
// 科目表示
//----------------------------------------------------------------------------
void displayItems(int iIndent, Item* iItem)
{
std::cout << std::string(iIndent*2, ' ') << iItem->mName;
if (iItem->mDoManage)
{
std::cout << u8" 残高:" << iItem->mAmount;
}
std::cout << "\n";
for (ChildIterator itr=iItem->mChildren.begin(); itr != iItem->mChildren.end(); ++itr)
{
displayItems(iIndent+1, &(*itr));
}
}
//----------------------------------------------------------------------------
// 取引表示
//----------------------------------------------------------------------------
void displayTrades(HouseholdAccounts* iHA)
{
for (TradeIterator itr=iHA->mTradeList.begin(); itr != iHA->mTradeList.end(); ++itr)
{
std::cout << theolizer::print("%04d/%02d/%02d %s <- %s(%6d) : %s\n",
itr->mDate.mYear,
itr->mDate.mMonth+0,
itr->mDate.mDay+0,
getFullName(itr->mDebitItem),
getFullName(itr->mCreditItem),
itr->mAmount,
itr->mNote);
}
}
//----------------------------------------------------------------------------
// 全体表示
//----------------------------------------------------------------------------
void display(HouseholdAccounts* iHouseholdAccounts)
{
std::cout << u8"--- 科目 ---\n";
displayItems(0, &(iHouseholdAccounts->mItemTree));
std::cout << u8"\n--- 取引 ---\n";
displayTrades(iHouseholdAccounts);
}
// ***************************************************************************
// 家計簿処理と結果表示
// ***************************************************************************
//----------------------------------------------------------------------------
// 初期化
//----------------------------------------------------------------------------
void clearIncrease(Item* iItem)
{
iItem->mAssetsIncrease=0;
for (ChildIterator itr=iItem->mChildren.begin(); itr != iItem->mChildren.end(); ++itr)
{
clearIncrease(&(*itr));
}
}
//----------------------------------------------------------------------------
// 結果表示
//----------------------------------------------------------------------------
void displayAmount(Item* iItem)
{
std::cout << getFullName(iItem);
if (iItem->mIsAssets)
{
if (0 <= iItem->mAssetsIncrease)
{
std::cout << theolizer::print(u8" : %6d円の増加", iItem->mAssetsIncrease);
}
else
{
std::cout << theolizer::print(u8" : %6d円の減少", -iItem->mAssetsIncrease);
}
}
else
{
if (0 <= iItem->mAssetsIncrease)
{
std::cout << theolizer::print(u8" : %6d円の収入", iItem->mAssetsIncrease);
}
else
{
std::cout << theolizer::print(u8" : %6d円の消費", -iItem->mAssetsIncrease);
}
}
if (iItem->mDoManage)
{
std::cout << theolizer::print(u8" 残高は%6d円\n", iItem->mAmount);
}
else
{
std::cout << "\n";
}
for (ChildIterator itr=iItem->mChildren.begin(); itr != iItem->mChildren.end(); ++itr)
{
displayAmount(&(*itr));
}
}
//----------------------------------------------------------------------------
// 計算
//----------------------------------------------------------------------------
void calculate(HouseholdAccounts* ioHouseholdAccounts)
{
// 初期化
clearIncrease(&(ioHouseholdAccounts->mItemTree));
// 集計
for (TradeIterator itr=ioHouseholdAccounts->mTradeList.begin();
itr != ioHouseholdAccounts->mTradeList.end();
++itr)
{
// ---<<< 増減処理 >>>---
// 借方の資産は増える/借方の非資産は減る
for (Item* p=itr->mDebitItem; p != NULL; p=p->mParent)
{
if (p->mIsAssets)
{
p->mAssetsIncrease += itr->mAmount;
}
else
{
p->mAssetsIncrease -= itr->mAmount;
}
}
// 貸方の資産は減る/借方の非資産は増える
for (Item* p=itr->mCreditItem; p != NULL; p=p->mParent)
{
if (p->mIsAssets)
{
p->mAssetsIncrease -= itr->mAmount;
}
else
{
p->mAssetsIncrease += itr->mAmount;
}
}
// ---<<< 残高処理 >>>---
// 借方
if (itr->mDebitItem->mDoManage)
{
itr->mDebitItem->mAmount += itr->mAmount;
}
// 貸方
if (itr->mCreditItem->mDoManage)
{
itr->mCreditItem->mAmount -= itr->mAmount;
}
}
displayAmount(&(ioHouseholdAccounts->mItemTree));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment