Monthly Archives: December 2013

Perbedaan SSD dan HDD

oke kali ini akan membahas perbedaan hdd dan ssd, banyak teman-teman saya yang bertanya perbedaan ini, karna kesibukan di dunia kampus yang tidak seperti di film2 FTV akhirnya baru kali ini saya sempat menulis lagi sekian lama tak menulis di blog ini, langgsung saja, Hingga kini, konsumen PC hanya memiliki sedikit pilihan soal media penyimpanan data utama untuk laptop, netbook, nettop, ataupun desktop yang mereka miliki. Ketika Anda membeli netbook atau ultraportable lainnya, Anda mungkin lebih memilih solid-state drive (SSD) sebagai drive utama (C: pada OS Windows). Sedangkan desktop atau laptop memiliki hard disk drive (HDD). Kini, Anda dapat mengkonfigurasi sistem Anda dengan HDD, SSD, atau keduanya. Tapi, bagaimana memilihnya? Di sini akan dibahas mengenai perbedaan antara keduanya, serta kelebihan dan kekuranganApa itu HDD? Apa pula itu SSD? Harddisk drive (HDD) piringan tradisional merupakan media penyimpanan non-volatile (data tidak akan hilang ketika komputer dalam keadaan off) dasar pada komputer. Pada dasarnya, HDD adalah piringan metal yang memiliki lapisan magnet. Lapisan tersebut lah yang menjadi tempat penyimpanan data. Sebuah head read/write mengakses data yang tersimpan ketika piringan berputar.

 

SSD juga memiliki fungsi yang sama seperti HDD. Namun, data tidak disimpan pada lapisan magnetik. Melainkan pada chip-chip memori flash yang saling terhubung. Chip-chip itu bisa saja tertanam secara permanen pada motherboard, kartu PCI/PCIe, atau pada kotak yang bentuknya seperti HDD. Chip flash memori ini berbeda dengan chip yang ada pada USB thumb drive (UFD) dalam hal tipe dan kecepatan. Chip flash memori pada SSD memiliki kecepatan dan reliabilitas yang lebih tinggi daripada UFD. Dengan kapasitas yang sama, harga SSD jauh lebih mahal daripada UFD.

 

Kelebihan dan Kekurangan

HDD dan SSD memiliki fungsi yang sama, yaitu untuk boot sistem, menyimpan aplikasi, dan menyimpan data-data pribadi. Namun, keduanya memiliki fitur unik masing-masing. Pertanyaannya, Apa bedanya? dan Kenapa memilih yang satu daripada yang lainnya?

 

Harga : SSD dijual dengan harga yang sangat mahal per GB-nya. Untuk membeli HDD 2,5 inci dengan kapasitas 1 TB Anda akan mengeluarkan biaya sekitar US$100. Untuk membeli SSD dengan kapasitas yang sama, Anda membutuhkan biaya sekitar US$900. Yang artinya 10 sen per GB untuk HDD, dan 90 sen per GB untuk SSD.

 

Kapasitas : Seperti yang sudah disebutkan di atas, kapasitas maksimal SSD sekarang ini mencapai 1 TB, dimana produknya cukup langka dan harganya yang sangat mahal. Anda mungkin lebih memilih SSD dengan kapasitas 128 GB hingga 500 GB sebagai drive utama. Untuk HDD, orang-orang biasanya memakai HDD dengan kapasitas 250 GB atau 500GB. Bagi pengguna multimedia, biasanya membutuh kapasitas yang lebih besar. HDD dengan kapasitas 1 TB sampai 4 TB biasa digunakan untuk PC kelas high-end.

 

Kecepatan : Di sinilah SSD menunjukkan taringnya. PC yang terpasang SSD dapat booting dalam hitungan detik, yang pasti di bawah semenit. HDD membutuhkan waktu yang lebih lama bergantung spesifikasi PC, dan tetap lebih lama daripada SSD ketika melakukan pekerjaan normal. PC atau Mac yang terpasang SSD mendapatkan skor PCMark lebih tinggi, ditambah lagi dengan skor kecepatan transfer data HDD vs SSD dimana SSD jauh lebih tinggi daripada HDD.

 

Fragmentasi : Dikarenakan oleh bentuk permukaan perekaman yang seperti spiral, permukaan HDD sangat baik untuk file-file berukuran besar yang terletak pada blok yang berdekatan. Dengan begitu, head dapat memulai dan mengakhiri pembacaan data dengan satu arah yang berkelanjutan. Ketika HDD mulai penuh, file-file yang berukuran besar dapat terpencar di sekitar piringan disk, yang biasa dikenal dengan fragmentasi. Walaupun algoritma baca/tulis mangalami peningkatan, yang dapat meminimalisir efek fragmentasi, fakta bahwa HDD dapat mengalami fragmentasi tak dapat dipungkiri. Sedangkan dengan SSD, Anda tak perlu dipusingkan dengan fragmentasi. Karena data disimpan pada chip dan tidak memiliki head pembacaan fisik.

 

Daya tahan : SSD tidak memiliki perangkat yang bergerak, jadi lebih aman dalam menyimpan dan memelihara data bahkan ketika Anda menjatuhkan laptop atau terjadi gempa ketika bekerja dengan laptop. Kebanyakan HDD memarkirkan head baca/tulis ketika sistem dalam keadaan mati, namun head tersebut selalu bergerak terus-menerus di sekitar piringan disk hingga mencapai ratusan mil/jam ketika bekerja. Selain itu, rem parkir head HDD tetap memiliki batasan. Jika Anda termasuk orang yang cukup teledor ataupun kasar terhadap perangkat Anda, maka Anda dianjurkan untuk menggunakan SSD.

 

Ketersediaan : Walaupun di akhir 2011 telah terjadi bencana di Thailand yang menjadi tempat pusat pabrikan HDD, namun HDD masih tetap mudah didapatkan di pasaran. Coba Anda lihat produk Western Digital, Samsung, Seagate, Toshiba, dan Hitachi, Anda dapat melihat banyaknya model HDD daripada SSD. Untuk PC dan Mac, HDD tetap akan terus dipakai, setidaknya untuk beberapa tahun ke depan.

 

Form factor (bentuk/ukuran) : Karena HDD bergantung pada putaran piringan, membuat terdapatnya batasan seberapa kecil ukuran sebuah HDD dapat diproduksi. Ada inisiatif untuk membuat HDD dengan ukuran 1,8 inci, namun terbentur dengan kapasitas maksimal 320 GB, sementara MP3 player dan pabrikan ponsel pintar (smartphone) telah menetapkan flash memori sebagai media penyimpanan datanya. SSD terbebas dari batasan tersebut, sehingga ukuran SSD dapat disusutkan seiring dengan waktu dan perkembangan teknologi. SSD tersedia dengan ukuran 2,5 inci dimana ukuran tersebut hanya untuk kenyamanan pengguna laptop. Seiring dengan semakin kecilnya ukuran laptop dan semakin banyaknya pengguna PC tablet untuk menjelajahi web, Anda akan melihat kemampuan SSD yang dapat beradaptasi dengan mudah dengan ukuran laptop/tablet.

 

Noise (Tingkat Kebisingan) : Bahkan HDD tersenyap akan menghasil sedikit kebisingan ketika piringan berputar atau ketika head baca/tulis yang terus bergerak maju-mundur. Semakin cepat sebuah HDD, maka semakin tinggi kebisingan yang dihasilkan. Sedangkan SSD tidak menghasilkan kebisingan sama sekali, hal ini dikarenakan bentuknya yang bukan mekanik.

 

