Friday, October 07, 2011

Add All Subdirectories in CMake

有時候,某個目錄下有那些子目錄要用add_subdirectory加到build system裡是動態的(也就是不能寫死),像是我們用android的repo工具,projects目錄下要掛什麼sub-project完全就是看default.xml,那麼這個時候cmake的add_subdirectory就整個很沒用,所以就只好用regex硬幹...如果有人碰到一樣的問題可以用以下的方法:



file(GLOB all_valid_subdirs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*/CMakeLists.txt")

foreach(dir ${all_valid_subdirs})
message(STATUS "path = ${dir}")
if(${dir} MATCHES "^([^/]*)//CMakeLists.txt")
string(REGEX REPLACE "^([^/]*)//CMakeLists.txt" "\\1" dir_trimmed ${dir})
add_subdirectory(${dir_trimmed})
endif()
endforeach(dir)

Thursday, October 06, 2011

"You've got to find what you love" - Steve

In memorial of our great leader, Steve Jobs.

Full transcript of the Stanford Commencement 2005
(from: http://news.stanford.edu/news/2005/june15/jobs-061505.html

I am honored to be with you today at your commencement from one of the finest universities in the world. I never graduated from college. Truth be told, this is the closest I've ever gotten to a college graduation. Today I want to tell you three stories from my life. That's it. No big deal. Just three stories.

The first story is about connecting the dots.

I dropped out of Reed College after the first 6 months, but then stayed around as a drop-in for another 18 months or so before I really quit. So why did I drop out?

It started before I was born. My biological mother was a young, unwed college graduate student, and she decided to put me up for adoption. She felt very strongly that I should be adopted by college graduates, so everything was all set for me to be adopted at birth by a lawyer and his wife. Except that when I popped out they decided at the last minute that they really wanted a girl. So my parents, who were on a waiting list, got a call in the middle of the night asking: "We have an unexpected baby boy; do you want him?" They said: "Of course." My biological mother later found out that my mother had never graduated from college and that my father had never graduated from high school. She refused to sign the final adoption papers. She only relented a few months later when my parents promised that I would someday go to college.

And 17 years later I did go to college. But I naively chose a college that was almost as expensive as Stanford, and all of my working-class parents' savings were being spent on my college tuition. After six months, I couldn't see the value in it. I had no idea what I wanted to do with my life and no idea how college was going to help me figure it out. And here I was spending all of the money my parents had saved their entire life. So I decided to drop out and trust that it would all work out OK. It was pretty scary at the time, but looking back it was one of the best decisions I ever made. The minute I dropped out I could stop taking the required classes that didn't interest me, and begin dropping in on the ones that looked interesting.

It wasn't all romantic. I didn't have a dorm room, so I slept on the floor in friends' rooms, I returned coke bottles for the 5¢ deposits to buy food with, and I would walk the 7 miles across town every Sunday night to get one good meal a week at the Hare Krishna temple. I loved it. And much of what I stumbled into by following my curiosity and intuition turned out to be priceless later on. Let me give you one example:

Reed College at that time offered perhaps the best calligraphy instruction in the country. Throughout the campus every poster, every label on every drawer, was beautifully hand calligraphed. Because I had dropped out and didn't have to take the normal classes, I decided to take a calligraphy class to learn how to do this. I learned about serif and san serif typefaces, about varying the amount of space between different letter combinations, about what makes great typography great. It was beautiful, historical, artistically subtle in a way that science can't capture, and I found it fascinating.

None of this had even a hope of any practical application in my life. But ten years later, when we were designing the first Macintosh computer, it all came back to me. And we designed it all into the Mac. It was the first computer with beautiful typography. If I had never dropped in on that single course in college, the Mac would have never had multiple typefaces or proportionally spaced fonts. And since Windows just copied the Mac, it's likely that no personal computer would have them. If I had never dropped out, I would have never dropped in on this calligraphy class, and personal computers might not have the wonderful typography that they do. Of course it was impossible to connect the dots looking forward when I was in college. But it was very, very clear looking backwards ten years later.

Again, you can't connect the dots looking forward; you can only connect them looking backwards. So you have to trust that the dots will somehow connect in your future. You have to trust in something — your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all the difference in my life.

My second story is about love and loss.

I was lucky — I found what I loved to do early in life. Woz and I started Apple in my parents garage when I was 20. We worked hard, and in 10 years Apple had grown from just the two of us in a garage into a $2 billion company with over 4000 employees. We had just released our finest creation — the Macintosh — a year earlier, and I had just turned 30. And then I got fired. How can you get fired from a company you started? Well, as Apple grew we hired someone who I thought was very talented to run the company with me, and for the first year or so things went well. But then our visions of the future began to diverge and eventually we had a falling out. When we did, our Board of Directors sided with him. So at 30 I was out. And very publicly out. What had been the focus of my entire adult life was gone, and it was devastating.

I really didn't know what to do for a few months. I felt that I had let the previous generation of entrepreneurs down - that I had dropped the baton as it was being passed to me. I met with David Packard and Bob Noyce and tried to apologize for screwing up so badly. I was a very public failure, and I even thought about running away from the valley. But something slowly began to dawn on me — I still loved what I did. The turn of events at Apple had not changed that one bit. I had been rejected, but I was still in love. And so I decided to start over.

I didn't see it then, but it turned out that getting fired from Apple was the best thing that could have ever happened to me. The heaviness of being successful was replaced by the lightness of being a beginner again, less sure about everything. It freed me to enter one of the most creative periods of my life.

During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I returned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.

I'm pretty sure none of this would have happened if I hadn't been fired from Apple. It was awful tasting medicine, but I guess the patient needed it. Sometimes life hits you in the head with a brick. Don't lose faith. I'm convinced that the only thing that kept me going was that I loved what I did. You've got to find what you love. And that is as true for your work as it is for your lovers. Your work is going to fill a large part of your life, and the only way to be truly satisfied is to do what you believe is great work. And the only way to do great work is to love what you do. If you haven't found it yet, keep looking. Don't settle. As with all matters of the heart, you'll know when you find it. And, like any great relationship, it just gets better and better as the years roll on. So keep looking until you find it. Don't settle.

My third story is about death.

When I was 17, I read a quote that went something like: "If you live each day as if it was your last, someday you'll most certainly be right." It made an impression on me, and since then, for the past 33 years, I have looked in the mirror every morning and asked myself: "If today were the last day of my life, would I want to do what I am about to do today?" And whenever the answer has been "No" for too many days in a row, I know I need to change something.

Remembering that I'll be dead soon is the most important tool I've ever encountered to help me make the big choices in life. Because almost everything — all external expectations, all pride, all fear of embarrassment or failure - these things just fall away in the face of death, leaving only what is truly important. Remembering that you are going to die is the best way I know to avoid the trap of thinking you have something to lose. You are already naked. There is no reason not to follow your heart.

About a year ago I was diagnosed with cancer. I had a scan at 7:30 in the morning, and it clearly showed a tumor on my pancreas. I didn't even know what a pancreas was. The doctors told me this was almost certainly a type of cancer that is incurable, and that I should expect to live no longer than three to six months. My doctor advised me to go home and get my affairs in order, which is doctor's code for prepare to die. It means to try to tell your kids everything you thought you'd have the next 10 years to tell them in just a few months. It means to make sure everything is buttoned up so that it will be as easy as possible for your family. It means to say your goodbyes.

I lived with that diagnosis all day. Later that evening I had a biopsy, where they stuck an endoscope down my throat, through my stomach and into my intestines, put a needle into my pancreas and got a few cells from the tumor. I was sedated, but my wife, who was there, told me that when they viewed the cells under a microscope the doctors started crying because it turned out to be a very rare form of pancreatic cancer that is curable with surgery. I had the surgery and I'm fine now.

This was the closest I've been to facing death, and I hope it's the closest I get for a few more decades. Having lived through it, I can now say this to you with a bit more certainty than when death was a useful but purely intellectual concept:

No one wants to die. Even people who want to go to heaven don't want to die to get there. And yet death is the destination we all share. No one has ever escaped it. And that is as it should be, because Death is very likely the single best invention of Life. It is Life's change agent. It clears out the old to make way for the new. Right now the new is you, but someday not too long from now, you will gradually become the old and be cleared away. Sorry to be so dramatic, but it is quite true.

Your time is limited, so don't waste it living someone else's life. Don't be trapped by dogma — which is living with the results of other people's thinking. Don't let the noise of others' opinions drown out your own inner voice. And most important, have the courage to follow your heart and intuition. They somehow already know what you truly want to become. Everything else is secondary.

When I was young, there was an amazing publication called The Whole Earth Catalog, which was one of the bibles of my generation. It was created by a fellow named Stewart Brand not far from here in Menlo Park, and he brought it to life with his poetic touch. This was in the late 1960's, before personal computers and desktop publishing, so it was all made with typewriters, scissors, and polaroid cameras. It was sort of like Google in paperback form, 35 years before Google came along: it was idealistic, and overflowing with neat tools and great notions.

Stewart and his team put out several issues of The Whole Earth Catalog, and then when it had run its course, they put out a final issue. It was the mid-1970s, and I was your age. On the back cover of their final issue was a photograph of an early morning country road, the kind you might find yourself hitchhiking on if you were so adventurous. Beneath it were the words: "Stay Hungry. Stay Foolish." It was their farewell message as they signed off. Stay Hungry. Stay Foolish. And I have always wished that for myself. And now, as you graduate to begin anew, I wish that for you.

Stay Hungry. Stay Foolish.

Thank you all very much.

Tuesday, August 30, 2011

VGPU: GPU, Infiniband, Virtualized



最近在公司做的東西,其實還蠻快就弄完的了。這個影片只是簡單的demo一下,接下來就是要加一些文字還有圖片還有對白,就可以準備丟出去了。這個東西基本上就是rCUDA很相似,只是加上Infiniband RDMA的支援,另外還有API跟比較彈性的使用者管理等等。雖然說前天發現rCUDA好像也做完這段了,只是目前還沒有release code,但是我想commercial跟GPL open source的東西還是各有他們的市場吧~

LLVM-based Programming Language Projects

忙到焦頭爛額,一不小心就四個月過去了,實在太久沒更新了...最近在跟LLVM當朋友,其實他還蠻友善的啦,只要用對方法。除了Clang之外,網路上也有很多programming language/compiler是用LLVM寫的,我覺得參考一下蠻有幫助的。

所以以下是我在Google Code還有Github上找的到的LLVM Language Project...
(很明顯這是一篇騙更新的文章)

http://code.google.com/p/crack-language/
http://code.google.com/p/pure-lang/
http://code.google.com/p/llvm-lua/ // Lua-to-LLVM
http://code.google.com/p/thud-lang/
http://code.google.com/p/modern-c/
http://code.google.com/p/esl/
http://code.google.com/p/lightbasic/
http://code.google.com/p/tart/
http://code.google.com/p/dil/
http://code.google.com/p/dolphin-llvm-jit/
http://code.google.com/p/zeroscript/
http://code.google.com/p/metal-lang/
http://code.google.com/p/bnb-lang/
http://code.google.com/p/dolphin-llvm-jit/
http://code.google.com/p/hell-lang/
http://code.google.com/p/rio-lang/
http://code.google.com/p/silverlanguage/
http://code.google.com/p/acelang/
http://code.google.com/p/llvm-ruby/

https://github.com/kripken/emscripten // LLVM-to-Javascript
https://github.com/bos/llvm // Haskell-to-LLVM
https://github.com/alcides/pascal-in-python // Pascal-to-LLVM
https://github.com/rferraz/spell
https://github.com/ldc-developers/ldc // D-to-LLVM
https://github.com/simonask/simongc // LLVM GC
https://github.com/ashgti/nq-nqp-rx
https://github.com/karottenreibe/loop
https://github.com/resistor/rsl-llvm // RSL-to-LLVM
https://github.com/endSly/LEC-Compiler // LEC-to-LLVM
https://github.com/scientific-coder/Computer-Languages // Spirit + LLVM Tutorial
https://github.com/prophile/bfc // Brainfuck-to-LLVM
https://github.com/jholewinski/llvm-ptx-samples // LLVM PTX Backend Example
https://github.com/FBMachine/eople
https://github.com/adh/ncc
https://github.com/mbdriscoll/l3c // Lisp-to-LLVM
https://github.com/cobbal/pietc
https://github.com/ChuGer/StringPro // ANTLR + LLVM Example
https://github.com/scan/PL0 // PL0-to-LLVM
https://github.com/tmiw/kite-llvm
https://github.com/hircus/espresso // Lisp-dialect

Monday, May 30, 2011

無止境的學習 (二)

其實有時候回頭看大學那一段接案時用Visual Studio開發的日子,再看看現在的寫程式的習慣、用的工具、專案的大小,總有種成長很多的感覺。從以前Linux下只會用vim,到現在都用eclipse搞定較大的project,搭配cgdb還有valgrind,其實我覺得比Windows上開發容易多了(雖然之前剛轉到Linux上時花了一陣子適應)。

而一般人剛接觸Linux開發覺得最痛苦的大概就是Makefile了。雖然GNU出了automake,Qt也有qmake,但是我覺得最容易學的大概是cmake了;cmake的語法真的簡單到一個不行,但相對的,也就沒什麼彈性,要寫一些比較複雜的rule就麻煩了;這一點Google SCons倒是做的非常好,畢竟他有Python為基礎,要寫什麼都簡單,但相對的我覺得速度較慢;另外cmake內建支援一堆package,也就是說他事先先幫你把巨集都定好,像是FindCUDA、FindBoost、FindTBB等等,讓開發人員可以很容易的找到某某函式庫的path,然後完成編譯的設定。但是cmake最大的缺點就是語法很不彈性而且很不嚴謹,macro跟function常常會傻傻分不清楚,我覺得cmake的作者肯定沒認真修過compiler或是programming language...

除了軟體之外,這兩年多也學到了一些比較跟硬體有關的技術,主要像是HPC裡常見的GPU還有Infiniband。GPU我想不用多講,從2006年開始玩到現在已經四年半了,中間GPU也經歷過許多代硬體架構的改進,從G80的架構到今天的Fermi,從CUDA 0.2a到4.0b,我覺得GPU這四年真的進化很多;雖然技術不斷的推陳出新,我覺得更重要的是,我開始習慣從更底層去思考系統的運作,不管今天是什麼處理器、什麼assembly、什麼OS、什麼language、什麼compiler,都可以去更深入的思考甚至是最佳化;我覺得這大概是接觸這麼多東西之後最大的收獲吧!

而至於像是Infiniband這種超高速每秒40Gb的網路技術,傳統是用在超級電腦裡的interconnect,但是也慢慢的因為Ethernet的發展緩慢,走入了一般的data center。我們這兩年從什麼都不懂,到完全了解Infiniband的硬體、還有他底層的API還有RDMA的communication model,其實花了很多功夫。在2008年時,我們還完全不知道Infiniband怎麼寫,就先花了二十萬把DDR的switch還有adapter買進來,沒什麼文件,就一本超厚的bible(根本就是他的hardware spec),再加上一支Google來的hello world的測試程式開始,到debug他的driver不能被當shared library載入這種鬼問題,到最後我們丟掉RDMA send/receive模式改用read/write+atomic operation,真的學到很多,過程也蠻有趣的。當初堅持不用MPI這種鬼東西、不走TCP/IP,全部靠libibverbs這個最底層的interface去build我們自己的network engine...現在回頭看,這兩年多來我們還真累積了不少。

剛順手翻了一下大陸很有名的程序員雜誌。這本雜誌我覺得真的是走在時代的尖端,每一期都會探討許多新的技術還有趨勢。像是今年5月這一期,全部都在講cloud computing的技術,光這一點我就真的覺得大陸的programmer是遠比台灣幸福的。我們活在代工王國的世界裡,這些代工廠或是品牌廠,要的就是Android的人才,而且是非常多Android的人才,所以大家都一股腦的去學Android開發,這也造就台灣又繼NB代工大國之後成為手機代工大國,宏達電股價衝上1500;但是相對的,當我們這些軟體人才都為了生計,最後做的都是這些手機廠所謂的"軟硬體整合"的工作的時候,我們怎麼在雲端運算或是網路服務的這些領域與其它國家相比? 也許最終還是落入一個製造業3%~5%的毛利的競爭,大家都做me too的產品,什麼時候才會有真正的innovation? 什麼時候才會有Internet上或軟體上的競爭力? 對現在的台灣來說,實在太遙遠了...好啦離題了,只是突然有感而發而已。我相信台灣有很多很好的軟體人才,也許再過幾年,會有一些突破性的改變,讓台灣的軟實力能登上國際網台吧! 我期許台灣有一天會變成不只是手機/各式各樣3C產品的製造地,我們也可以很大聲的說,我們也是各種Internet服務的集散地、軟體技術的集散地...(待續)

Sunday, May 15, 2011



One loses for not believing in himself
One loses for dying dreams
One loses for living without an aim
One loses for not knowing his potential
A wellness coach is needed along the way to success
Close your eyes
Open your mind
Never self-limit yourself
Grow to your full potential
You can make it

Friday, April 15, 2011

無止境的學習 (一)

很少寫技術文章,或許是過去這幾年其實碰了太多新東西了,今天突然有種衝動想要紀錄一下,順便回顧一下這段時間的成長。

首先是C/C++。公司絕大部份都是寫C++,其實現在回頭看過去這兩年半,對於這個語言的了解似乎又更進一步了,對於一些新的C++0x的功能也因這兩年C++0x的標準化而認識更深;當然總是有人會覺得這些很沒必要,用最基本的C++也可以把程式寫的很好,我完全同意;但我們還是用了非常多C++0x的功能,只是因為有了這些功能,讓C++更簡潔、效能更好、寫起來更簡單,甚至是讓程式碼的架構變的更有彈性;其實我認為這些不是什麼太強大的新功能,只是把原本C++該做的補完罷了,解決了許多C++當初設計上的漏洞。

舉個例子,像是strong-typed enum就解決了enum這種C++時代遺留下來、大小不明確的型別。auto跟decltype就解決了很多複雜的nested template(如boost tuple)很難寫出正確的type然後宣告一個變數的問題。把threading放進語言當中我覺得也簡化了很多multi-core的程式設計,以後就不用再用一堆有的沒的3rd party threading library了(雖然目前應該沒有compiler完全實作全部的C++0x threading,我是早就先偷買JustThread來嚐鮮了XD)

除了C/C++之外,這兩年許多新的語言如雨後春筍般的冒出來,也愈來愈多人用,像是Google Go,Scala等等。其實看這些新語言的設計,不難發現這幾年動態語言流行的一些新東西,像是closure、signal/slot、map/reduce的概念都直接built-in到語言中。

在這麼多新語言中,我認為其中Google Go的設計是我最喜歡的,但是他的語法就不是人人都能接受就是了。另外,許多語言都開始想要在語言設計上支援many-core computing,像是erlang的agent或是stackless python tasklet;當然我其實沒那麼多時間把這些語言全部玩過一次,但簡單看一下其實就看的出他的一些特色。

而除了語言之外,因應web 2.0或是新的many-core computing的大趨勢,有許多有趣的framework被開發出來;像是基於server-side javascript的node.js,我個人認為這個實在是個非常有趣的東西,雖然效能不可能跟native code來比,但是他運用了javascript語言的特性,讓http/json server開發變的超簡單,真的很有潛力。

至於many-core computing,像是zeromq的架構我覺得也是非常好的,只要你願意花個幾個小時trace一下zeromq的設計,就不難發現他lock-free network of queues的強大之處,我們甚至自己也重新實做了一個類似的,用來提昇多核心的效能。

對於像我們在做high performance computing跟cluster computing的人來說,一些cluster membership或group communication的middleware也是非常必要的;例如今年OSDC分享的zookeeper(作者居然親自來了),例如RedHat支持的OpenAIS/Corosync等等,我覺得去認真的讀完一些consensus的paper,再回頭看這些分散式系統的實作,也會非常有幫助。

除了language與middleware之外,這幾年compiler的技術也是一日千里。從以前我在學compiler都還在用lex/yacc的時候,進步到現在用一套ANTLR搞定所有AST,甚至是有神人直接用metaprogramming做出boost::spirit跟yardparser,再加上一套general-purpose的LLVM做為universal IR,連optimizer都不用自己做了,這些都實在是五年前完全想像不到的啊! 而且搞不好再過幾年,clang就可以把gcc幹掉了也說不定呢~因為有這些compiler的技術,我自認為寫compiler已經不再是什麼深奧的學問、神祕的技術了。所以套句食神的話:只要有心,人人都可以寫compiler...(待續)

Wednesday, March 02, 2011

People and Faith

最近好忙。

跑了一趟上海,跑了一趟北京,本來還想接著去美國DEMO跟矽谷跟VC聊聊天,沒想到北京下了一場雪打亂了整個行程。但是當我走在上海跟北京的街上,我才突然有種「真的已經過了兩年」的感覺。現在回想起兩年前,總覺得很可笑,當初真的什麼都不懂就開始做了,連valuation都還不知道怎麼算,更不用說對公司未來的規畫跟募資的想法。就這樣開始做了。

而這兩年來,真的經歷了大大小小的風風雨雨,跑了很多地方,見了很多人,學到了很多東西。我開始往回檢視以前的一些想法,開始檢視一些錯誤,希望能從中多學到些什麼,希望能避免一些犯過的錯誤。最終我有一個新的體悟。

從四年前,參加YEF的時候,大家都告訴我們創業的「人」很重要,那個時候我就一個毛頭小子,根本不了解「人」到底有多重要。兩年多前公司成立,開始慢慢發現,「好人」是多麼的難尋,一個小公司,沒有兩把刷子真的很難找到對的人;不管是透過YEF,透過104,最後都還是透過朋友、朋友的朋友、同學等等管道,找到了今天的團隊。好的人會帶你上天堂,不好的人真的就害你住套房。「人」真的很重要。

但是兩年後的今天,我開始體悟到,最重要的其實不是「人」,而是「信念」。再強的人,沒有信念,也只能在看似山窮水盡的地方舉旗投降;不強的人,只要有信念,只要方向正確,堅持下去,總是有機會熬出一片天。所以如果你今天問我,最想給想要創業或是剛創業的人的一句話,我會說:「永遠不要失去信念」,相信,就有力量。

...當然「人」還是很重要的啦! 所以我還是回頭講一下我對人的看法。

我認為創業路上最好的人,就是能力又強又有信念的人。能找到這種人當你的伙伴,真的會事倍工半。但是這種人超級難找,可能一百個想創業的人裡不到三個,而且這些人大都想要自己創業,所以除非你有自信心你比這三個人更有能力更有leadership跟passion,否則不要想太多了。

退而求其次,就是能力不強但是願意相信你的人。咦? 為什麼不是能力不強但是有信念的人呢? 很簡單,因為有信念的人大都對自己很有自信,能力不強但又很有自信的人,自然就會做出一些令人傻眼的事情,而且他們不容易受控制,總覺得自己是對的。反之,能力不強但是願意相信你的人,當他認同你的信念的時候,所能產生出來的力量才會是最強大的。

請大家不要單單只看眼前的事情而做出決定,有時候沒有什麼對錯,但是當你「選擇相信」、「選擇不放棄」時,時間會最終幫助你會證明自己。

Tuesday, February 08, 2011

Generalized foreach with C++0x

從別的地方看來的(一時找不太到URL),然後自己加上其它std container的支援以及整數/陣列的支援...個人用了一陣子覺得蠻方便的XD

只能說C++0x的auto跟decltype實在是好物!!





/* foreach support for non-container type, the indexer iterates through 0 ~ (A-1) */
static inline int8_t beginof(int8_t a) { return 0; }
static inline int8_t endof(int8_t a) { return a; }
static inline uint8_t beginof(uint8_t a) { return 0; }
static inline uint8_t endof(uint8_t a) { return a; }

static inline int16_t beginof(int16_t a) { return 0; }
static inline int16_t endof(int16_t a) { return a; }
static inline uint16_t beginof(uint16_t a) { return 0; }
static inline uint16_t endof(uint16_t a) { return a; }

static inline int32_t beginof(int32_t a) { return 0; }
static inline int32_t endof(int32_t a) { return a; }
static inline uint32_t beginof(uint32_t a) { return 0; }
static inline uint32_t endof(uint32_t a) { return a; }

static inline int64_t beginof(int64_t a) { return 0; }
static inline int64_t endof(int64_t a) { return a; }
static inline uint64_t beginof(uint64_t a) { return 0; }
static inline uint64_t endof(uint64_t a) { return a; }

template static inline T* beginof (T (&a)[N]) { return a; }
template static inline T* endof (T (&a)[N]) { return a + N; }

// foreach support for std::vector
#include
template static inline typename std::vector::iterator beginof (std::vector& v) { return v.begin(); }
template static inline typename std::vector::iterator endof (std::vector& v) { return v.end(); }

template static inline typename std::vector::const_iterator beginof (const std::vector& v) { return v.begin(); }
template static inline typename std::vector::const_iterator endof (const std::vector& v) { return v.end(); }

// foreach support for std::list
#include
template static inline typename std::list::iterator beginof (std::list& v) { return v.begin(); }
template static inline typename std::list::iterator endof (std::list& v) { return v.end(); }

template static inline typename std::list::const_iterator beginof (const std::list& v) { return v.begin(); }
template static inline typename std::list::const_iterator endof (const std::list& v) { return v.end(); }

// foreach support for std::map
#include
template static inline typename std::map::iterator beginof (std::map& m) { return m.begin(); }
template static inline typename std::map::iterator endof (std::map& m) { return m.end(); }

template static inline typename std::map::const_iterator beginof (const std::map& m) { return m.begin(); }
template static inline typename std::map::const_iterator endof (const std::map& m) { return m.end(); }

// foreach support for std::tr1::unordered_set
#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include
template static inline typename std::unordered_set::iterator beginof (std::unordered_set& m) { return m.begin(); }
template static inline typename std::unordered_set::iterator endof (std::unordered_set& m) { return m.end(); }

template static inline typename std::unordered_set::const_iterator beginof (const std::unordered_set& m) { return m.begin(); }
template static inline typename std::unordered_set::const_iterator endof (const std::unordered_set& m) { return m.end(); }

#include
template static inline typename std::unordered_map::iterator beginof (std::unordered_map& m) { return m.begin(); }
template static inline typename std::unordered_map::iterator endof (std::unordered_map& m) { return m.end(); }

template static inline typename std::unordered_map::const_iterator beginof (const std::unordered_map& m) { return m.begin(); }
template static inline typename std::unordered_map::const_iterator endof (const std::unordered_map& m) { return m.end(); }
#else
#include
template static inline typename std::tr1::unordered_set::iterator beginof (std::tr1::unordered_set& m) { return m.begin(); }
template static inline typename std::tr1::unordered_set::iterator endof (std::tr1::unordered_set& m) { return m.end(); }

template static inline typename std::tr1::unordered_set::const_iterator beginof (const std::tr1::unordered_set& m) { return m.begin(); }
template static inline typename std::tr1::unordered_set::const_iterator endof (const std::tr1::unordered_set& m) { return m.end(); }

// foreach support for std::tr1::unordered_map
#include
template static inline typename std::tr1::unordered_map::iterator beginof (std::tr1::unordered_map& m) { return m.begin(); }
template static inline typename std::tr1::unordered_map::iterator endof (std::tr1::unordered_map& m) { return m.end(); }

template static inline typename std::tr1::unordered_map::const_iterator beginof (const std::tr1::unordered_map& m) { return m.begin(); }
template static inline typename std::tr1::unordered_map::const_iterator endof (const std::tr1::unordered_map& m) { return m.end(); }
#endif

// foreach support for __gnu_cxx::hash_map
#include
template static inline typename __gnu_cxx::hash_map::iterator beginof (__gnu_cxx::hash_map& m) { return m.begin(); }
template static inline typename __gnu_cxx::hash_map::iterator endof (__gnu_cxx::hash_map& m) { return m.end(); }

template static inline typename __gnu_cxx::hash_map::const_iterator beginof (const __gnu_cxx::hash_map& m) { return m.begin(); }
template static inline typename __gnu_cxx::hash_map::const_iterator endof (const __gnu_cxx::hash_map& m) { return m.end(); }

#define foreach(i, c) \
for(decltype(beginof(c)) i = beginof(c); i != endof(c); ++i)





Thursday, January 27, 2011

Git Remote Branch Tracking

當local產生了一個temporary branch
但是過一會又想要push會remote的時候
(也就是當初在create branch的時候沒有設tracking..)
從git 1.7之後就有個新的指令(感謝小白~)


$ git branch --set-upstream [branch_name] origin/[branch_name]


設定完之後就可以隨便push/pull了啦!!

Autojump with Profile Switch

當autojump用到走火入魔的地步的時候...你就會需要profile switch了!
也就是說我希望在不同的情況下, 某一個keyword會到不同的目錄!!
以下簡單的script請自行服用~~


#!/bin/bash
if [ "$#" -gt "0" ]; then
if [ -d ~/.local/share/autojump_$1 ]; then
rm -fr ~/.local/share/autojump
ln -s ~/.local/share/autojump_$1 ~/.local/share/autojump
echo "changed autojump profile to \"$1\""
else
read -N 1 -p "profile \"$1\" does not exist, create it? (y/n)"
if [ "$REPLY" == "y" ]; then
mkdir ~/.local/share/autojump_$1
rm -fr ~/.local/share/autojump
ln -s ~/.local/share/autojump_$1 ~/.local/share/autojump
echo -e "\nchanged autojump profile to \"$1\""
else
echo -e ""
fi
fi
else
echo "Usage: ajcp [profile_name]"
echo ""
echo "Change to given autojump profile."
fi