Saturday, August 30, 2014

Ubuntu 14.04 and Android MTP

I'm not sure is it just me, or are there some other Ubuntu users who are unable to access the files and directories in their Android smartphone.
Anyway, I found that the below step/package works:

apt-get install jmtpfs

Sunday, June 01, 2014

vim to ubuntu 14.04: youcompleteme :-)

I just found out that "youcompleteme" was added as a package in Ubuntu 14.04 LTS.
Now, vim fans like me can have the amazing IDE-like experience by simply doing the few easy steps below:
apt-get install vim apt-get install vim-youcompleteme apt-get install vim-addon-manager vam install youcompleteme
The screen shots (C++ and Python) below work out of the box!


Enjoy!

Monday, February 24, 2014

Value Semantics, Concepts Based Polymorphism and Composite Pattern

Not long ago, I watched Sean Parent's Value Semantics and Concepts Based Polymorphism.
In the presentation, Sean showed a sample code that manipulates "document type".

Yesterday, while flipping over an old book on my book shelf, Pattern Hatching: Design Patterns Applied, by John Vlissides, I came across his example of using the Composite Pattern to illustrate a simplified file system structure with class Node, class File and class Directory.  There it uses the classical way of inheritance.
I couldn't help but notice the similarity between the simplified file system recursive structure of the Composite Pattern with Sean's example of the document inside document.

So, I just play around with concepts based polymorphism a bit.
Note that the code may not be optimize or anything, as it is a quick copy-and-modify.

Here is node.h:
#ifndef NODE_H #define NODE_H #include #include #include #include class node_t { struct concept_t { virtual ~concept_t() = default; virtual size_t total_size() const = 0; virtual void print(std::ostream& out) = 0; virtual concept_t* copy() = 0; }; struct file_model_t : concept_t { file_model_t(size_t x) : total_size_(x) {} size_t total_size() const { return total_size_; } void print(std::ostream& out) { out << total_size_; } concept_t* copy() { return new file_model_t(*this); } size_t total_size_; }; struct dir_model_t : concept_t { dir_model_t(std::initializer_list l) : children_(l) {} size_t total_size() const { size_t total_size = 0; for (const auto& c : children_) total_size += c.total_size(); return total_size; } virtual void print(std::ostream& out) { out << "("; auto i = children_.begin(); out << *i; ++i; while (i != children_.end()) { out << ","; out << *i; ++i; } out << ")"; } concept_t* copy() { return new dir_model_t(*this); } std::vector children_; }; std::unique_ptr p_; public: node_t(size_t value) : p_(new file_model_t(value)) { /*std::cout << "ctor file" << std::endl;*/ } node_t(std::initializer_list l) : p_(new dir_model_t(l)) { /*std::cout << "ctor dir" << std::endl;*/ } node_t(const node_t& x) : p_(x.p_->copy()) { /*std::cout << "copy" << std::endl;*/ } node_t& operator=(node_t x) { //std::cout << "assign" << std::endl; p_ = std::move(x.p_); return *this; } size_t total_size() const { return p_->total_size(); } friend std::ostream& operator<<(std::ostream& out, const node_t& n) { n.p_->print(out); return out; } }; using file_t = node_t; using directory_t = node_t; #endif //NODE_H
And here is the client code:
#include #include #include "node.h" int main() { file_t f1 ( 10 ); std::cout << "f1: " << f1.total_size() << std::endl; file_t f2 ( 20 ); std::cout << "f2: " << f2.total_size() << std::endl; directory_t d1 { f1, f2 }; std::cout << "d1: " << d1.total_size() << std::endl; file_t f3 ( 30 ); std::cout << "f3: " << f3.total_size() << std::endl; directory_t d2 { f3, d1 }; std::cout << "d2: " << d2.total_size() << std::endl; std::cout << d2 << std::endl; }
And this is the output:
f1: 10 f2: 20 d1: 30 f3: 30 d2: 60 (30,(10,20))

Note how the directory nests the subdirectory.
More importantly, the value semantics of the client code, polymorphism without reference or pointer, cool!

Admittedly, I'm quite new to this concepts-based polymorphism technique, and may also not be paying too much attention to other aspect of the C++ code in general. If you find any mistake, feedback and advice are appreciated.