Overall : Secara keseluruhan, HDD menang dari sisi harga, kapasitas, dan ketersediaan barang. Sedangkan SSD unggul dalam hal kecepatan, daya tahan, bentuk/ukuran, tingkat kebisingan, dan fragmentasi.Perlu diketahui, setiap sel chip flash memori yang ada pada SSD memiliki batasan berapa kali data dapat ditulis dan dihapus. Walau begitu, dengan adanya teknologi TRIM pada SSD yang secara dinamis meningkatkan siklus baca/tulis-nya, besar kemungkinan Anda akan membuang perangkat (SSD) yang usang sebelum mengalami kesalahan baca/tulis (read/write error). Kecuali bagi pengguna multimedia high-end seperti editor video yang secara konstan membaca dan menulis data.

 

Media Penyimpanan Yang Cocok Untuk Anda

Media penyimpanan manakah yang cocok untuk kebutuhan Anda? SSD atau HDD? Atau keduanya?

  • HDD
  1. Pekerja Multimedia dan Pengunduh (Downloader) Kelas Berat : Pekerja multimedia dan kolektor video membutuhkan kapasitas yang besar. Anda dapat menggunakan HDD dengan ukuran terbesar yaitu 4 TB.Pengguna dengan Dana Terbatas : Anda dapat mendapatkan HDD yang berukuran besar dengan harga yang murah.
  2. Seniman Grafis : Editor video dan grafis biasanya lebih cocok menggunakan HDD karena keharusannya membaca dan menulis data secara terus-menerus yang dapat memperpendek umur media penyimpanan data. Mengganti HDD jauh lebih murah daripada mengganti SSD.
  3. Pengguna Umum : Jika Anda tidak mempersoalkan masalah kecepatan dan daya tahan akan getaran, sebaiknya menggunakan HDD daripada SSD.

 

  • SSD
  1. Road Warriors : Pengguna yang lebih sering menghabiskan waktunya bekerja di jalanan dan sering berpindah-pindah, lebih membutuhkan keamanan extra untuk media penyimpanan datanya.
  2. Speed Demons : Jika Anda termasuk orang yang membutuhkan kecepatan tinggi, SSD lebih cocok buat Anda daripada HDD.
  3. Seniman Grafis dan Teknisi : Walau di atas telah disebutkan kalau seniman grafis lebih cocok menggunakan HDD, namun ada, kalanya dibutuhkan kecepatan untuk menyelesaikan pekerjaannya. Pengguna ini merupakan kandidat pengguna dual drive (menggunakan SSD dan HDD).
  4. Editor Audio : Ketika Anda merekam musik, Anda pasti tak ingin mendengar suara bising yang dihasilkan oleh HDD.

Semoga bermanfaat :)

[Solved] Error displaying the error page: Application Instantiation Error

ApplicationInstantiation
Problem:
The following issues caused this error message to appear:

  • The database username in our configuration.php file does not match that of what is configured on our hosting account
  • The database password in our configuration.php file does not match what of what is configured on our hosting account
  • The database hostname in our configuration.php file could not be connected to
  • Your MySQL server is down


Solution:
In your Joomla configuration.php file, ensure that your database username, password, and hostname match what is set / provided by your host.

// your database username goes here
public $user = 'database-username';
// your database password goes here
public $password = 'database-password';
// your database server name
public $host = 'localhost';

but some issue on cPanel. if you have MySQL server is down
you can follow this command:

ps aux | grep -i mysql

kill your MySQL PID

kill -9 PID-MySQL

and restart your MySQL service

/etc/init.d/mysql restart

Disable Automatic Address Configuration – Automatic Private IP Addressing (APIPA)

In every Windows Operating System enabled computer, there is a feature Microsoft offers which is APIPA. APIPA is a DHCP failover mechanism for local networks. With APIPA, DHCP clients can obtain IP addresses when DHCP servers are non-functional or the client couldn’t get the IP from server. APIPA exists in all modern versions of Windows except Windows NT.

When DHCP server fails, APIPA allocates IP addresses in the private range 169.254.0.1 to 169.254.255.254. This range is one of Private Network address (hence the name is Automatic Private IP Address).

The method is tested on Windows 8.1 64 bit. The method is generic one, using configuration of Registry entry.

To do, open registry edition. Before we proceed, please remember that incorrectly editing the registry may severely damage system. You can backup any valued data on your machine before making changes to the registry. You can also use the Last Know Good Configuration startup option if problems are encountered after done this guide.

On Windows Vista onward, you will face User Access Control which ask you whether you grant permission for Registry Editor. Choose yes to proceed.

In Registry Editor, navigate to the following registry key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

Now create a DWORD value (32 bit if there is both 32 and 64 bit DWORD value) with following name:

IPAutoconfigurationEnabled

Set the value to 0.

Close the Registry Editor. To make a change, restart the machine.

Data Structure Alignment in C++ on x86 and x64 Machine

Data structure alignment is the way data is arranged and accessed in memory. It consists of two separate but related issues: data alignment and data structure padding.

In this article we will discuss about memory alignment for simple struct.

All of the codes are tested on Windows 8 64-bit using GCC compiler suite. OK, I said I use 64-bit Windows 8, but the title suggest we discuss both 32 and 64 bit, therefore I will also give both code.

Before we start, guess what the output of this program is? Write down your answer, don’t compile it yet.

#include <iostream>
using namespace std;

// Alignment requirements

// char         1 byte
// short int    2 bytes
// int          4 bytes
// double       8 bytes

struct A
{
	char c;
	short s;
};

struct B
{
	short s;
	char c;
	int i;
};

struct C
{
	char c;
	double d;
	int i;
};

struct D
{
	double d;
	int i;
	char c;
};

int main()
{
	cout << "The sizeof A is: " << sizeof(A) << endl;
	cout << "The sizeof B is: " << sizeof(B) << endl;
	cout << "The sizeof C is: " << sizeof(C) << endl;
	cout << "The sizeof D is: " << sizeof(D) << endl;
	return 0;
}

Now read this article.

Definition of Data Alignment

Every data type in C/C++ will have data alignment requirement (in fact, it is mandated by processor architecture, not by language).

MemoryAlignment1

Memory is byte addressable and arranged sequentially. If the memory is arranged as single bank of one byte width, the processor needs to issue 4 memory read cycles to fetch an integer. We can save lot of work when we read all 4 bytes of integer in one memory cycle only. To take such advantage, the memory will be arranged as group of 4 banks.

The memory addressing still be sequential. If bank 0 occupies an address X, bank 1, bank 2 and bank 3 will be at (X + 1), (X + 2) and (X + 3) addresses. If an integer of 4 bytes is allocated on X address (X is multiple of 4), the processor needs only one memory cycle to read entire integer.

Where as, if the integer is allocated at an address other than multiple of 4, it spans across two rows of the banks. Such an integer requires two memory read cycle to fetch the data.

MemoryAlignment2

A variable’s data alignment deals with the way the data stored in these banks. It is expressed as the numeric address module of power of 2. For example, the address 0x0001103F modulo 4 is 3; that address is said to be aligned to 4n+3, where 4 indicates the chosen power of 2. The alignment of an address depends on the chosen power of two. The same address modulo 8 is 7.

The natural alignment of int on 32-bit machine is 4 bytes. When a data type is naturally aligned, the CPU fetches it in minimum read cycles.

Similarly, the natural alignment of several data type are listed here:

For 32-bit x86:

  • A “char” (one byte) will be 1-byte aligned
  • A “short int” (two bytes) will be 2-byte aligned
  • An “int” (four bytes) will be 4-byte aligned
  • A “long” (four bytes) will be 4-byte aligned
  • A “double (eight bytes) will be 8-byte aligned on Windows and 4-byte aligned on Linux (8-byte with -malign-double compile time option).
  • A “long long” (eight bytes) will be 8-byte aligned.
  • A “long double (ten bytes with C++Builder and DMC, eight bytes with Visual C++, twelve bytes with GCC) will be 8-byte aligned with C++Builder, 2-byte aligned with DMC, 8-byte aligned with Visual C++ and 4-byte aligned with GCC.
  • Any “pointer” (four bytes) will be 4-byte aligned. (e.g.: char*, int*)

A notable difference in alignment for 64-bit system when compared to 32-bit system:

  • A “long” (eight bytes) will be 8-byte aligned.
  • A “double“ (eight bytes) will be 8-byte aligned.
  • A “long double“ (eight bytes with Visual C++, sixteen bytes with GCC) will be 8-byte aligned with Visual C++ and 16-byte aligned with GCC.
  • Any “pointer” (eight bytes) will be 8-byte aligned.

So it means, a short int can be stored in bank 0 – bank 1 pair or bank 2 – bank 3 pair. A double requires 8 bytes, and occupies two rows in the memory banks. Any misalignment of double will force more than two read cycles to fetch double data.

As seen before, double variable will be allocated on 8 byte boundary on 32 bit machine and requires two memory read cycles. On a 64 bit machine, based on number of banks, double variable will be allocated on 8 byte boundary and requires only one memory read cycle.

So, we can formulate that a memory address A, is said to be N-byte aligned when A is a multiple of N bytes (where N is power of 2). A memory access is said to be aligned when the datum being accessed is N bytes long and the datum address is N-byte aligned. When a memory access is not aligned, it is said to be misaligned. Note that by definition byte memory accesses are always aligned.

Structure and Padding to Align the Data

In C/C++, structures are used as a data pack (composite data). It doesn’t provide any data encapsulation or data hiding features (except when we define it with the way we define a class).

As stated before, a good aligned data in memory can ease the fetch process. Because of the alignment requirements of various data types, every member of structure should be naturally aligned. The members of structures allocated sequentially increasing order.

Now, alignment should be used to balance the structure. The term balance here refer to make every member naturally aligned (remember, short int use 2 bytes and can be put on a pair of byte 0-byte 1 or byte 2-byte 3 but not byte 1-byte 2). Therefore we need to do something to make them in correct position (align).

The method we use is padding. Padding is only inserted when a structure member is followed by a member with a larger alignment requirement or at the end of the structure.

There is an alternative way, reordering the members, however C/C++ do not allow the compiler to reorder structure members to save space. This job should be done manually.

So how this stuff works?

Remember, we cannot say that the aggregate size of a struct is only sum of all the components. There exists a padding. The padding boundary also depend on the 32-bit or 64-bit architecture of the CPU and the OS. The alignment is done on the basis of the highest size of the variable in the structure.

Let’s view this little structure. When we count it, we should get 8 bytes as total size:

struct Mix
{
	char Data1;
	short Data2;
	int Data3;
	char Data4;
};

After compilation, appropriate paddings will be inserted to ensure a proper alignment for each of its member:

struct Mix
{
	char Data1;          // 1 byte
	char Padding1[1];
	short Data2;         // 2 bytes
	int Data3;           // 4 bytes
	char Data4;          // 1 byte
	char Padding2[3];
};

We see two padding there, Padding1 and Padding2. Remember that short require 2-bytes alignment. Hence, it cannot be placed right after Data1, because it would be put on Bank 1-Bank 2 pair. We add padding between them so when we fetch the Data2 we will have minimum fetch.

After the Data4, there is also a padding with 3 bytes at the end.

Now the compiled size of the structure is 12 bytes. It is important to note that the last member is padded with the number of bytes required so that the total size of the structure should be a multiple of the largest alignment of any structure member (alignment(int) in this case, which = 4

Let’s review the output for previous snippet. If you are confused, first refer to the previous section (Data Alignment)

For 64-bit OS user:

  1. The sizeof A is: 4
  2. The sizeof B is: 8
  3. The sizeof C is: 24
  4. The sizeof D is: 16

For 32-bit Windows user:

  1. The sizeof A is: 4
  2. The sizeof B is: 8
  3. The sizeof C is: 24
  4. The sizeof D is: 16

For 32-bit Linux user:

  1. The sizeof A is: 4
  2. The sizeof B is: 8
  3. The sizeof C is: 16
  4. The sizeof D is: 16

You can also prove it by yourself.

How do we get that?

Structure A

struct A
{
	char c;
	short s;
};

We have two members here, c as character, and s as short integer. Char is 1 byte and Short is 2 bytes. The total should be 3, but it’s 4.

If the short int element is immediately allocated after the char element, it will start at an odd address boundary. Therefore a padding is inserted there so now the structure will be:

struct A
{
	char c;
	char Padding;
	short s;
};

And the total sizeof(A) = sizeof(char) + 1 (padding) + sizeof(short) = 1 + 1 + 2 = 4 bytes.

Structure B

struct B
{
	short s;
	char c;
	int i;
};

We have three members here, s as short integer, c as character, and i as integer. Char is 1 byte, Short is 2 bytes, and Integer is 4 bytes. The total should be 7, but it’s 8.

It has the same reason as first example. As i is immediately after c, it will start at an odd address boundary. Therefore a padding is inserted. Now the structure will be:

struct B
{
	short s;
	char c;
	char Padding;
	int i;
};

And the total sizeof(B) = sizeof(short) + sizeof(char) +  1 (padding) + sizeof(int) = 2 + 1 + 1  + 4 = 8 bytes.

Structure C

struct C
{
	char c;
	double d;
	int i;
};

Now this is the trickiest part.

We have three members here, c as character, d as double float, and i as integer. If your architecture is 64-bit, you get Double as 8 bytes while 32 you get 4 bytes. Other than those, all other value is remain same. Char is 1 byte, and Integer is 4 bytes. The total should be 7, but it’s 8.

Now, the after compilation for x64 we got:

struct C
{
	char c;             // 1 byte
	char Padding1[7];
	double d;           // 8 bytes
	int i;              // 4 bytes
	char Padding2[4];
};

So you would wonder, why the padding Padding1 is 7 bytes instead of 3 bytes? Remember that the boundary is determined by the largest element’s boundary. We have double which is 8 bytes.

So the total size would be: sizeof(C) = sizeof(char) + 7 (padding) + sizeof(double) + sizeof(int) + 4 (padding) = 1 + 7 + 8 + 4 + 4 = 24

Now we see for the x86 Linux (gcc) case:

struct C
{
	char c;             // 1 byte
	char Padding1[3];
	double d;           // 4 bytes
	int i;              // 4 bytes
	char Padding2[4];
};

Here we have double as 4 bytes. As very same argument, we insert padding between c and d. There is padding at the end to meet natural alignment so it fit power of 2 size.

So the total size would be: sizeof(C) = sizeof(char) + 3 (padding) + sizeof(double) + sizeof(int) + 4 (padding)  = 1 + 3 + 4 + 4 + 4 = 16

Structure D

struct D
{
	double d;
	int i;
	char c;
};

We still have three members here, d as double, i as integer, and c as character. Char is 1 byte, double is 8 bytes or 4 bytes depend on which system you are (see previous explanation), and Integer is 4 bytes.

Both 64 and 32 bit will have following alignment after compilation:

struct D
{
	double d;           // 8 bytes
	int i;              // 4 bytes
	char c;		    // 1 byte
	char Padding1[3];
};

So you might expect, the padding is 3 byte at the end of struct so we can’t ensure the size is natural aligned.

So the total size would be: sizeof(D) = sizeof(double) + sizeof(int) + sizeof(char) + 3 (padding) = 8 + 4 + 1 + 3 = 16

How to install ownClound in your Ubuntu

Assalamualaikum all :D

today i will give new stuf about “ownCloud” :D

ownCloud is a free and open-source web application for data synchronization, file sharing, and remote storage of documents (“cloud storage“). /wikipedia said =))

Now here i am use Ubuntu 12.10 and i will install a ownCloud in my computer so this is localhost – sure :D

oke we need to install LAMP-server here :

sudo apt-get install lamp-server^

and you need other library too for ownCloud

sudo apt-get install php5-gd php-xml-parser php5-intl smbclient curl libcurl3 php5-curl

oke lets go to Configure :D

- we need mod_rewrite and mod_headers enable

a2enmod rewrite &amp;&amp; a2enmod headers

- Now is Configure our vhost

nano /etc/apache2/sites-available/default

change this

AllowOverride None

to

AllowOverride All

- Next restart apache

service apache2 restart

- Now Download and extract ownCloud package

cd /var/www/
wget http://download.owncloud.org/community/owncloud-latest.tar.bz2
tar -xjf owncloud-latest.tar.bz2

- Change Owner for owncloud extracted :D

chown -R www-data:www-data owncloud/

- Now Create new Database for ownCloud

mysql -u root -p #enter your mysql password
CREATE DATABASE owncloud;
GRANT ALL ON owncloud.* TO 'owncloud'@'localhost' IDENTIFIED BY 'yourmysqlpassword';

the last is try to restart your apache

service apache2 restart

and open in your browser :

http://localhost/owncloud/

this is my ownCloud in my localhost :D

wassalam :D owncloud ubuntu

The post How to install ownClound in your Ubuntu appeared first on ndesocode.

TCP/IP (Transmision Control Protocol/Internet Protocol)

Assalamualaikum WR WB

Semalam malam para sahabat blogger semua, 

Tulisan saya malam ini untuk melanjutkan catatan belajar saya kemarin malam tentang OSI Layer. Masih berbicara tentang layer, namun layer ini dijelaskan dalam protocol jaringan yang berbeda yaitu TCP/IP. 


Pengertian TCP/IP

TCP/IP merupakan protocol jaringan komputer yang berguna untuk bisa terjadinya komunikasi data antar 2 atau lebih perangkat jaringan. TCP/IP dibuat oleh Departemen Pertahanan Amerika Serikat (DOD). TCP/IP juga sering disebut DOD model. 

Berbeda dengan OSI layer yang memiliki 7 arsitektur layer, namun di TCP/IP hanya ada 4 arsitekur layer. Walau hanya memiliki 4 Layer saja namun setiap fungsi layer di TCP/IP sama dengan fungsi layer yang berada di OSI model. Berikut keempat layer tersebut :

4. Application Layer
3. Host-to-host Layer
2. Internet layer
1. Network Access Layer 


Pengertian Tiap Layer TCP/IP

4. Application layer

Application layer menjelaskan protokol untuk komunikasi antar aplikasi dan juga sebagai pengatur interfaces yang dibutuhkan oleh user. Application layer juga menyediakan layanan untuk aplikasi yang berjalan di PC/Laptop. Tetapi application layer tidak menjelaskan aplikasi yang dipakai, namun layanan jaringan yang berjalan di aplikasi tersebut. 

Sebegai Contoh, pada application layer terdapat protokol yang bernama http. Http ini berfungsi untuk menjelaskan bagaimana web browser bisa mengambil isi dari konten web yang berasal dari web server. 

Contoh protokol yang berjalan di layer ini adalah HTTP, Telnet, FTP, SMTP, dll.

3. Host-To-Host Layer

Host-to-host layer bertanggung jawab atas transportasi/jalur yang dilakukan data antar aplikasi. Sama halnya dengan transport layer, didalam host-to-host layer terdapat protokol yang bertugas untuk menjaga komunikasi data secara langsung protokol itu adalah TCP dan UDP. 

2. Internet Layer

Merupakan layer yang berfungsi untuk melakukan pemetaan (routing) dan enkapsulasi paket-paket jaringan menjadi paket-paket IP. Protokol yang bekerja pada layer ini adalah IP, ARP, ICMP, IGMP. 

1. Network Access Layer

Merupakan layer yang berfungsi untuk meletakan frame-frame jaringan diatas media jaringan yang digunakan. TCP/IP dapat bekerja di berbagai teknologi mulai dari LAN, MAN, WAN yang berjalan dia atas jaringan PSTN, ISDN, dan ATM.

Demikanlah catatan saya dalam pembelajaran CCNA, mohon maaf apabila ada kekurangan. Atas perhatiannya saya ucapkan terima kasih. 

Wassalamualaikum WR WB

Setting Up Raspberry Pi + Smart Card Reader + PHP

Smart Card is a pocket-sized card with embedded integrated circuits. It provides identification, authentication, data storage and application processing on simple medium. There are two big categories of smart card: contact and contactless. To identify and authenticate a smart card properly we need a smart card reader. There are many smart card reader and the way we operate is depend on what smart card it can detect.

To detect and use smart card, there is a specification for smart card integration into computing environments. It is called PC/SC (Personal Computer / Smart Card). The standard has been implemented to various operating system: Windows (since NT/9x), Linux, Unix.

We can however create a small device which can make use of smart card reader, instead of using our PC. That’s what we will discuss on this article.

As title suggest, after we have smart card connected we will use PHP as a programming environment.

For this article, we use:

  1. Working Raspberry Pi model B (+SD card)
  2. Raspbian Wheezy release date 2013-09-25
  3. Smart Card Reader, ACR122
  4. USB power hub

Grab the Materials

Make sure the Raspberry Pi is working properly with Raspbian Wheezy installed. Also make sure all the hardware are available.

We need USB power hub as the ACR122 Smart Card Reader gives too high load for Raspberry Pi so we will feed electricity from somewhere else.

Installation

Install the drivers and related package

apt-get install build-essential libusb-dev libusb++-dev libpcsclite-dev libccid

  • build-essential is package for building a application
  • libusb-dev and libusb++-dev are package for user-space USB programming
  • libpcsclite-dev is a middleware to access a smart card using PC/SC (development files) using PC\SC-lite definition
  • libccid is a smart card driver

Install PHP and all needed development tool

apt-get install php5-dev php5-cli php-pear

Once PHP installed, we need a PHP extension for smart card:

pecl install pcsc-alpha

You can see the documentation here.

Configuration

On some case, we need to add an entry to php.ini manually for registering pcsc extension. To do this, open up php.ini and add following entry:

extension = pcsc.so

OSI (Open System Interconnection)

Asslamulaikum WR WB

Selamat malam para blogger, 

Saya mencoba menulis artikel yang sesuai dengan judul yaitu OSI. Sebelumnya saya pernah memposting artikel yang sama tentang pengertian OSI layer. Kenapa saya mempostingnya kembali, karena saya sekarang sedang mempelajari tentang materi-materi tentang CCNA. Ternyata OSI layer masuk kedalam materi CCNA tersebut. Itulah alasan saya menulis kembali dan memasukannya kedalam label CCNA...hhe.. :)

Pengertian OSI

OSI atau Open System Interconnection merupakan protokol yang digunakan untuk mendifinisikan dan menjelaskan bagaimana komunikasi bisa terjadi antara 2 atau lebih perangkat jaringan yang berada didalam jaringan atau internet. 

OSI dibuat oleh badan standardisasi internasional yang kita kenal dengan seburan ISO. OSI tersebut diperkenalkan sekitar tahun 1980an. OSI merupakan protokol yang memiliki 7 arsitektur layer yang ditiap masing-masing layer memiliki fungsi berbeda-beda, berikut layer tersebut :


1. Physical Layer
    2. Data Link Layer
      3. Network Layer
        4. Transport Layer
          5. Session Layer
            6. Presentation Layer
              7. Application Layer


                  Pengertian Tiap Layer OSI

                  7. Application Layer

                  Application layer bertanggung jawab untuk memberikan interface kepada user untuk bisa berinteraksi dengan layanan aplikasi atau layanan jaringan, sebagai contoh : Web Browser.

                  Application layer mengidentifikasi layanan yang digunakan menggunakan nomor port. Nomor port merupakan channel logik yang digunakan untuk berkomunikasi. Nomor port berjumlah dari 0 - 65535. Nomor Port yang sudah terpakai dari 1 - 1023, sedangkan yang belum terpakai dari 1024 - 65535. 

                  Contoh :

                  - HTTP - 80
                    - FTP - 21
                      - Telnet - 23
                        - SMTP - 25
                          - TFTP - 63

                          6. Presentation Layer

                          Presentation layer bertanggung jawab untuk mendefinisikan format standart yang akan dipakai untuk komunikasi data. fungsi utama dari presentation layer adalah :

                          - Encoding-Decoding
                            - Encryption-Decryption
                              - Commpresing-Decommpressing

                              5. Session Layer

                              Session layer bertanggung jawab untuk memulai, memelihara, dan mengakhiri sesi atau interaksi yang terjadi antar aplikasi. Session ID digunakan untuk mengidentifikasi sesi atau interaksi yang sedang berlangsung. 

                              4. Transport Layer

                              Transport layer bertanggung jawab untuk transportasi data antar aplikasi. Layer ini memiliki beberapa fungsi utama, yaitu : 

                              - Mengidentifikasi Layanan
                                - Multiplexing - Demultiplexing
                                  - Segmentation
                                    - Sequencing - Reassembling
                                      - Error Corection
                                        - Flow control

                                        Transport layer mengidentifikasi layanannya dengan menggunakan bantuan dari nomor port yang digunakan. Dalam layer ini ada protokol utama yang berfungsi untuk menjaga transportasi data, yaitu TCP dan UDP 

                                        3. Network Layer

                                        Network layer bertanggung jawab untuk komunikasi data yang terjadi di beberapa jaringan yang berbeda. Didalam layer ini dijelaskan juga tentang IP Addressing dan Routing. Terdapat 2 buah protokol yang bekerja didalam layer ini, yaitu :

                                        1. Routed Protocol

                                        Router protocol bertindak sebagai pembawa data dan juga untuk mendefinisikan pengalamatan logis

                                        2. Routing Protocol

                                        Routing Protocol bertindak sebagai penentu rute terbaik yang akan dilewati oleh data tsb. 

                                        Perangkat jaringan yang bekerja dilayer ini adalah Router, dan Switch layer 3.

                                        2. Data Link Layer

                                        Data link layer bertangggung jawab untuk mengirimkan data diantara perangkat jaringan yang terdapat dibeberapa jaringan LAN. Layer ini dibagi menjadi 2 sub layer, yaitu : 

                                        1. MAC (Media Access Control)

                                        MAC berhubungan dengan pengalamatan hardware atau MAC Address. MAC Address adalah 12 digit hexadesimal yang digunakan untuk mengidetifikasikan perangkat yang berada di suatu jaringan yang ada. MAC itu sendiri juga menyediakan Error Detection menggunakan CRC (Cyclic Redundancy Check) dan Fragmentaion (encapsulation). 

                                        2. LLC (Logical Link Control)

                                        Sub layer ini berhubungan dengan layer 3 (Network). 

                                        Perangkat yang digunkan dalam layer ini adalah Switch, HUB, Bridge. dll...

                                        1. Physical Layer

                                        Setelah data dikemas secara utuh data tersebut diubah menjadi beberapa bentuk tergantung dari media  yang digunakan, bisa berupa arus listrik, Serat kaca, maupun gelombang radio. Disinilah Layer fisik ini bekerja, yang bertanggung jawab untuk sebagai perantara antar perangkat jaringan yang berbeda. 

                                        Dalam hal ini ada 3 tipe media perantara, yaitu :

                                        - Tembaga - Coacxial, UTP/STP
                                        - Serat Kaca - Fiber Optic
                                        - Gelombang - Wireless


                                          Demikian lah tulisan saya tentang OSI Layer, walaupun ini hanya berupa ringkasannya saja, saya harap anda bisa mengerti atas apa yang telah saya tulis. Atas perhatiannya saya ucapkan terima kasih.

                                          Wassalamualaikum WR WB

                                          SCP Command

                                          Hello bro :D

                                          i will paste here about SCP / Secure Copy :D

                                          this is usefull for administrator to transfer file into / out to server or localhost :D

                                          Copy the file “foobar.txt” from a remote host to the local host

                                          $ scp your_username@remotehost.edu:foobar.txt /some/local/directory

                                          Copy the file “foobar.txt” from the local host to a remote host

                                          $ scp foobar.txt your_username@remotehost.edu:/some/remote/directory

                                          Copy the directory “foo” from the local host to a remote host’s directory “bar”

                                          $ scp -r foo your_username@remotehost.edu:/some/remote/directory/bar

                                          Copy the file “foobar.txt” from remote host “rh1.edu” to remote host “rh2.edu”

                                          $ scp your_username@rh1.edu:/some/remote/directory/foobar.txt \
                                          your_username@rh2.edu:/some/remote/directory/

                                          Copying the files “foo.txt” and “bar.txt” from the local host to your home directory on the remote host

                                          $ scp foo.txt bar.txt your_username@remotehost.edu:~

                                          Copy the file “foobar.txt” from the local host to a remote host using port 2264

                                          $ scp -P 2264 foobar.txt your_username@remotehost.edu:/some/remote/directory

                                          Copy multiple files from the remote host to your current directory on the local host

                                          $ scp your_username@remotehost.edu:/some/remote/directory/\{a,b,c\} .
                                          $ scp your_username@remotehost.edu:~/\{foo.txt,bar.txt\} .

                                          Full Copas Here

                                          Continue reading

                                          Ten C++11 Features You Should Know and Use

                                          This article will be a resume to several articles discussing individual subject.

                                          There are lots of new additions to the C++ language and standard library after C++11 standard passed. However, I believe some of these new features should become routing for all C++ developers.

                                          Features we are talking about:

                                          1. auto & decltype
                                          2. nullptr
                                          3. Range-based for loops
                                          4. Override and final
                                          5. Strongly-typed enums
                                          6. Smart pointers
                                          7. Lambdas
                                          8. non-member begin() and end()
                                          9. static_assert and type traits
                                          10. Move semantics

                                          auto & decltype

                                          More: Improved Typed Reference in C++11: auto, decltype, and new function declaration syntax

                                          Before C++11 era, keyword auto was used for storage duration specification. In the new standard, C++ define clearly the purpose to be type inference. Keyword auto is a placeholder for a type, telling the compiler it has to deduce the actual type of a variable that is being declared from its initializer.

                                          auto I = 42;        // I is an int
                                          auto J = 42LL;      // J is an long long
                                          auto P = new foo(); // P is a foo* (pointer to foo)

                                          Using auto means less code for writing typename. The very convenience use of auto would be inferring type for iterator:

                                          std::map<std::string, std::vector<int>> myMap;
                                          for (auto it = begin(map); it != end(map); ++it)
                                          {
                                          //...
                                          }

                                          Here we save lot of works by order compiler to deduce the type of it.

                                          decltype in other hand is a handy keyword to get type of an expression. Here we can inspect what’s going on this code:

                                          short a = 10;
                                          long b = 655351334;
                                          decltype(a+b) c = 5;
                                          
                                          std::cout << sizeof(a) << " " << sizeof(b) << " " << sizeof(c) << std::endl;

                                          When we execute this code using proper C++11 compiler, we got variable c as a type used for summation of a and b. We know that when a short is summed with a long, the short variable will be typecasted automatically to type sufficient enough to hold the result code. And the decltype will give us it’s type.

                                          As said before, decltype is used to get type of an expression, therefore it is valid for use to do this:

                                          int function(int a, int b)
                                          {
                                          	return a * b;
                                          }
                                          
                                          int main()
                                          {
                                          	decltype(function(a,b)) c = 10;
                                          
                                          	return 0;
                                          }

                                          As long as the expression involved is valid.

                                          Now, in C++ we have a new function declaration syntax. This syntax leverage the power of both auto and decltype. Note that auto cannot be used as the return type of a function, so we must have a trailing return type. In this case auto does not tell the compiler it has to infer the type, it only instructs it to look for the return type at the end of the function.

                                          template <typename T1, typename T2>
                                          auto compose(T1 t1, T2 t2) -> decltype (t1 + t2)
                                          {
                                          	return t1+t2;
                                          }

                                          In above snippet, we compose the return type of function from the type of operator + that sums the values of types T1 and T2.

                                          nullptr

                                          More: Nullptr, Strongly typed Enumerations, and Cstdint

                                          Since the inception of C++, zero is used as the value of null pointers. This is a direct influence from C language. The system itself has drawbacks due to the implicit conversion to integral types.

                                          void function(int a);
                                          void function(void* a);
                                          
                                          function(NULL);

                                          Now, which one is being called? On smarter compiler, it will gives error saying “the call is ambiguous”.

                                          C++11 library gives solution for this. Keyword nullptr denotes a value of type std::nullptr_t that represents the null pointer literal. Implicit conversions exists from nullptr to null pointer value of any pointer type and any pointer-to-member types, but also to bool (as false). But no implicit conversion to integral types exists.

                                          void foo(int* p) {}
                                          
                                          void bar(std::shared_ptr<int> p) {}
                                          
                                          int* p1 = NULL;
                                          int* p2 = nullptr;   
                                          if(p1 == p2)
                                          {
                                          }
                                          
                                          foo(nullptr);
                                          bar(nullptr);
                                          
                                          bool f = nullptr;
                                          int i = nullptr; // error: A native nullptr can only be converted to bool or, using reinterpret_cast, to an integral type

                                          Using 0 is still valid for backward compatibility.

                                          Range-based for loops

                                          More: C++ Ranged Based Loop

                                          Ever wonder how could we do foreach statement in C++? Joy for us because C++11 now augmented the for statement to support it. Using this foreach paradigm we can iterate over collections. In the new form, it is possible to iterate over C-like arrays, initializer lists, and anything for which the non-member begin() and end() functions are overloaded.

                                          std::map<std::string, std::vector<int>> map;
                                          std::vector<int> v;
                                          v.push_back(1);
                                          v.push_back(2);
                                          v.push_back(3);
                                          map["one"] = v;
                                          
                                          for(const auto& kvp : map) 
                                          {
                                            std::cout << kvp.first << std::endl;
                                          
                                            for(auto v : kvp.second)
                                            {
                                               std::cout << v << std::endl;
                                            }
                                          }
                                          
                                          int arr[] = {1,2,3,4,5};
                                          for(int& e : arr) 
                                          {
                                            e = e*e;
                                          }

                                          The syntax is not different from “normal” for statement, okay it is a little different.

                                          The for syntax in this paradigm is:

                                          for (type iterateVariable : collection)
                                          {
                                          // ...
                                          }

                                          Override and final

                                          In C++, there isn’t a mandatory mechanism to mark virtual methods as overriden in derived class. The virtual keyword is optional and that makes reading code a bit harder, because we may have to look through the top of the hierarchy to check if the method is virtual.

                                          class Base 
                                          {
                                          public:
                                             virtual void f(float);
                                          };
                                          
                                          class Derived : public Base
                                          {
                                          public:
                                             virtual void f(int);
                                          };

                                          Derived::f is supposed to override Base::f. However, the signature differ, one takes a float, one takes an int, therefor Base::f is just another method with the same name (and overload) and not an override. We may call f() through a pointer to B and expect to print D::f, but it’s printing B::f.

                                          C++11 provides syntax to solve this problem.

                                          class Base 
                                          {
                                          public:
                                             virtual void f(float);
                                          };
                                          
                                          class Derived : public Base
                                          {
                                          public:
                                             virtual void f(int) override;
                                          };

                                          Keyword override force the compiler to check the base class(es) to see if there is a virtual function with this exact signature. When we compile this code, it will triggers a compile error because the function supposed to override the base class has different signature.

                                          On the other hand if you want to make a method impossible to override any more (down the hierarchy) mark it as final. That can be in the base class, or any derived class. If it’s in a derived class, we can use both the override and final specifiers.

                                          class Base 
                                          {
                                          public:
                                             virtual void f(float);
                                          };
                                          
                                          class Derived : public Base
                                          {
                                          public:
                                             virtual void f(int) override final;
                                          };
                                          
                                          class F : public Derived
                                          {
                                          public:
                                             virtual void f(int) override;
                                          }

                                          Function declared as ‘final’ cannot be overridden by ‘F::f’.

                                          Strongly-typed enums

                                          More: Nullptr, Strongly typed Enumerations, and Cstdint

                                          Traditional enums in C++ have some drawbacks: they export their enumerators in the surrounding scope (which can lead to name collisions, if two different enums in the same have scope define enumerators with the same name), they are implicitly converted to integral types and cannot have a user-specified underlying type.

                                          C++11 introduces a new category of enums, called strongly-typed enums. They are specified with the “enum class” keyword which won’t export their enumerators in the surrounding scope and no longer implicitly converted to integral types. Thus we can have a user specified underlying type.

                                          enum class Options { None, One, All };
                                          Options o = Options::All;

                                          Smart pointers

                                          All the pointers are declared in header <memory>

                                          In this article we will only mention smart pointers with reference counting and auto releasing of owned memory that are available:

                                          • unique_ptr: should be used when ownership of a memory resource does not have to be shared (it doesn’t have a copy constructor), but it can be transferred to another unique_ptr (move constructor exists).
                                          • shared_ptr: should be used when ownership of a memory resource should be shared (hence the name).
                                          • weak_ptr: holds a reference to an object managed by a shared_ptr, but does not contribute to the reference count; it is used to break dependency cycles (think of a tree where the parent holds an owning reference (shared_ptr) to its children, but the children also must hold a reference to the parent; if this second reference was also an owning one, a cycle would be created and no object would ever be released).

                                          The library type auto_ptr is now obsolete and should no longer be used.

                                          The first example below shows unique_ptr usage. If we want to transfer ownership of an object to another unique_ptr use std::move. After the ownership transfer, the smart pointer that ceded the ownership becomes null and get() returns nullptr.

                                          void foo(int* p)
                                          {
                                             std::cout << *p << std::endl;
                                          }
                                          std::unique_ptr<int> p1(new int(42));
                                          std::unique_ptr<int> p2 = std::move(p1); // transfer ownership
                                          
                                          if(p1)
                                            foo(p1.get());
                                          
                                          (*p2)++;
                                          
                                          if(p2)
                                            foo(p2.get());

                                          The second example shows shared_ptr. Usage is similar, though the semantics are different since ownership is shared.

                                          void foo(int* p)
                                          {
                                             std::cout << *p << std::endl;
                                          }
                                          void bar(std::shared_ptr<int> p)
                                          {
                                             ++(*p);
                                          }
                                          std::shared_ptr<int> p1(new int(42));
                                          std::shared_ptr<int> p2 = p1;
                                          
                                          foo(p2.get());
                                          bar(p1);   
                                          foo(p2.get());

                                          We can also make equivalent expression for first declaration as:

                                          auto p3 = std::make_shared<int>(42);

                                          make_shared<T> is a non-member function and has the advantage of allocating memory for the shared object and the smart pointer with a single allocation, as opposed to the explicit construction of a shared_ptr via the contructor, that requires at least two allocations. In addition to possible overhead, there can be situations where memory leaks can occur because of that. In the next example memory leaks could occur if seed() throws an error.

                                          void foo(std::shared_ptr<int> p, int init)
                                          {
                                             *p = init;
                                          }
                                          foo(std::shared_ptr<int>(new int(42)), seed());

                                          No such problem exists if using make_shared.

                                          The last sample shows usage of weak_ptr. Notice that you always must get a shared_ptr to the referred object by calling lock(), in order to access the object.

                                          auto p = std::make_shared<int>(42);
                                          std::weak_ptr<int> wp = p;
                                          
                                          {
                                            auto sp = wp.lock();
                                            std::cout << *sp << std::endl;
                                          }
                                          
                                          p.reset();
                                          
                                          if(wp.expired())
                                            std::cout << "expired" << std::endl;

                                          Lambdas

                                          More: Guide to Lambda Closure in C++11

                                          Lambda is anonymous function. It is powerful feature borrowed from functional programming that in turned enabled other features or powered library. We can use lambda wherever a function object or a functor or a std::function is expected.

                                          You can read the expression here.

                                          std::vector<int> v;
                                          v.push_back(1);
                                          v.push_back(2);
                                          v.push_back(3);
                                          
                                          std::for_each(std::begin(v), std::end(v), [](int n) {std::cout << n << std::endl;});
                                          
                                          auto is_odd = [](int n) {return n%2==1;};
                                          auto pos = std::find_if(std::begin(v), std::end(v), is_odd);
                                          if(pos != std::end(v))
                                            std::cout << *pos << std::endl;

                                          A bit trickier are recursive lambdas. Imagine a lambda that represents a Fibonacci function. If you attempt to write it using auto you get compilation error:

                                          auto fib = [&fib](int n) {return n < 2 ? 1 : fib(n-1) + fib(n-2);};

                                          The problem is auto means the type of the object is inferred from its initializer, yet the initializer contains a reference to it, therefore needs to know its type. This is a cyclic problem. The key is to break this dependency cycle and explicitly specify the function’s type using std::function.

                                          std::function<int(int)> lfib = [&lfib](int n) {return n < 2 ? 1 : lfib(n-1) + lfib(n-2);};

                                          non-member begin() and end()

                                          Two new addition to standard library, begin() and end(), gives new flexibility. It is promoting uniformity, concistency, and enabling more generic programming which work with all STL containers. These two functions are overloadable, can be extended to work with any type including C-like arrays.

                                          Let’s take an example. We want to print first odd element on a C-like array.

                                          int arr[] = {1,2,3};
                                          std::for_each(&arr[0], &arr[0]+sizeof(arr)/sizeof(arr[0]), [](int n) {std::cout << n << std::endl;});
                                          
                                          auto is_odd = [](int n) {return n%2==1;};
                                          auto begin = &arr[0];
                                          auto end = &arr[0]+sizeof(arr)/sizeof(arr[0]);
                                          auto pos = std::find_if(begin, end, is_odd);
                                          if(pos != end)
                                            std::cout << *pos << std::endl;

                                          With non-member begin() and end() it could be put as this:

                                          int arr[] = {1,2,3};
                                          std::for_each(std::begin(arr), std::end(arr), [](int n) {std::cout << n << std::endl;});
                                          
                                          auto is_odd = [](int n) {return n%2==1;};
                                          auto pos = std::find_if(std::begin(arr), std::end(arr), is_odd);
                                          if(pos != std::end(arr))
                                            std::cout << *pos << std::endl;

                                          This is basically identical code to the std::vector version. That means we can write a single generic method for all types supported by begin() and end().

                                          template <typename Iterator>
                                          void bar(Iterator begin, Iterator end) 
                                          {
                                             std::for_each(begin, end, [](int n) {std::cout << n << std::endl;});
                                          
                                             auto is_odd = [](int n) {return n%2==1;};
                                             auto pos = std::find_if(begin, end, is_odd);
                                             if(pos != end)
                                                std::cout << *pos << std::endl;
                                          }
                                          
                                          template <typename C>
                                          void foo(C c)
                                          {
                                             bar(std::begin(c), std::end(c));
                                          }
                                          
                                          template <typename T, size_t N>
                                          void foo(T(&arr)[N])
                                          {
                                             bar(std::begin(arr), std::end(arr));
                                          }
                                          
                                          int arr[] = {1,2,3};
                                          foo(arr);
                                          
                                          std::vector<int> v;
                                          v.push_back(1);
                                          v.push_back(2);
                                          v.push_back(3);
                                          foo(v);

                                          static_assert and type traits

                                          static_assert performs an assertion check at compile-time. If the assertion is true, nothing happens. If the assertion is false, the compiler displays the specified error message.

                                          template <typename T, size_t Size>
                                          class Vector
                                          {
                                             static_assert(Size < 3, "Size is too small");
                                             T _points[Size];
                                          };
                                          
                                          int main()
                                          {
                                             Vector<int, 16> a1;
                                             Vector<double, 2> a2;
                                             return 0;
                                          }

                                          static_assert becomes more useful when used together with type traits. These are a series of classes that provide information about types at compile time. They are available in the <type_traits> header. There are several categories of classes in this header: helper classes, for creating compile-time constants, type traits classes, to get type information at compile time, and type transformation classes, for getting new types by applying transformation on existing types.

                                          In the following example function add is supposed to work only with integral types.

                                          template <typename T1, typename T2>
                                          auto add(T1 t1, T2 t2) -> decltype(t1 + t2)
                                          {
                                             return t1 + t2;
                                          }

                                          However, there are no compiler errors if one writes

                                          std::cout << add(1, 3.14) << std::endl;
                                          std::cout << add("one", 2) << std::endl;

                                          The program actually prints 4.14 and “e”. But if we add some compile-time asserts, both these lines would generate compiler errors.

                                          template <typename T1, typename T2>
                                          auto add(T1 t1, T2 t2) -> decltype(t1 + t2)
                                          {
                                             static_assert(std::is_integral<T1>::value, "Type T1 must be integral");
                                             static_assert(std::is_integral<T2>::value, "Type T2 must be integral");
                                          
                                             return t1 + t2;
                                          }

                                          Move semantics

                                          More: Move Semantics and rvalue references in C++11

                                          C++11 has introduced the concept of rvalue references (specified with &&) to differentiate a reference to an lvalue or an rvalue. An lvalue is an object that has a name, while an rvalue is an object that does not have a name (temporary object). The move semantics allow modifying rvalues (previously considered immutable and indistinguishable from const& types).

                                          A C++ class/struct used to have some implicit member functions: default constructor (only if another constructor is not explicitly defined) and copy constructor, a destructor and a copy assignment operator. The copy constructor and the copy assignment operator perform a bit-wise (or shallow) copy, i.e. copying the variables bitwise. That means if you have a class that contains pointers to some objects, they just copy the value of the pointers and not the objects they point to. This might be OK in some cases, but for many cases you actually want a deep-copy, meaning that you want to copy the objects pointers refer to, and not the values of the pointers. In this case you have to explicitly write copy constructor and copy assignment operator to perform a deep-copy.

                                          What if the object you initialize or copy from is an rvalue (a temporary). You still have to copy its value, but soon after the rvalue goes away. That means an overhead of operations, including allocations and memory copying that after all, should not be necessary.

                                          Enter the move constructor and move assignment operator. These two special functions take a T&& argument, which is an rvalue. Knowing that fact, they can modify the object, such as “stealing” the objects their pointers refer to. For instance, a container implementation (such as a vector or a queue) may have a pointer to an array of elements. When an object is instantiating from a temporary, instead of allocating another array, copying the values from the temporary, and then deleting the memory from the temporary when that is destroyed, we just copy the value of the pointer that refers to the allocated array, thus saving an allocation, copying a sequence of elements, and a later deallocation.

                                          The following example shows a dummy buffer implementation. The buffer is identified by a name (just for the sake of showing a point revealed below), has a pointer (wrapper in an std::unique_ptr) to an array of elements of type T and variable that tells the size of the array.

                                          template <typename T>
                                          class Buffer 
                                          {
                                             std::string          _name;
                                             size_t               _size;
                                             std::unique_ptr<T[]> _buffer;
                                          
                                          public:
                                             // default constructor
                                             Buffer():
                                                _size(16),
                                                _buffer(new T[16])
                                             {}
                                          
                                             // constructor
                                             Buffer(const std::string& name, size_t size):
                                                _name(name),
                                                _size(size),
                                                _buffer(new T[size])
                                             {}
                                          
                                             // copy constructor
                                             Buffer(const Buffer& copy):
                                                _name(copy._name),
                                                _size(copy._size),
                                                _buffer(new T[copy._size])
                                             {
                                                T* source = copy._buffer.get();
                                                T* dest = _buffer.get();
                                                std::copy(source, source + copy._size, dest);
                                             }
                                          
                                             // copy assignment operator
                                             Buffer& operator=(const Buffer& copy)
                                             {
                                                if(this != &copy)
                                                {
                                                   _name = copy._name;
                                          
                                                   if(_size != copy._size)
                                                   {
                                                      _buffer = nullptr;
                                                      _size = copy._size;
                                                      _buffer = _size > 0 > new T[_size] : nullptr;
                                                   }
                                          
                                                   T* source = copy._buffer.get();
                                                   T* dest = _buffer.get();
                                                   std::copy(source, source + copy._size, dest);
                                                }
                                          
                                                return *this;
                                             }
                                          
                                             // move constructor
                                             Buffer(Buffer&& temp):
                                                _name(std::move(temp._name)),
                                                _size(temp._size),
                                                _buffer(std::move(temp._buffer))
                                             {
                                                temp._buffer = nullptr;
                                                temp._size = 0;
                                             }
                                          
                                             // move assignment operator
                                             Buffer& operator=(Buffer&& temp)
                                             {
                                                assert(this != &temp); // assert if this is not a temporary
                                          
                                                _buffer = nullptr;
                                                _size = temp._size;
                                                _buffer = std::move(temp._buffer);
                                          
                                                _name = std::move(temp._name);
                                          
                                                temp._buffer = nullptr;
                                                temp._size = 0;
                                          
                                                return *this;
                                             }
                                          };
                                          
                                          template <typename T>
                                          Buffer<T> getBuffer(const std::string& name) 
                                          {
                                             Buffer<T> b(name, 128);
                                             return b;
                                          }
                                          int main()
                                          {
                                             Buffer<int> b1;
                                             Buffer<int> b2("buf2", 64);
                                             Buffer<int> b3 = b2;
                                             Buffer<int> b4 = getBuffer<int>("buf4");
                                             b1 = getBuffer<int>("buf5");
                                             return 0;
                                          }

                                          The default copy constructor and copy assignment operator should look familiar. What’s new to C++11 is the move constructor and move assignment operator, implemented in the spirit of the aforementioned move semantics. If you run this code you’ll see that when b4 is constructed, the move constructor is called. Also, when b1 is assigned a value, the move assignment operator is called. The reason is the value returned by getBuffer() is a temporary, i.e. an rvalue.

                                          You probably noticed the use of std::move in the move constructor, when initializing the name variable and the pointer to the buffer. The name is actually a string, and std::string also implements move semantics. Same for the std::unique_ptr. However, if we just said _name(temp._name) the copy constructor would have been called. For _buffer that would not have been even possible because std::unique_ptr does not have a copy constructor. But why wasn’t the move constructor for std::string called in this case? Because even if the object the move constructor for Buffer is called with is an rvalue, inside the constructor it is actually an lvalue. Why? Because it has a name, “temp” and a named object is an lvalue. To make it again an rvalue (and be able to invoke the appropriate move constructor) one must use std::move. This function just turns an lvalue reference into an rvalue reference.

                                          UPDATE: Though the purpose of this example was to show how move constructor and move assignment operator should be implemented, the exact details of an implementation may vary. An alternative implementation was provided by Member 7805758 in the comments. To be easier to see it I will show it here:

                                          template <typename T>
                                          class Buffer
                                          {
                                             std::string          _name;
                                             size_t               _size;
                                             std::unique_ptr<T[]> _buffer;
                                          
                                          public:
                                             // constructor
                                             Buffer(const std::string& name = "", size_t size = 16):
                                                _name(name),
                                                _size(size),
                                                _buffer(size? new T[size] : nullptr)
                                             {}
                                          
                                             // copy constructor
                                             Buffer(const Buffer& copy):
                                                _name(copy._name),
                                                _size(copy._size),
                                                _buffer(copy._size? new T[copy._size] : nullptr)
                                             {
                                                T* source = copy._buffer.get();
                                                T* dest = _buffer.get();
                                                std::copy(source, source + copy._size, dest);
                                             }
                                          
                                             // copy assignment operator
                                             Buffer& operator=(Buffer copy)
                                             {
                                                 swap(*this, copy);
                                                 return *this;
                                             }
                                          
                                             // move constructor
                                             Buffer(Buffer&& temp):Buffer()
                                             {
                                                swap(*this, temp);
                                             }
                                          
                                             friend void swap(Buffer& first, Buffer& second) noexcept
                                             {
                                                 using std::swap;
                                                 swap(first._name  , second._name);
                                                 swap(first._size  , second._size);
                                                 swap(first._buffer, second._buffer);
                                             }
                                          };